Get Walls inside BoundingBox (Python)

Ah - misinterpreted your question. Assuming no code changes in the Python node, the issue you are running into has to do with some additional parameters which are associated to bounding boxes when they are created by certain means. In particular the ContextCoordinateSystem.

This is about to get a bit technical, so hold onto your hat.

In the context of Dynamo, bounding boxes are always aligned to the global coordinate system, so the Z axis of any bounding box is aligned to the global Z, the X axis of a Bounding box is aligned to the global X, and the Y to the Y.

This is not the case in Revit, as bounding boxes can have a rotational transform applied to them. Revit utilizes that additional property to allow for creating the view extents for things like section views while keeping a simple 6 digits for defining the limits. Because of this a long while back the Dynamo team added a transform coordinate system property onto bounding box objects; these couldn’t interact with Dynamo geometry elements, but allowed for creation of bounding boxes for use in creation of sections and such. They also set up the bulk of the bounding box creation and query methods to ensure that the coordinate system was applied to the object’s ContextCoordianteSystem property, which is read only at this time.

Sadly, BoundingBox.ByCorners appears to have been missed, so no matter how it’s created (Python, DesignScript, or Nodes) we get a resulting object which cannot be converted to a Revit BoundingBoxXYZ object as the ContextCoordinateSystem property is null.

Fortunately there is a fix (besides the rebuilding of bounding boxes by the method which was noted above). While there isn’t a node, the method BoundingBox.ByCornersCoordinateSystem(Point, Point, CoordinateSystem) can be called via DesignScript or Python. As such we can check if a BB has a context coordinate system value, and if not regenerate the boundingbox with the property added.

That code might look something like this:

# Load DesignScript Library and the BoundingBox class using the bndBox alias
import sys, traceback, clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
from Autodesk.DesignScript.Geometry import BoundingBox as bndBox

# Load the Revit API including geometry and element conversion extensions
clr.AddReference('RevitAPI')
clr.AddReference('RevitNodes')
clr.AddReference('RevitServices')
import Revit
import RevitServices
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
doc = DocumentManager.Instance.CurrentDBDocument

#inputs and static variables
dsBBs = IN[0] 
rvtBBs = []
cs = CoordinateSystem.Identity() 
collections = []

for bb in dsBBs: #loops over the bounding boxes from the Dynamo environment
	try: #attempt to convert the DesignScript BB object to a Revit BB object
		rvtBBs.append(bb.ToRevitType()) #append the BB converted BB to the list of Revit bounding boxes
	except:
		b = bndBox.ByCornersCoordinateSystem(bb.MinPoint,bb.MaxPoint, cs) #recreate the DesignScript BB object with a CoordiatneSystem property value
		rvtBBs.append(b.ToRevitType()) #append the converted BB to the list of Revit bounding boxes

for bb in rvtBBs: #loops over the converted bounding boxes
	outline = Outline(bb.Min, bb.Max)
	#filter = BoundingBoxIntersectsFilter(outline)
	filter = BoundingBoxIsInsideFilter(outline)
	collector = FilteredElementCollector(doc).WherePasses(filter).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements() #by using one line you can use the ToElements() method to remove the additional list iteration; this will likely be faster in most cases
	collections.append(collector)

OUT = collections

I have brought this to the attention of the development team, and they hope to issue a fix (along with some other updates to BoundingBox objects) in a future release.

3 Likes