I am trying to write an exception to problematic Revit room geometry within a python node.
The goal is to extract room solids where possible, and for the exception to produce a list where rooms that will cause the script to run with errors because of geometry issues are highlighted, along with the groups containing those rooms. This will allow the usable rooms to be included in the rest of the script, and provide an output report identifying the elements needing addressing by anyone unfamiliar with error checking in Dynamo.
At the moment when the script runs into problematic geometry (i.e. trim_edge_loops, strangely shaped rooms, overlapping boundaries etc.) it causes Dynamo and Revit to crash. But these are the elements Iâm looking to identify and list
You should place the SpatialElementGeometryCalculator outside your loop and have it therefore only initiated once.
You can check if the geometry can be calculated with the method CanCalculateGeometry(SpatialElement)
-> That way you could use an if statement instead of try/except (if this is the exception you want to filter out)
A simplified version would look like this:
import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
doc = DocumentManager.Instance.CurrentDBDocument
rooms = UnwrapElement(IN[0])
output = []
calculator = SpatialElementGeometryCalculator(doc)
for room in rooms:
if calculator.CanCalculateGeometry(room):
solid = calculator.CalculateSpatialElementGeometry(room).GetGeometry()
output.append(solid.ToProtoType())
else:
output.append("cannot calculate element geometry")
OUT = output
Try it this way and see if Revit and Dynamo still crash.
If so, limit the number of rooms you run it on and make sure to include at least one room that fits into your exception. A sample Revit file (minimal,4 rooms, purged) could help us to help you.
By the way: You can use UnwrapElement on a list of elements. Avoid having anything in a loop that does have to be there.
Thank you Kibar, this looks like a perfect solution! Unfortunately I am getting the AttributeError: âSolidâ object has no attribute âToPrototypeâ for solid.ToProtoType()
Having researched the error here and various other sources (as well as my own testing this evening) I canât figure out why the solid wonât convert and itâs stopping me from seeing if your solution above works⌠Have you any advice on alternative methods of converting Revit geometry to Dynamo geometry?
I have tested it using the references in your solution as well as my original node but no joy on either.
You wrote AttributeError: âSolidâ object has no attribute âToPrototypeâ. If that is the exact error, you âmisspelledâ ToProtoType. Python is case sensitive and your last T was lower.
This might not really matter, but by using import * you´re getting 2 Solid classes:
One through from Autodesk.DesignScript.Geometry import *
and the other through from Autodesk.Revit.DB import *
For now you could just comment out the following lines by placing # in front, because it works for me without them:
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
Again: I don´t think the Solid classes from Revit.DB and DesignScript.Geometry are being cross references in your script. You don´t initiate a Solid object, but have it returned from GetGeometry().