Hi i am having a problem with my bounding boxes, I am trying to get the materials on both side of an element (window) and i wanna compare them to each other. My steps are:
detecting elements
Making a solid & boundingbox from it.
Rotating the boundingbox
Take the correct faces and giving them thickness/ making them the new bounding boxes
Rotating them back to compare the bounding bounding boxes to each other.
Here is the problem:
After i rotate the bounding boxes back i get a list that is empty. i checked and this only happens when the bounding box has to rotate back to a place. Anyone know why this is happening?
I’m not sure I completely understand, but I wonder if the problem is the use of bounding boxes… They are always axis aligned… Perhaps they aren’t rotating as you expect?
I tend to only use element BBs for speed, or where I can’t get a Solid to extract without failing… If you’ve already extracted Solids, can you just rotate / clash those?
Otherwise, perhaps you can simplify the graph to help identify the issue? Freeze each part in sequence to see which part isn’t behaving as you expect… the orange preview should show the problem?
The problem i am having is not that i don’t understand the way bounding boxes have to rotate they are rotating as expected the problem is more in the trend of it isn’t picking up all the elements that are inside of the bounding box so my BB doesn’t read out all the clashing elements. See below the bounding boxes i create on both sides of the selected element:
Wait…you are trying to get materials or elements? Cause it looks like the BB is getting the wall and the window for that screenshot / is the one that is not a different window type?
Don’t display the rotated cuboid. Display the result of BoundingBox.ToCuboid, and label the cuboids in the view so we have reference to both ‘where the bounding box you’re collecting elements from is’ and ‘which bounding box is failing to catch the window and the wall’.
My belief is that there is an issue presented prior to rotating due to not just the order of element creation but that you’re using face indexes to get the right and left side.
A more consistent result would entail getting the window’s transform (coordinate system) pulling the window’s geometry back to the origin by inverting the coordinate system and transforming it, pulling the bounding box from that transformed geometry, and using the min and max point to generate two new bounding boxes for right and left jamb. Those bounding boxes can then be converted back to the window’s transform in the Revit API or in newer Dynamo builds (light grey nodes indicates you’re on the last 12 months of support for Revit 2022 or in an unsupported build). End result will be consistent results.
Bounding boxes are great, and fast, but having dealt with rotational issues in past now when dealing with spacial relationships between elements which are non-axis aligned I either look to work with one of the following:
Geometry Solid Intersects. Via OOTB nodes for small cases
or in Python Coding with the BooleanOperationsUtils.ExecuteBooleanOperation(solid, reference, BooleanOperationsType.Intersect) for larger operations
ReferenceIntersector to project rays to find elements in associated proximities directionally.
Here is an example for windows:
import clr,sys,System
# Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
# Revit Services for Transactions
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Document Essentials
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc = uiapp.ActiveUIDocument
# Revit Nodes
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
left = []
right = []
# Get all windoes and walls in view
walls = FilteredElementCollector(doc,doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_Walls).ToElements()
windows = FilteredElementCollector(doc,doc.ActiveView.Id).OfCategory(BuiltInCategory.OST_Windows).ToElements()
for window in windows:
# Get facing directions
facing = window.FacingOrientation.ToVector()
left_direction = Vector.Rotate(facing,Vector.ByCoordinates(0,0,1),90)
right_direction = Vector.Rotate(facing,Vector.ByCoordinates(0,0,1),-90)
#Get Window location points for left and right sides
location = window.Location.Point.ToPoint()
half_window_width = float(window.Symbol.LookupParameter('Width').AsValueString())/2
left_point = Geometry.Translate(location,left_direction,half_window_width)
right_point = Geometry.Translate(location,right_direction,half_window_width)
# Find elements either side
cat_list = [BuiltInCategory.OST_Walls]
typed_list = System.Collections.Generic.List[BuiltInCategory](cat_list)
cat = ElementMulticategoryFilter(typed_list)
refInter = ReferenceIntersector(cat, FindReferenceTarget.Face, doc.ActiveView)
refInter.FindReferencesInRevitLinks = True
# See whats directly intersecting a ray projected off the side of window
left_check = refInter.Find(left_point.ToXyz(), left_direction.ToXyz())
left_elems = [c.GetReference() for c in left_check]
left_dists = [c.Proximity for c in left_check]
left_refs = [c.ElementId for c in left_elems]
l_index = left_dists.index(min(left_dists))
l_elem = doc.GetElement(left_refs[l_index])
left.append(l_elem)
# See whats directly intersecting a ray projected off the side of window
right_check = refInter.Find(right_point.ToXyz(), right_direction.ToXyz())
right_elems = [c.GetReference() for c in right_check]
right_dists = [c.Proximity for c in right_check]
right_refs = [c.ElementId for c in right_elems]
r_index = right_dists.index(min(right_dists))
r_elem = doc.GetElement(right_refs[r_index])
right.append(r_elem)
OUT = windows,left,right
Thank u u helped me to get rid of the bounding box for this proces. I now use the Element.IntersectSolid node + SolidIntersectiontResult.intersectingElements from Bimorph to get the elements inside the boxes and it works way better: