BoundingBoxXYZ() Creation from SectionBox Inconsistencies

I am working on understanding why I am getting two results when I use python to create a bounding box from a ‘SectionBox’.

Looking at this post: https://forum.dynamobim.com/t/bounding-box-of-section-box-min-max-pts-z-values-dont-correspond-with-model-elevation/15776, I see that the SectionBox Origin XYZ components are retrieved and then added to the Min and Max XYZ components. It seems that I am having inconsistencies when I create a BoundingBoxXYZ from only the Max and Min X,Y,Z components of the SectionBox without adding to the origin point. Nevertheless, the BoundingBoxes retrieved from both options are quite close. Which is right?

Option A:

transform = sectionbox.Transform
sboxoriginx = transform.Origin.X
sboxoriginy = transform.Origin.Y
sboxoriginz = transform.Origin.Z
minx = sectionbox.Min.X + sboxoriginx
maxx = sectionbox.Max.X + sboxoriginx
miny = sectionbox.Min.Y + sboxoriginy
maxy = sectionbox.Max.Y + sboxoriginy
minz = sectionbox.Min.Z + sboxoriginz
maxz = sectionbox.Max.Z + sboxoriginz
bbox = BoundingBoxXYZ()
bbox.Min = XYZ((minx), (miny), (minz))
bbox.Max = XYZ((maxx), (maxy), (maxz))

Option B:

section_box = view.GetSectionBox()
#transform = section_box.Transform #needed for some reason
bbMax = section_box.Max
bbMin = section_box.Min

bbox = BoundingBoxXYZ()
bbox.Min = XYZ(bbMin.X, bbMin.Y, bbMin.Z)
bbox.Max = XYZ(bbMax.X, bbMax.Y, bbMax.Z)

tsectionbox = bbox.ToProtoType()

Finally, is it possible to use .ToDSType(True) rather than .ToProtoType()? The prior is throwing an error.

Thanks!

It because:

  1. sectionBox.Transform returns a BoundingBoxXYZ which has a transform property, and that transform property when its derived from a view, always orientates the BasisZ towards the viewer. Hence, your transform is effectively rotated 90 degrees, so when you transform your XYZs they are plotted in a rotated coordinate space
  2. view.GetSectionBox() can only be called on a View3D not a ViewSection, and 3d views have an Identity transform - i.e. its not ‘rotated’.

ToDSType() is Dynamo’s primary wrapper method and can only be called on an object from Revit which inherits from is Element base class. BoundingBoxXYZ are pure RevitAPI objects which do not inherit from this class, hence you can’t call ToDSType() on it. Since its an object type native to Revit in the API context and not Dynamo, you have to convert it (build it from scratch) to a ProtoGeometry BoundingBox and the simplest way to achieve that is by calling the ToProtoType() helper method.

8 Likes

@Thomas_Mahon - thank for the detailed reply. I’m still a unclear on a few points though:

  1. Ive read through the dynamo primer as well as this link: https://www.google.com/amp/s/danimosite.wordpress.com/2018/10/14/revit-nodes-vs-revit-api/amp/
    I’m still unsure on how ‘RevitNodes’ (I assume this is the pure Revit element you refer to) differs from the Revit API as the Revit.Elements is contained in the Revit API. Maybe I’m wrong here.

Furthermore, when creating the boundingbox, is it necessary to add the origin point to the min and max to get the proper bb? I refer to the examples I posted initially.

Thank you.

Importing Revit.Elements allows you to use the DS nodes directly in python (more information here). They do not return pure Revit elements, but they can all be converted to Revit types. Regarding the origin, yes, you may have to offset the values using the model’s origin. Here is an example written in C# although it is simple enough to translate to python.

1 Like

RevitNodes is Dynamo’s Revit Element wrapper library which essentially serves as the interop between Dynamo and Revit. It is not the same as the RevitAPI nor can you make RevitAPI calls with any object from the RevitNodes library as these are Dynamo wrapper objects. Instead, you extract the wrapped (Internal) RevitAPI Element and from there you can make valid RevitAPI calls.

A ‘pure Revit API’ object is in reference to any object from the RevitAPI which only exists in the API context, such as a BoundingBoxXYZ.

If all you want to do is get the min max points in their respective locations in coordinate space, just transform the points using the boundingBox.Transform:

bb = viewSection.BoundingBox[viewSection]
transform = bb.Transform
min = transform.OfPoint(bb.Min)
max = transform.OfPoint(bb.Max)
3 Likes

@cgartland - Thanks for sharing the link. I understand now after reading through it a few times what @Thomas_Mahon is stating.

Thanks to you both.