I use rs.CurveBooleanUnion and check the areas, but this method is very slow. Is there a faster way?
Here’s my script. It takes first one curve, second a list of curves, and checks for overlaps between the first curve and the curves in the list. Returns those that overlap and the ones that don’t in separate lists.
def shape_filter_intersect(curve_bound,shapes):
area1 = rs.Area(curve_bound)
false_shapes = []
true_shapes = []
for shape in shapes:
area2 = rs.Area(shape)
areasum = area1 + area2
areasum=float('%.3f'%(areasum)) #ROUND TO 3 DECIMALS
crvbool = rs.CurveBooleanUnion([curve_bound,shape])
if len(crvbool) != 1:
rs.DeleteObjects(crvbool)
false_shapes.append(shape)
else:
areabool = rs.Area(crvbool)
areabool=float('%.3f'%(areabool)) #ROUND TO 3 DECIMALS
if areabool != areasum: # if not equal
rs.DeleteObjects(crvbool)
false_shapes.append(shape)
else:
rs.DeleteObjects(crvbool)
true_shapes.append(shape)
return false_shapes, true_shapes
(2)
skip the unneeded area calculation (put it in the else part of the condition).
(3)
there might be some performance tricks using polylines within tolerances or a rough version first … depends a bit on the context, amount of hits, complexity of curves and so on.
(4)
are you turning redraw off ?
give a feedback if above already helps. happy coding - kind regards -tom
From what I read in the documentation, PlanarClosedCurveRelationship and PlanarCurveCollision are used to check for intersections not for overlaping. So they don’t help.
Your definition of overlaps does not correspond to the curves themselves, but rather the regions they enclose. On the left, the curves themselves intersect with no overlap, and on the right they intersect with an overlap.
If you need to check for region overlaps, you will likely need to work with surfaces or volumes made from your curves. For example on the left, a BooleanIntersection between volumes extruded from the curves will have a non-zero volume. On the right the volume will either fail to calculate or be zero.
@Helvetosaur , you were right. my definition of overlap was not correct. Two curves overlap when they have a sub-segment overlapping. Here’s the new diagram.
Below, new code. I used Rhino.Geometry.Intersect.Intersection.CurveCurve() and Rhino.Geometry.PointContainment.Inside() to chek for overlap and inclusion.
def shape_filter_intersect2(curve_bound,shapes):
tol = 1
plane = Rhino.Geometry.Plane.WorldXY
false_shapes = []
true_shapes = []
curve_bound = rs.coercecurve(curve_bound)
for shape in shapes:
shape = rs.coercecurve(shape)
events = Rhino.Geometry.Intersect.Intersection.CurveCurve(curve_bound, shape, tol, tol)
has_overlap = False
if events:
for event in events:
if event.IsOverlap:
has_overlap = True
break
if has_overlap:
result = shape.TryGetPolyline()
if result and result[0]: # success
polyline = result[1]
has_strictly_inside_point = False
for pt in polyline:
containment = curve_bound.Contains(pt, plane, tol)
if containment == Rhino.Geometry.PointContainment.Inside:
has_strictly_inside_point = True
break
if has_strictly_inside_point:
#print("✅ At least one point strictly inside ")
false_shapes.append(shape)
else:
#print("❌ All points outside or on edge")
true_shapes.append(shape)
else:
#print("⚠️ Shape is not a valid polyline")
false_shapes.append(shape)
else:
#print("❌ No overlap")
false_shapes.append(shape)
# Convert shapes to Rhino object IDs for further action
false_shapes_IDs = [sc.doc.Objects.AddCurve(shape) for shape in false_shapes]
true_shapes_IDs = [sc.doc.Objects.AddCurve(shape) for shape in true_shapes]
return false_shapes_IDs, true_shapes_IDs