Different behaviour of boolean difference between GUI and PythonScript

Hi Nathan,

i will try to explain what happens and why. First, you are using the RhinoScript method rs.BooleanDifference which behind the scenes uses RhinoCommon to make the actual Boolean and tries to add the result to the document. Sometime within the Rhino 6 development cycle, the developers decided that bad objects are not allowed to be added to the document. So you get a System.Guid.Empty as result. This happens if you try to add a bad object to the document.

Lets dig a bit deeper and show some code to ask for the ship, create the box and then do the boolean difference in order to analyze the result:

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

def DoSomething():
    
    ship_id = rs.GetObject("Select Ship", 16, True, False)
    if not ship_id: return
    
    ship_brep = rs.coercebrep(ship_id, True)
    
    a = Rhino.Geometry.Point3d(-9.0, 0.0, -4.5)
    b = Rhino.Geometry.Point3d( 7.5, 6.0, 3.0)
    bbox = Rhino.Geometry.BoundingBox(a, b)
    box_brep = bbox.ToBrep()
    
    tolerance = scriptcontext.doc.ModelAbsoluteTolerance
    results = Rhino.Geometry.Brep.CreateBooleanDifference(ship_brep, box_brep, tolerance)
    if not results: print "No Boolean result"; return
    
    for brep in results:
        rc, log = brep.IsValidWithLog()
        if not rc:
            print "Invalid Brep created: {}".format(log)

DoSomething()

If you run this with your file, you’ll see that this gives a boolean result, but it is not valid. The error in the brep is:

Invalid Brep created: brep.m_L[9] loop is not valid.
loop.m_type = 0 (must be 1=outer, 2=inner, or 3=slit)
brep.m_F[5] face is not valid.
brep.m_L[face.m_li[3]=9] is not valid.
ON_Brep.m_F[5] is invalid.

Now why does this happen with Python but not when the Boolean is created manually in Rhino ? Rhino does clean up certain things during commands which code does not, unless you code it.

If you inspect your geometry visually, some areas appear suspicious to me, eg. look at the isocurves at the front of the ship, the overshoot their trim curves:

Or look at the rendermesh near the aft section, some faces are not created:

Both errors indicate that something is wrong with tolerances in your file and the geometry was probably created with insufficient accuracy.

In generaly i would expect booleans to fail if you’re trying to bool exactly or near exactly cooincident edges, which is what you do.

To get over this without too much involvement, you could either script Rhino’s _BooleanDifference command using rs.Command, or make the script control the boolean tolerance and make it detect an invalid brep in order to attempt a repair, so the result can be added to the document like in below example.

Nathan.py (1.1 KB)

_
c.