Solid comparison - BooleanOperationsUtils

Solid comparison - BooleanOperationsUtils

antonio_hipolito
Enthusiast Enthusiast
415 Views
3 Replies
Message 1 of 4

Solid comparison - BooleanOperationsUtils

antonio_hipolito
Enthusiast
Enthusiast

Hi, 

I need to compare geometries of two objects. What's the best aproach for solid comparison? 

BooleanOperationsUtils.ExecuteBooleanOperation seems to fail a lot of times due to very slight geometry differences... (i mean very slight!)

Tried also to compare volume and vertexes after face tesselation but tesselation seams to return diferente number of vertex if very slight geometries are found.

A boolean operation seams to be a good aproach, since we could compare volumes after those operations and get an ideia on the "size" of the difference.

Anyone knows a workarround that can bypass those exceptions due to slight diferences, raised by BooleanOperationsUtils.ExecuteBooleanOperation?

 

0 Likes
Accepted solutions (1)
416 Views
3 Replies
Replies (3)
Message 2 of 4

jeremy_tammik
Alumni
Alumni

Yes, I agree that calculating the difference between two solids and using the volume of that difference to determine whether they are almost equal would be a very good approach. Yes, I have heard that the Boolean operations provided by the Revit API have problems handling very small inequalities. I once heard of a developer who implemented a fallback algorithm: first, he tried to use the built-in Boolean operations; if they failed, he switched to the ACIS modeler. I also think that using other approaches such as volume and vertices might be possible, but they are tricky and not 100% reliable, especially as you say that the number of vertices can vary. I am afraid I have no workaround to suggest. What kind of solids are you talking about? If they have regular and predictable shapes, that might enable some simpler approach. I asked the devteam for you whether they have any suggestions. I also think there is a Revit Idea Station wish for more stable Boolean operations in the Revit API. Maybe you could find that and vote for it.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 4

jeremy_tammik
Alumni
Alumni
Accepted solution

I heard back from the devteam with some interesting insights:

 

Revit's Boolean operations are sensitive to small numerical discrepancies, and that approach isn't likely to be robust. Moreover, it does more computation than is probably warranted for the purpose of checking of two solids have the same shape (within certain tolerances).

  

Revit does have internal code that checks if two solids have the same shape. The AssemblyComponentDescriptor class seems to be the main class. I believe that the high-level idea is to compute certain characteristic features of each object (e.g., "meaningful" vertices) and to compare those features, taking into account that the two objects may have different positions and orientations.

 

That code is probably what you want, though it's also not a panacea; for example, we also have reports that the code does not consider two objects that differ very slightly to be "the same". In general, this is probably a difficult problem to get right in a universal way, since the definition of "nearly the same" may differ depending on the context.

 

Geometry comparison is only enabled by means of assembly right now. It might be a good idea to expose it directly in future, for wider use. While there are some issues, this might be the best bet for comparison.

 

For now, unfortunately, the only thing I can suggest, however clumsy it may be, is to create two AssemblyInstances out of the elements which contain the solids and then compare the type ids of the created assemblies. If they are the same, then the geometries are the same too.

 

However, even this may not be easy or even possible if these solids do not belong to elements at the time of creation; or if the solids are only parts of elements, not the whole elements. Assembly creation is not allowed from pure geometry, it is only possible from whole elements.

 

I hope this helps.

 

As they say, this is a tricky problem.

 

If I were you, I would try something (much!) simpler, e.g.:

 

Determine 'rounded' vertices of the elements. I often round the coordinates to the closest millimetre. Depending on how large a tolerance you need, you could choose a much larger value. The rounded vertices should be calculated in such a way that they bundle up some adjacent vertices that are close together into one single one. Then, compare this list of vertices for equality.

 

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

antonio_hipolito
Enthusiast
Enthusiast

Hi Jeremy, thanks for your valueable inputs.

I did not find the AssemblyComponentDescriptor class on REVIT API docs, but found CompareAssemblyInstances inside AssemblyInstance Class.... I think that's the one.

Nevertheless, I'll go try a simpler aproach as you advice, looking for identifiers on the GeometryObject like vertices and so on.

Thanks again!

 

0 Likes