Room Boundaries with Dynamo
Ever wanted to create a bunch of finishing walls and floors using pre-existing rooms in a large REVIT project? I recently did and these are my findings.
To tackle the problem you can go down two different roads: either write a custom API command or use Dynamo. Yes, Dynamo, that GH-like tool I was willing to test but handn’t find the time to. So after giving a fast try to the API and finding some hiccups with the selection of FloorTypes and WallTypes, I decided to give Dynamo a try.
If you don’t know anything about Dynamo I recommend you read this Q&A with its Authors
Computational BIM
I love the concept of computational BIM as much as I love the way REVIT treats data. It’s huge consistency across the whole platform makes it perfect for a tool like Dynamo, however, most of the domestic issues I’ve ever faced in a project could be solved by using that same consistency through family edition, schedules and normal user interface. Besides, for more geometrically complex problems I have been using Grasshopper for several years, so until now I hadn’t found the right problem to tackle with Dynamo. Until now.
That portion of problems where a GH-like approach to REVIT entities and operation is what I understand as Computational BIM, or, put in other words, the kind of problems that have little to do with geometry, roofs, adaptive components.
Being an experienced GH user might help you in understanding the workflow of Dynamo but I suggest you forget for a while about the way you script components, deal with trees and datatypes in GH, else you’ll have a hard time. Dynamo has a different approach to many things:
- You don’t bake things but act on REVIT elements that get created or updated when something changes in your definition.
- Nodes can be created in a similar way to GH Clusters with the interesting advantage of allowing inserting them in the same node, in a recursive fashion.
- Nodes can also be scripted directly using Python and accessing REVIT entities and API tools through wrappers (I wished I understood what a wrapper is)
- Available tools depend on whether you’re working on a Project or a Family file.
- Code blocks are like GH panels with super-powers. Check here.
In my opinion, Dynamo has a great phylosophical advantage against GH, it is completely OpenSource, which has made its community quite strong and expert in less time. There is a lot of information out there, just check the Dynamobim.org site
Room Boundaries
Let’s get down to the issue. I wanted to retrieve the boundary of all the rooms in my document in order to use them to create a finish floor and walls using that boundary.
First, and main problem, is that there is no direct way, not that I was aware of, to retrieve the boundary of a room once you select it. So to do so you have two options:
- Use Nathan Miller’s LunchBox package, which you can download by clicking Packages > Search For Package and once installed, use the Lunchbox Room Elemenent Collector.
- Script your own Dynamo Node.
Which one do think I picked? 🙂
The best way to get started with Dynamo Scripting I found is to read this page on the Dynamo GitHub repository . This post also resulted quite useful.
Let’s have a look at the code, I tried to add comments to make it clearer.
#This script was composed by Roberto Molinos - www.modelical.com
import clr
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
# Import ToDSType(bool) extension method, not sure we need this
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# Make sure the GeometryConversion utilities are accesible see https://github.com/DynamoDS/Dynamo/issues/1946
clr.ImportExtensions(Revit.GeometryConversion)
# Unwrap
rooms = []
for i in IN[0]:
rooms.append(UnwrapElement(i)) #This kind of opens the Revit element so it can be used by Dynamo Script
# Curve array
curves = []
# Boundary options for rooms
opt = SpatialElementBoundaryOptions()
# Iterate through every room
for room in rooms:
if room.Area > 0: # Make sure it has positive Area, i.e is placed
rvBoundary = room.GetBoundarySegments(opt) # Get room boundary
dsBoundary = [] # A Dynamo list to hold the boundary per room, remember it can be complex, with holes
for rvLoop in rvBoundary: # For each loop in the room boundary
dsLoop = [] # A list to hold each room's loop
for rvPiece in rvLoop: # Retrieve each segment of the loop
dsPiece = Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(rvPiece.Curve,True) # Read the segment as Curve and convert to Dynamo geometry
dsLoop.append(dsPiece) # Add the piece to the Dynamo Loop
dsBoundary.Add(dsLoop) # Add the Dynamo Loop to the Dynamo Boundary
curves.append(dsBoundary) # Add the Dynamo Boundary per room to the Curves list
#Output
OUT = curves
Here you can see the whole definition, click to download it: Modelical-RoomBoundaries
And, if you click on the RUN button within a file with some rooms in it, just like I did, you should get something like this.
You may notice there’s another Scripting Node in my definition. Just a tiny piece of code which reuses most of the large one, to find the thickness of the wall type selected.
#This script was composed by 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
And this is where I see the strongest point of Dynamo: If you’re a bit familiar with Revit API you can access almost any parameter with ease and use it you your benefit.
Let me know your thoughts!
Hello how can i do room separator and curtain walls ignores and do. not wall
Hello how can i do room separator and curtain walls ignores and Do not build the wall
Hi Roberto, I’m not sure which Revit version you used for the script, but as far as I know, the BoundarySegment class doesn’t have a Curve method from 2022 onwards, or perhaps even earlier. In my code, I replaced it with GetCurve() method and it worked. I also replaced Add with append in dsBoundary.append(dsLoop). Apart from that, it works smoothly 🙂 Many thanks!”