Different behaviour of boolean difference between GUI and PythonScript

Hi everyone !

I’m having an issue with BooleanDifference. Basically i have two closed polysurfaces: a symmetrical boat (X-axis) and a box all over the port side of the boat (Y>=0). So as to be clear, port side (‘left side’) of the boat is inside the box while starboard side (‘right side’) is outside the box. I want to perform a boolean difference so as to get the box minus the boat.

My issue is: if i do it in the GUI with boolean difference selecting subtract from BOX and subtract with BOAT it works fine. But, if I use the following script, it deletes everything … (I already verified that the 2 first lines were selecting the right solid)
box = rs.FirstObject(select = True) #select the box
ship = rs.InvertSelectedObjects() #select the boat
bool = rs.BooleanDifference(box, ship)

And if I print “bool” it shows me: [<System.Guid object at 0x000000000000008C [00000000-0000-0000-0000-000000000000]>]

Any thoughts ? Am i clear enough ?

I also tried to do it with simple geometries (a box and a sphere), trying to subtract half of the sphere from the box, and this time, the result with the script is quite random … Or i get the right thing, i.e the box minus half oh the sphere, or i get the “other part” of the sphere, the one which does not intersect the box.

Thanks a lot,

Normally the volume to be subtracted “from” is the first chosen, then the volume to subtract. So in your first procedure, the box will remain and if the boat was a closed volume you will have a hollow in the box in the shape of half the boat.

In rhinoscriptsyntax, the order is the same. The first argument should be the GUID representing the box, the second the GUID of the boat. The result should be the same as the normal Rhino function.

If you are getting “reversed” results in either, usually it means one or more of the objects involved are not closed. But in theory, both Rhino native and rhinoscriptsyntax should give the same result with the objects in the same order.

rs.FirstObject() will select the last object added to the file. Are you sure you are selecting things in the right order in your script? Check by using rs.GetObject() instead and manually selecting each object.


Thank you for the answer. So I double (even triple) checked and I can confirm you this:

  • the two bodies are closed

  • called in the good order in BooleanDifference

  • rs.FirstObject() was targeting the box and rs.InvertSelectedObjects() the ship, as wanted

So as to be sure, i tried with rs.GetObject() (script below) and i got the same result, i.e no output, the operation delete the inputs.

box = rs.GetObject(“Box”) # select the box
ship = rs.GetObject(“Ship”) # select the boat
bool = rs.BooleanDifference(box, ship)

Is it possible that the rs.BooleanDifference has a problem ? Or am I missing a point ?


OK, sorry, in that case, without having the file to test, it will be hard to determine the problem…


You will find attached my geometry with the box.

I have few things to tell you about it. As it is, I am facing a classical problem of boolean difference, i.e as the symmetrical plan of the boat is combined with the face of my box, I have to perform slight moves in -Y direction. That I understand.
But I thought that one slight move with a value of E-6 (which is my document’s absolute tolerance) should be enough, at my surprise it wasn’t. Well, if someone has an explanation?
So, I have to successively move the boat up to a total displacement of 0.000126 in -Y direction for the boolean difference to perform, but then the result of the boolean is what I explained in my first post: nothing.

As I was losing patience I performed a move in -Y direction of 0.001 and tadaaa the boolean finally worked …
So, from zero move to 0.000125 boolean difference fails. From 0.000126 to something like 0.001 all my objects disappear. More than 0.001, it works.
EDIT: To be exact, from 0 to 0.000125, boolean difference fails, result = None ; from 0.000126 to 0.000249, boolean difference is performed but everything disappear ; from 0.00025 boolean difference is a success.
Moreover, I have no way to know, before the BooleanDifference, if it is going to result in nothing or the correct output.

Is there a tolerance I can’t find, that I need to change ? Or is there limitations within Rhino ?

The main problem, obviously, is that I need this kind of E-06 precision for the next steps on another software …

Boolean_Difference.3dm (1.4 MB)

The best thing to do is stop using Booleans. That alone will be a huge step forward.

Booleans make you stupid. They actually destroy brain cells and will eventually turn you into a complete idiot if you remain addicted to them.
Booleans are also a huge time waster. People spend hours a even days setting things up to do a boolean instead of spending a few minutes to take the necessary steps to go directly to the result.

The reason the Boolean fails is due to the degenerate surfaces that you used to make the bow of your boat with.

If you want to live with degenerate geometry you can still easily divide this in half.

Given that everything but the flat stern are symetrical surfaces, you can just extract the surfaces in one half and split the stern with a line.

Hi Jim,

Actually i’m working on a ‘quasi’ automatic script which won’t be used by me, so it’s not in my interest to intervene manually on the geometry to do such things (like dividing the geometry in half).

Also I don’t understand where you see degenerate surfaces on the bow, could you lighten me on that point ? How do you see them ?

I am pretty sure there is a tolerance somewhere I could play on … This can’t be a coincidence that I have to Move the boat in -Y axis by exactly 0.00025 to make the Boolean Difference properly work …


Booleans are already automated processes. What part are you trying to automate?

The Boolean difference you are asking Rhino to perform means you are asking Rhino to trim off the half of the boat that is outside the box and cut a hole in the box face that intersects the boat and then join the parts into one.
You can do this process yourself if you first extract the problematic bow surfaces. After that you can trim off the rest of the surfaces that are outside the box. You can then join the one bow surface to the half you want to keep and use the boundary curve to trim a hole in the Box face. After that the parts can be joined to a solid closed polysurface

The first indication is when you notice commands failing. An effective way to identify degenerate surfaces is to use OffsetSrf. A degenerate surface will have a haywire offset. If you ever would want to add thickness to the hull that would also fail.

But you said that doesn’t produce the result you want so how can you call that working properly?
If you move the geometry far enough off the centerline then Rhino can find a complete intersection and then it can do the rest of the steps of trimming off what is not part of the result and joining what remains.