how to get element nearby specific element using bounding box if it is just outside(some distance apart) bounding box?

how to get element nearby specific element using bounding box if it is just outside(some distance apart) bounding box?

prasannamurumkar
Advocate Advocate
4,883 Views
16 Replies
Message 1 of 17

how to get element nearby specific element using bounding box if it is just outside(some distance apart) bounding box?

prasannamurumkar
Advocate
Advocate

i want to get element with some specific distance from parent element.

.for that i am finding  way to do it.

1.i have tried by getting location point of both element but it not work right.

2.now i am trying by bounding box of parent element

it is working but problem is it is working those elements which are very near to parent element.

for that i am trying to  scale bounding box so all element nearby i should collect.

but it is not working right by using outline.scale() method.Because bounding box actual min,max point remain same.

and element getting are same after applying intersect filter(before and after using scale method).

 

could anyone suggest solution?

 
 
0 Likes
Accepted solutions (1)
4,884 Views
16 Replies
Replies (16)
Message 2 of 17

RPTHOMAS108
Mentor
Mentor

The problem with the various BoundingBox...Filter classes is they were all created for a bounding box parallel to the model space. You see they all take an Outline class within the various constructors to these filters and this class has no orientation unlike BoundingBoxXYZ which has a transform depicting it's orientation within the model.

 

If you have a long member like a beam in a diagonal direction to model space then the bounding box is square not rectangular following the orientation of the beam. So this is not ideal for finding nearest elements to something, mostly is used for coarse filtering I expect.

 

Probably you need to give a less abstract description of what you are trying to do i.e. naming the element categories involved and what you mean by 'parent element' and then someone may be able to suggest something better. 

 

 

 

0 Likes
Message 3 of 17

prasannamurumkar
Advocate
Advocate

Thank you for reply.

 

in my case 

for current scenerio no diagonal element and long element.

1.i want to make sure the location of electricswitch should be 100 mm near by geyser.

 

Here my parent element is geyser.

finding bounding box of geyser and filtering the all switches in that.

Another case

2.In this case making sure location of electric switch should be 100 mm near by door.

Here my parent element is door.

finding bounding box of door and filtering the all switches in that.

so there are different cases .

i am getting element when it is following under bounding box

 

Now in our case user might increase the distance from 100 to 200mm or 100 to 500mm

for that logic should work if bounding box scaled but i think it is not working.

0 Likes
Message 4 of 17

jeremytammik
Autodesk
Autodesk

You can keep a list of all the relationships between parent element and dependent element.

 

Go through the list, grab the geometry vertices Vp of parent and Vd dependent element, and ensure that the minimal distance between Vp and Vd is less than 100 mm.

 



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

Message 5 of 17

prasannamurumkar
Advocate
Advocate

Thank you for reply.

trying to get vertices of the element as you suggested 

element->geometry element->geometry object->solid-.>edge->edge as curve->end points.(vertices)

but each element having solid is null in my case for parent element.

 

are you suggesting same way to get vertices or have suggesting different way?

 

 

 

 

 

 

 

 

 

 

 

 

