Does CurveBooleanUnion work?


#1

Hi there,

I’ve been trying to use CurveBooleanUnion and have run the example as shown in the documentation on 2 coplanar rectangular curves which overlap in one corner.

The script appears to run ok, however, I don’t get any resulting union curve. All I end up with are the same curves I started with. None of the exceptions in the def in curve.py are raised.

Any advice is welcome.

Thanks!


(Menno Deij - van Rijswijk) #2

Have you tried your script with two curves that do give a correct result with the RhinoCommand CurveBoolean? That would be the first thing I’d do.

Other than that, the code to CurveBooleanUnion is below (courtesy https://github.com/mcneel/rhinopython/blob/master/scripts/rhinoscript/curve.py)

If you use that code, rather than calling rs.CurveBooleanUnion, you can step through and see where the trouble is, for example by inserting some debug code to check length of lists etc.
My guess is that the call to CurveBooleanUnion does not return any curves because your curves are not (exactly) planar. But - that’s just a guess :smile:

def CurveBooleanUnion(curve_id):
    """Calculate the union of two or more closed, planar curves and
    add the results to the document. Note, curves must be coplanar.
    Parameters:
      curve_id = list of two or more close planar curves identifiers
    Returns:
      The identifiers of the new objects.
    """
    in_curves = [rhutil.coercecurve(id,-1,True) for id in curve_id]
    if len(in_curves)<2: raise ValueException("curve_id must have at least 2 curves")
    out_curves = Rhino.Geometry.Curve.CreateBooleanUnion(in_curves)
    curves = []
    if out_curves:
        for curve in out_curves:
            if curve and curve.IsValid:
                rc = scriptcontext.doc.Objects.AddCurve(curve)
                curve.Dispose()
                if rc==System.Guid.Empty: raise Exception("unable to add curve to document")
                curves.append(rc)
        scriptcontext.doc.Views.Redraw()
    return curves

#3

Thanks for the suggestions & in answer to the questions:
Yes, I’ve had it work with using the CurveBoolean command from within the interface, quite happily.
I like the idea of just pulling in the CurveBooleanUnion function to my script to debug (previously I’d been adding debug comments to the curve.py file which required a restart every alteration). This leaves me with 2 questions:

  1. how would I import utility as rhutil in my own script so that the CurveBooleanUnion function will work? I’ve tried but it states there is no module called utility!
  2. From my debugging it looks like the function is creating a valid curve in out_curves and appends it to curves. Again, no exception is being raised. Please excuse the formatting. I’m not having much luck getting the <pre><code> tags behaving properly in the preview.

From the following code, I get the following output:

def CurveBooleanUnion(curve_id):
print "in CurveBooleanUnion"
"""Calculate the union of two or more closed, planar curves and
add the results to the document. Note, curves must be coplanar.
Parameters:
  curve_id = list of two or more close planar curves identifiers
Returns:
  The identifiers of the new objects.
"""
in_curves = [rhutil.coercecurve(id,-1,True) for id in curve_id]
if len(in_curves)<2: raise ValueException("curve_id must have at least 2 curves")
out_curves = Rhino.Geometry.Curve.CreateBooleanUnion(in_curves)
curves = []

print "created out_curves"

if out_curves:
    print "parsing out_curves"
    for curve in out_curves:
        print "checking for valid curve"
        if curve and curve.IsValid:
            print "adding valid curve"
            rc = scriptcontext.doc.Objects.AddCurve(curve)
            print "disposing of curve"
            curve.Dispose()
            print "checking if empty"
            if rc==System.Guid.Empty: 
                raise Exception("unable to add curve to document")
            print "appending curves with new curve"
            curves.append(rc)
    print "redrawing view"
    scriptcontext.doc.Views.Redraw()
print curves
return curves

and the output:

created out_curves
parsing out_curves
checking for valid curve
adding valid curve
disposing of curve
checking if empty
appending curves with new curve
redrawing view
[<System.Guid object at 0x000000000000002B [61493cde-3eab-48e0-8113-1854aec4df2d]>]


#4

OK. I’ve found out what was catching me out. The documentation gives an example call which deletes the curves you’ve just created rather than the source curves. Perhaps a better example would be:


curve_ids = rs.GetObjects(“Select curves to union”, rs.filter.curve)
if curve_ids and len(curve_ids)>1:
    result = rs.CurveBooleanUnion(curve_ids)
    if result: rs.DeleteObjects(curve_ids)

rather than the current:


curve_ids = rs.GetObjects(“Select curves to union”, rs.filter.curve)
if curve_ids and len(curve_ids)>1:
    result = rs.CurveBooleanUnion(curve_ids)
    if result: rs.DeleteObjects(result)


(Steve Baer) #5

Thanks, I’ll change the help docs to reflect this better example in the future.


#6

That’s great! Thanks.