Extraer y usar los contornos de las habitaciones en Dynamo
¿Alguna vez has querido crear un montón de acabados en paredes y suelos utilizando habitaciones pre-existentes en un proyecto de grandes dimensiones en Revit ? Hace poco lo hice y estas son mis conclusiones.
Para abordar el problema se pueden tomar dos caminos diferentes: o bien escribir un comando personalizado en la API o bien utilizar Dynamo. Sí, Dynamo, esa herramienta parecida a GH que yo estaba dispuesto a probar pero no encontraba tiempo para dedicarle. Así que después de dar una prueba rápida a la API y encontrar algunos contratiempos con la selección de FloorTypes y WallTypes, decidí darle una oportunidad a Dynamo.
Si no conoces nada sombre Dynamo, te recomiendo que leas esta entrevista a sus autores: Q&A with Dynamo Authors
BIM Computacional
Me encanta el concepto de BIM Computacional tanto como me gusta la manera con la cual Revit trata los datos. Esa enorme consistencia que tiene toda la plataforma hace que sea perfecto para una herramienta como Dynamo, sin embargo, la mayoría de los problemas domésticos a los que me he enfrentado en un proyecto podrían ser resueltos mediante el uso de esa misma consistencia a través de la edición de la familia, las tablas y la interfaz de usuario normal. Además, para problemas geométricos más complejos he estado utilizando Grasshopper durante varios años, por lo que hasta ahora no había encontrado el problema idóneo para afrontar con Dynamo. Hasta ahora.
Esos problemas en los que adoptamos un enfoque parecido a GH sobre las entidades y el funcionamiento Revit es lo que yo entiendo como BIM Computacional, o, dicho en otras palabras, el tipo de problemas que poco tienen que ver con la geometría, las cubiertas, los componentes adaptativos.
Ser un usuario de GH experimentado podría ayudar a comprender el flujo de trabajo de Dynamo, pero te sugiero que olvides por un momento la forma por la cual llamas a los componentes, cómo lidias con las listas y los árboles de datos, si no, lo vas a pasar mal. Dynamo tiene un enfoque diferente en muchas cosas:
- No hace bake de la geometría, en lugar de eso actúa sobre los elementos de Revit que se crean o actualizan cuando algo cambia en la definición.
- Los nodos se crean de forma similar a los Clusters con la interesante ventaja de permitir la inserción de ellos en el mismo nodo, ¡recursión!
- Los nodos también puede ser definidos directamente utilizando Python y el acceso a entidades de Revit y aherramientas de la API a través de wrappers (me hubiera gustado entender del todo lo que es un wrapper)
- Las herramientas disponibles dependen de si se está trabajando sobre un proyecto o sobre archivo de familia.
- Los bloques de código “Code Blocks” son como los “Panels” de GH pero con superpoderes. Más aquí.
En mi opinión además, Dynamo tiene una gran ventaja filosófica sobre GH: es completamente OpenSource. Esto ha hecho que su comunidad sea muy fuerte y experta en menos tiempo. Hay una gran cantidad de información por ahí, simplemente visita Dynamobim.org
“Room Boundaries”
Vayamos al grano. Quería recuperar el contorno de todas las habitaciones de mi documento con el fin de utilizarlas para crear un acabado de suelo y paredes con él.
El primer y principal problema es que no hay, o al menos no tengo conciencia de que lo haya, forma directa para recuperar los límites de una habitación una vez crada ésta. Así que para hacerlo tenemos dos opciones:
- Usar el LunchBox package de Nathan Miller, que puedes descargar haciendo click sobre Packages > Search For Package y una vez instalado, usar la herramienta Lunchbox Room Elemenent Collector.
- Hacer un script para crear tu propio nodo.
¿Cual creéis que escogí? 🙂
La mejor manera que encontré para empezar a escribir código en Dynamo fue leer esta página en el repositorio GitHub de Dynamo. Este post también resultó de bastante ayuda.
Echemos un vistazo al código, intenté añadir comentarios para hacerlo más claro.
#Este script ha sido elaborado por Roberto Molinos - www.modelical.com
import clr
# Importamos la API de Revit
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
# Importamos el método de extensión ToDSType(bool),no estoy seguro de que necesitemos esto
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# Aseguramos que las utilidades GeometryConversion están accesibles, ver https://github.com/DynamoDS/Dynamo/issues/1946
clr.ImportExtensions(Revit.GeometryConversion)
# Unwrap "Desenvolvemos" el elemento de Revit
rooms = []
for i in IN[0]:
rooms.append(UnwrapElement(i)) #Esto abre el elemento de Revit para que pueda ser usado por Dynamo Script
# Lista de curvas
curves = []
# Opciones de contorno para habitaciones
opt = SpatialElementBoundaryOptions()
# Bucle para todas las habitaciones
for room in rooms:
if room.Area > 0: # Asegurarse de que el área es positiva, y por tanto de que la habitación está colocada
rvBoundary = room.GetBoundarySegments(opt) # Obtenemos el contorno de la habitación
dsBoundary = [] # Una lista para manejar los contornos por habitación, recordar que puede ser compleja, con huecos
for rvLoop in rvBoundary: # Para cada loop en el contorno de la habitación
dsLoop = [] # Una lista para manejar cada loop de contorno
for rvPiece in rvLoop: # Recuperamos cada segmento del loop
dsPiece = Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(rvPiece.Curve,True) # Leemos el segmento como curva y lo convertimos a Dynamo Geometry
dsLoop.append(dsPiece) # Añadimos el segmento Dynamo al loop Dynamo
dsBoundary.Add(dsLoop) # Añadimos el loop Dynamo al contorno Dynamo
curves.append(dsBoundary) # Añadimos el contorno Dynamo por habitación a la lista de curvas
#Output
OUT = curves
Aquí puedes ver la definición completa, pincha para descargarla: Modelical-RoomBoundaries
Y, si corres la definición clicando RUN con un archivo que contenga algunas habitaciones, como yo hice, deberías obtener algo como esto.
Habrás notado que hay otro Scripting Node en la definición. Simplemente son unas pocas líneas de código que reutiliza gran parte de la otra definición para obtener el grosor del tipo de muro elegido.
#Este script ha sido elaborado por Roberto Molinos - www.modelical.com
import clr
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
# Unwrap
walltype = UnwrapElement(IN[0])
#Output
OUT = walltype.Width
Y aquí es donde veo el punto más fuerte de Dynamo: Si estás un poco familiarizado con la API de Revit puedes acceder a casi cualquier parámetro con facilidad y usarlo en tu propio beneficio.
Déjame saber tu opinión y si has usado la definición para algo útil.