This is pretty obvious, once you think about it, and apparently worth pointing out anyway:
The outline defining a bounding box filter is always aligned with the cardinal axes.
This question was clarified in
the Revit API discussion forum thread
on BoundingBox
outline and BoundingBoxIsInsideFilter
:
Question: I have a question about a bounding box.
I tried to get its outline and retrieve the elements inside it.
I encountered 3 cases:
Here is the code; the exception is thrown by the Outline
constructor:
View3D curView3d = doc.ActiveView as View3D; BoundingBoxXYZ box = curView3d.GetSectionBox(); Transform t = box.Transform; Outline o = new Outline( t.OfPoint( box.Min ), t.OfPoint( box.Max ) ); FilteredElementCollector collector = new FilteredElementCollector( doc ); BoundingBoxIsInsideFilter bbfilter = new BoundingBoxIsInsideFilter( o ); IList<ElementId> insideList = collector .WhereElementIsNotElementType() .WherePasses( bbfilter ) .Where( x => x.GetTypeId().IntegerValue != -1 ) .Where( x => x.IsPhysicalElement() ) .Select( x => x.Id ) .ToList(); uidoc.Selection.SetElementIds( insideList );
Answer: As said, this is pretty obvious, once you think about it.
The outline defining a bounding box filter is always aligned with the cardinal axes.
If you simply grab the Min
and Max
point of the bounding box and rotate them far enough, they will end up in positions that specify an empty Outline
.
Hence the exception.
You seem to be expecting a rotated box. Instead, it creates an axis aligned outline, which won't have the same proportions as the original box (the min and max were rotated).
You can solve this problem by doing the opposite, i.e., rotating the elements' outlines and not the BBox's outline (new outline from all rotated corners, so you lose some precision).
We ended up doing that is one case and it worked pretty well.
Another approach that comes to mind:
Instead of using the BoundingBoxIsInsideFilter
class with an axis-aligned bounding box,
you could simply create your own Solid
representing the rotated box and use
an ElementIntersectsSolidFilter
.
Note that the BoundingBoxIsInsideFilter
is a quick filter, whereas the ElementIntersectsSolidFilter
is slow,
cf. Quick, Slow and LINQ Element Filtering.