Boolean difference in gh much slower than in Rhino

slow_boolean_difference.gh (137.3 KB)

In this simplified example (I cut part of the model for IP reasons) it takes 14+ seconds to calculate, whereas in Rhino this goes almost instantly. When I leave the cut-off part in tact the calculation takes even much longer (43 seconds). The amount of faces in the polysurface seems to have huge impact on calculation time.

The same using python / Rhino common takes 1.1 seconds (using the brep lists variant of Boolean difference) So my guess is that the current SolidDifference tool in gh uses the first implementation of BooleanDifference. Could well be the same with SolidDifference, I haven’t checked yet

So this solution is actually much faster than the built in solid difference. the one that took 43 seconds takes 2.8 seconds now for substracting 24 objects from the original solid. But still it is slower than Rhino, the python version takes 1.8 seconds with only one object

Are you explicitly setting the tolerance in your scripting implementations? I believe the native Grasshopper components uses the Rhino document tolerance. This might be part of the explanation.

I don’t quite understand your conclusion, because if gh uses my native Rhino tolerance, then the Boolean difference should take about as long in Rhino as it would in gh. When I use the first implementation of Boolean difference of rhino common, it takes about as long in python as it does in gh. Therefore I assume gh native component uses this rhino common method rather than the second implementation doing the Boolean difference by sets

@pascal @wim ?

Just guessing at part of this, that the relatively small difference between the faster GH way and the native Rhino way we can put down to the extra layers of GH, dotNet, Python, that GH must wade through to get it done. But, I have not ideas beyond that - @chuck - is in charge of Rhino Boolean operations, but I do not know how much of that is relevant to the GH component…

-Pascal

did you see also my second post, where I used a different method in a gh python component that speeds things up considerably?

If I remember correctly, in order to make the dotNet calls happy and threadsafe, all of the surface trees and other cached information is created on a dotNet polysurface beforehand. This eliminated a huge number of crashes at the expense of creating caches on surfaces that don’t need them for a particular boolean operation, and could be the source of the difference. @stevebaer does this sound familiar?

@pascal feel free to create a YT issue for this and put it on my list

https://mcneel.myjetbrains.com/youtrack/issue/RH-57558
-w

bump: @stevebaer see attached example, it seems gh native component uses different method to compute solid difference:


solid_difference.gh (221.6 KB)

1 Like

It would be great to give this some attention.

Booleans in GH is a really good way to explore design/detailing options before committing. Especially with SubD, where cutting a hole natively via SubD editing is a futile, slow, inaccurate and destructive approach. However currently live booleans in GH become unusably slow with more than 1-2 simple components, even when dealing with mesh representations of SubD/Nurbs objects.

Thx,

G

1 Like

Hello,

A good short term solution may be the Sasquatch plugin.

But ideally Booleans would just be fast in the OOTB GH component!

Dan

in this case not: this plugin also takes 11.2 seconds to complete. There are several Boolean Difference methods in RhinoCommon and the one I’m using is faster if you substract many objects from 1 object.

Always (notably in a Surface modeller like Rhino) try to do similar ops in steps (for error tracking). See attached.

Brep_slow_boolean_difference.gh (127.0 KB)

thanks, it’s nice to have a solution like that as alternative for when things get impossible to check visually. Unfortunately it is also almost as slow as the built in solution. Faster would be to do surface splitting instead of booleans and stitching the result. Not sure if this can be efficiently scripted though since successful splitting A does not mean successful splitting B

Gijs, I brought up to them the surface splitting method too, but the issue was that you are still dealing with as many operands and need to sort our what to keep, what to discard, post-splitting, and you would end up being as slow. But I’m not sure if this was just a hunch or needed to be tested.

G

It can (not a very big deal) but the benefits would be marginal (if any at all). See a simple test (a splitter (BrepFace) VS a brep (some Box) where each splits tthe other):

Have in mind that picking the right item(s) from the resulting array (what is inside/outside etc etc) would require tests that take time.

If you deal with that sort of stuff in daily basis I would suggest to use a fast solid modeller (or attempt to switch to a mesh based approach - IF it works anyway). If is an isolated case … accept things as they are.

Update: found a couple of minutes to add Plan B (pointless to the max - Elapsed grows [expected])

Brep_slow_boolean_difference_V1.gh (234.7 KB)