BoundingBox outline and BoundingBoxIsInsideFilter

BoundingBox outline and BoundingBoxIsInsideFilter

Shai.Nguyen
Advocate Advocate
7,961 Views
10 Replies
Message 1 of 11

BoundingBox outline and BoundingBoxIsInsideFilter

Shai.Nguyen
Advocate
Advocate

Hi all,

I have questions about bounding box. I tried to get outline of BoundingBox and retrieve elements inside it. But I've faced 3 cases:

1. My code works fine with horizontal BoundingBox  (rorate = 0 deg).

1.PNG2. BoundingBox still can get outline, but can not select all element inside. (rorate = 10 ~ 20 deg).

2.PNG

3. BoundingBox can't get outline(rorate > 45 deg) .Error message is "outline is an empty outline".See code below in red line 

3.PNG

 

[Transaction(TransactionMode.Manual)]
    public class ElementInsideBoundingBox : IExternalCommand
    {
        public Result Execute(
          ExternalCommandData commandData,
          ref string message,
          ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Application app = uiapp.Application;
            Document doc = uidoc.Document;
            
            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);
            return Result.Succeeded;
        }
    }

I attached revit file for example. Please tell me where I was wrong?
Thank you in advanced!

 

0 Likes
Accepted solutions (1)
7,962 Views
10 Replies
Replies (10)
Message 2 of 11

jeremytammik
Autodesk
Autodesk

Thank you for your query, good explanation and reproducible case.

 

I passed it on to the development team to ask what they can say off-hand.

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 3 of 11

jeremytammik
Autodesk
Autodesk

I heard back from the development team on this. They say:

 

We struggled with a similar issue. My understanding is that an Outline is always axis aligned - you are rotating the min and max points of the bounding box, `new Outline(t.OfPoint(box.Min), t.OfPoint(box.Max));` this doesn't give the  results 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 BB (the min and max were rotated). We solved 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 we loose some precision, but we didn't care). Perhaps there is another way but that is what we ended up doing and it worked pretty well. 

 

I hope this helps.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 4 of 11

jeremytammik
Autodesk
Autodesk
Accepted solution

I edited and cleaned up our discussion for posterity, plus adding another, new, suggestion to address your need using a solid intersection filter instead:

 

http://thebuildingcoder.typepad.com/blog/2018/04/bounding-box-filter-always-axis-aligned.html

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 5 of 11

Shai.Nguyen
Advocate
Advocate

thank you Jeremy. I'd love to see that.

Message 6 of 11

jeremytammik
Autodesk
Autodesk

So would I  🙂

 

Go ahead, try it out, and share the results.

 

Thank you!

 

Cheers,

 

jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 7 of 11

Shai.Nguyen
Advocate
Advocate

Hi Jeremy,

There are many categories that cannot get Solid out of geometry, i.e Lines, Planting,... That means I cannot use ElementIntersectsSolidFilter to retrieve them. Do you have any suggestions?

0 Likes
Message 8 of 11

jeremytammik
Autodesk
Autodesk

Yes.

 

Use a larger axis aligned bounding box filter to apply quick filtering.

 

In a second step, eliminate the elements that lie outside the enclosed rotated box that you are really interested in.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 9 of 11

BIM_S_S
Participant
Participant

hi    

you mentioned about this case as below.

ou 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.

 

 

please share the code in which you rotated the bounding box

 

0 Likes
Message 10 of 11

Anonymous
Not applicable

Why in this line:
".Where(x => x.IsPhysicalElement())"
can't find "IsPhysicalElement()"(ps:even in the API Doc)?

Did you create a method?

0 Likes
Message 11 of 11

jlpgy
Advocate
Advocate

Hi:

It's a method that not decleared in RevitAPI.

But I think it's name is quite easy to understand.

And also, you can try these lines:

        internal static IEnumerable<Element> GetLocationElems(View v)
        {
            // Get elements that are visible in a View
            // And the elements must have a valid location (curve/point)
            
            var es = new FilteredElementCollector(v.Document, v.ID).ToElements();
            return (from e in es
                    where e != null && e.IsValidObject && e.Location != null
                    where (e.Location is LocationCurve) || (e.Location is LocationPoint)
                    select e).ToList();
        }

I replaced some lines in the above codes. So if there is some little errors, I do believe it's also quite easy to work it out.

单身狗;代码狗;健身狗;jolinpiggy@hotmail.com