Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

BoundingBox outline and BoundingBoxIsInsideFilter

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
Shai.Nguyen
6420 Views, 10 Replies

BoundingBox outline and BoundingBoxIsInsideFilter

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!

 

10 REPLIES 10
Message 2 of 11
jeremytammik
in reply to: Shai.Nguyen

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

Message 3 of 11
jeremytammik
in reply to: Shai.Nguyen

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
in reply to: Shai.Nguyen

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
in reply to: jeremytammik

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

Message 6 of 11
jeremytammik
in reply to: Shai.Nguyen

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

Message 7 of 11
Shai.Nguyen
in reply to: jeremytammik

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?

Message 8 of 11
jeremytammik
in reply to: Shai.Nguyen

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
in reply to: jeremytammik

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

 

Message 10 of 11
s26478626
in reply to: Shai.Nguyen

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

Did you create a method?

Message 11 of 11
jlpgy
in reply to: s26478626

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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community