Options opt = new Options();
GeometryElement geoElement= element.get_Geometry(opt);
foreach (GeometryObject g1 in geoElement)
{
if (g1 == null)
{

}
else
{
Solid s1 = g1 as Solid;
if(s1!=null)
foreach (Edge e in s1.Edges)
{
Curve cut = e.AsCurve();
XYZ p1 = cut.GetEndPoint(0);
XYZ p2 = cut.GetEndPoint(1);
foreach (Element ele in elementListelctric)
{
GeometryElement geo2=ele.get_Geometry(opt);
if (g1 == null)
{

}
else
{
foreach (GeometryObject g2 in geo2)
{
if (g2 == null)
{

}
else
{
Solid s2 = g2 as Solid;
foreach (Edge e2 in s2.Edges)
{
Curve cut1 = e.AsCurve();
XYZ p3 = cut1.GetEndPoint(0);
XYZ p4 = cut1.GetEndPoint(1);
if(p1.DistanceTo(p3)< 0.328084 || p1.DistanceTo(p4) < 0.328084 || p2.DistanceTo(p3) < 0.328084 || p2.DistanceTo(p4) < 0.328084)
{
geyserElementList.Add(element);
}

}
}
}
}
}

}
}

 

 

In my case for parent(geyser) elements all element solid(s1) are getting null.

i want to mention my parent(geyser) element is from link document.

0 Likes
Message 6 of 17

prasannamurumkar
Advocate
Advocate

issue of not getting solid is resolved i got solid by

if(s1==null)
{
GeometryInstance ins = g1 as GeometryInstance;
if (ins != null)
{
GeometryElement g4 = ins.GetInstanceGeometry();
foreach (GeometryObject g2 in g4)
{

s1 = g2 as Solid;


}
}

0 Likes
Message 7 of 17

prasannamurumkar
Advocate
Advocate

could anyone suggest better approach.Above approach which i m using is very time consuming.

0 Likes
Message 8 of 17

jeremytammik
Autodesk
Autodesk

I cannot read you code, but it does look as if it can be easily optimised.

 

Are you re-traversing all element geometry of each element several times over?

 

How about performing one run to retrieve the element extents, and then checking proximity in a second, separate run?

 



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

Message 9 of 17

prasannamurumkar
Advocate
Advocate

Thank you for reply.

As per your suggestion.

it is possible to do like retrive extents of element in first 

but still i have to collect all edges,faces of element to get their end points(extent)

but i have elements like geyser, IDU unit . faces and edges are too many.

Seems to be diificult apprach.

 

could you recommend simple approach like

 

1.getting location point of element and calculating distance.

2.getting bounding box and scale bounding box and apply filter.(was trying to do earlier.)

 

could you recommend other than above.

0 Likes
Message 10 of 17

jeremytammik
Autodesk
Autodesk

Both approaches sound perfectly fine and sufficiently performant.

 

No need to worry about performance, if you go about it right.

  

For example, take a look at this interesting and impressive approach for a high-performance optimisation using Revit API for outline for many elements (>100'000 items), e.g., for 54000 walls (after filtering) and 18000 pipes, leading to 972'000'000 operation:

 

  



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

Message 11 of 17

prasannamurumkar
Advocate
Advocate

Thanks for the time.

0 Likes
Message 12 of 17

prasannamurumkar
Advocate
Advocate
Accepted solution

worked using aproach 1.

by getting location point currently it is working fine

 

 

sharing some snap of code 

 

Note: it is not complete code 

foreach (Element elementel in elementListelctric)
{
LocationPoint location1 = element.Location as LocationPoint;
Transform transform1 = RvtLinkp.GetTransform();

XYZ newLocation2 = transform1.OfPoint(location1.Point);
Transform transform = RvtLink.GetTransform();
LocationPoint location2 = elementel.Location as LocationPoint;
XYZ newLocation = transform.OfPoint(location2.Point);
double distance = newLocation2.DistanceTo(newLocation);

XYZ point1 = new XYZ(newLocation.X, newLocation.Y, newLocation.Z+8);
XYZ point2 = new XYZ(newLocation2.X, newLocation2.Y, newLocation2.Z);
distance = location1.Point.DistanceTo(location2.Point);
distance = point2.DistanceTo(point1);


Message 13 of 17

shitanshus
Explorer
Explorer

RvtLinkp could not be found in Revit API docs. Is it any property defined?

0 Likes
Message 14 of 17

jeremy_tammik
Alumni
Alumni

RvtLinkp and RvtLink are probably both instances of the RevitLinkInstance class:

  

https://www.revitapidocs.com/2023/a3a27c39-75bf-67d1-ae78-4cadd49a9c8e.htm

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 15 of 17

prasannamurumkar
Advocate
Advocate
ou can get revit link instance
 var links = new FilteredElementCollector(revitDocument).OfClass(typeof(RevitLinkInstance)).ToList();

and then you can get transform

       foreach (RevitLinkInstance doc in links)           
{                       
 lstDocs.Add(doc.GetLinkDocument(), doc.GetTotalTransform());
}

 

0 Likes
Message 16 of 17

prasannamurumkar
Advocate
Advocate
You can get revit link instance
 var links = new FilteredElementCollector(revitDocument).OfClass(typeof(RevitLinkInstance)).ToList();

and then you can get transform
       foreach (RevitLinkInstance doc in links)           
{                       
 lstDocs.Add(doc.GetLinkDocument(), doc.GetTotalTransform());
}
0 Likes
Message 17 of 17

prasannamurumkar
Advocate
Advocate

Revit link instance is link instance of that model
to get transform that one can get from above code.

 

0 Likes