RhinoCommon CreateCurveBooleanDifference overload

The method should accept either a single curve or a list of curves, but if I feed it a list, I get the following error:

Message: expected Curve, got Array[Curve]

Does this have something to do with having to specifically create an IEnumerable instead of a simple list? ISTR something like that with a few other methods…

Thx, --Mitch

Curve.CreateBooleanDifference Method (Curve, IEnumerable(Curve))

Calculates the boolean difference between a closed planar curve, and a list of closed planar curves. Note, curves must be co-planar.

Parameters
curveA
Type: Rhino.Geometry.Curve
The first closed, planar curve.

subtractors
Type: System.Collections.Generic.IEnumerable(Curve)
curves to subtract from the first closed curve.

Return Value
Result curves on success, empty array if no difference could be calculated.

Hi Mitch,

i do not get this error, but i do not know how you created your list of subtractor curves.

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext

def CurveBooleanDifference():
    id_crv = rs.GetObject("curve to subtract from", 4, True, False)
    if not id_crv: return
    
    ids = rs.GetObjects("curves to subtract", 4, False, False)
    if not ids: return
    
    if id_crv in ids: return
    
    crv = rs.coercecurve(id_crv)
    curves = [rs.coercecurve(i) for i in ids]
    
    arr = Rhino.Geometry.Curve.CreateBooleanDifference(crv, curves)
    if not arr: return
    
    objs = [scriptcontext.doc.Objects.AddCurve(a) for a in arr]
    rs.SelectObjects(objs)
    scriptcontext.doc.Views.Redraw()
    
if __name__=="__main__":
    CurveBooleanDifference()

What i find kind of strange is the result of Curve.CreateBooleanDifference(). Eg. try to pick a circle as the curve to subtract from, then two rectangles overlapping the circle when it asks for “curves to subtract”. Why is the circle subtracted from the rectangles ? I would not expect this.

Apart from this i would not expect why Curve.CreateBooleanDifference() returns the first curve if the subtraction is made between two non overlapping curves either ! The helpfile states:

Return Value:
Result curves on success, empty array if no difference could be calculated.

:confused:

c.

I can’t get it to error out on my simple example either, I will look into why it is failing on my main script (too big and unfinished to post right now). I worked around it for now with a “manual” loop and successive subtractions.

However, I don’t get why the following test returns not only the correct difference, but all the individual curves used to subtract… :hushed:

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc
a=0
subtractors=[]
for i in range(4):
    pt0=Rhino.Geometry.Point3d(5+a,0,0)
    pt1=Rhino.Geometry.Point3d(0+a,5,0)
    pt2=Rhino.Geometry.Point3d(-5+a,0,0)
    pt3=Rhino.Geometry.Point3d(0+a,-5,0)
    subtractors.append(Rhino.Geometry.PolylineCurve([pt0,pt1,pt2,pt3,pt0]))
    a+=15
    
pt0=Rhino.Geometry.Point3d(-10,0,0)
pt1=Rhino.Geometry.Point3d(55,0,0)
pt2=Rhino.Geometry.Point3d(55,-20,0)
pt3=Rhino.Geometry.Point3d(-10,-20,0)
rect=Rhino.Geometry.PolylineCurve([pt0,pt1,pt2,pt3,pt0])

result=Rhino.Geometry.Curve.CreateBooleanDifference(rect,subtractors)
for crv in result: sc.doc.Objects.AddCurve(crv)
sc.doc.Views.Redraw()

No, it doesn`t. Your example shows the same bug i mentioned in my reply above. Move the large rectangle away to see it. Your subtractor objects got altered by a boolean subtraction which IMHO should never happen.

@stevebaer It seems that the Curve.CreateBooleanDifference method has two bugs. If the subtractors do not overlap themself, as the example Mitch posted above, the curve to subtract from is altered as expected but the subtractors are altered as well.

If the subtractors do overlap themself, they are somehow booleaned together first and the result of this boolean addition is subtracted from the input curve. This is the only scenario where i see that the result of the method is as expected. Try with my script above.

Also try with my script above what is returned when a curve is subtracted from another curve which does not overlap at all. It returns the first curve passed to the method. I´m shure this is a bug too.

c.

Oh, yeah - bizarre… !

This is what I eventually concocted for a workaround:

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc

pt0=Rhino.Geometry.Point3d(-10,0,0)
pt1=Rhino.Geometry.Point3d(55,0,0)
pt2=Rhino.Geometry.Point3d(55,-20,0)
pt3=Rhino.Geometry.Point3d(-10,-20,0)
rect=Rhino.Geometry.PolylineCurve([pt0,pt1,pt2,pt3,pt0])

a=0
for i in range(4):
    pt0=Rhino.Geometry.Point3d(5+a,0,0)
    pt1=Rhino.Geometry.Point3d(0+a,5,0)
    pt2=Rhino.Geometry.Point3d(-5+a,0,0)
    pt3=Rhino.Geometry.Point3d(0+a,-5,0)
    pl=Rhino.Geometry.PolylineCurve([pt0,pt1,pt2,pt3,pt0])
    result=Rhino.Geometry.Curve.CreateBooleanDifference(rect,pl)
    if result and len(result)==1:
        rect=result[0]
    a+=15
sc.doc.Objects.AddCurve(rect)
sc.doc.Views.Redraw()