I am attempting to determine the length, width, and height of assemblies created in Revit, then to write these values into the corresponding parameter to a specific element of the assembly. This is essentially my first project using a 2D visual coding environment, and I would greatly appreciate help in understanding if I’m pursuing the correct path to a solution, as well as help with filling in missing pieces.
My current understanding for how to gather the length, width, and height parameters is via Element.BoundingBox, in a workflow something like the image below, and later to write the results to elements via Element.SetParameterByName.
I found a partial solution from a similar situation, where the recommended solution included the node Element.Solids, as shown below. While functional, this program takes an impractical ~30 minutes to run a test, and has a tendency to exceed available RAM near the end of a run (~32 GB).
To try and address these issues, I’ve tried to create a flow which removes from Assembly.Members any Element.Names with String.Contains “SDCF”, then feeding the result into List.FilterByBoolMask. While I have a list of the items to remove, I am unable to find a node, such as List.SetDifference, which removes those items as sub-components from the Assembly.Members list.
Is this the way to filter out unwanted geometry before calculating Element.Solids? Is there a simpler way to filter out sub-components of a list prior to invoking a function? Is the process described a solution at all? Is there some other function I’m yet unfamiliar with that imitates typing “BX” in Revit, a process which already creates a bounding box close to the one I seek to reproduce? I originally anticipated this to be a quick/short task to accomplish, and now find this is much more complicated than originally expected.
Again, thanks in advance for help with this process.
Instead of pulling the solids, just use the Element.BoundingBox node. This will mean no geometry other than the bounding box for each of the elements in the assembly. If you’re after the bounding box for the assembly you may want to try and pull the bounding box from that instead of the elements which make up the assembly as pulling from the assembly’s elements will result in many bounding boxes which will need to be unioned. If you do need to union try using a BoundingBox.ByGeometry with the list of bounding boxes, or from the lists of minimum and maximum points.
Once you have a bounding box for each assembly you can build a vector from the min point and max point of each bounding box, and pull the X, Y, and Z values from the vectors as a means of extracting the width, length, and height of the bounding box.
Keep in mind that bounding boxes will not be ‘minimum fit’ so if you have a linear assembly on an angle your width and length might not be as you expect.
When I try use the nodes Element.(Oriented)BoundingBox, BoundingBox ByUnion, Geometry.Extents, or Element.Geometry+ for each step prior to Element.Solids, I get either “null,” a list of empty lists, or a dictionary of empty lists. I might be misunderstanding or missing an intermediary step prior to using the Geometry.BoundingBox or Geometry.Extents nodes, I’ve included my test workflows and their resultants below.
I’m confident that once I have a list of bounding boxes, pulling the vectors or Geometry.Extents should be easy enough to achieve. Thanks again for helping out! It’s neat to see some of the different potential solution paths to the same simple objective.
Based on help from here, I’ve been able to create an imperfect solution for this task. In interest of assisting any future discoverers of this thread, the results:
To describe the script: for all assemblies, this finds all components of the type “Structural Columns” or “Structural Framing,” pulls the bounding box of all assembly elements, and writes width + length + height to the component members’ (not assembly’s) parameters named “Assembly Depth/Length/Height” for ease of scheduling.
While fast, this solution only provides an upper bound for the bounding box. Assembly.Members → Element.BoundingBox seems to get the bounding box for everything: solids, voids, floating reference planes, etc. To get the bounding box of just the solids seems to require use of the Element.Solids node mentioned earlier, but the size + complexity of assemblies in my project(s) tends to overflow my PC’s memory after 20-30 minutes. I’m not aware of memory manipulation techniques, so this is likely the end of this project for me. Thanks again for your help, jacob.small and pyXam!