A few hundred shouldn’t be too taxing. The gpt code you got looks fine, a neat gpt trick is to feed the code back into gpt and ask it to parallelize it. Also there is some optimization to be had if you can preprocess the line list in smaller search buckets, e.g. group them by z, group them by direction, only run the intersection check n/k^n/k times rather than n^n (where k is number of groups)

throw the optimization suggestions in gpt, it should be able to handle the changes fine.

Ah - you’re right. Surface.ByUnion might be a better solution here. I do recall having a fox for such issues via topology methods, just not entirely sure what it was.

I also find with GPT that it varys from day to day… It’s like a human. Some days I get great responses, other days I end up swearing at it and writing the code all myself.

If you disable the highlighting cylinder (rightmost nodes) for either the ‘bounding two faces’ or the ‘bounding one face’ curves the result is pretty clear.

My guess is that in your case there were slight gaps or perhaps errors in the modeling / geometry conversion (perhaps large units at play?), which lead to conditions where you had overlapping our unconnected vertices. If they deviate from the adjacent curve in any way you get the error you described.

# Load the Python Standard and DesignScript Libraries
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import itertools
def group_lines(lines, incr = 0):
"""
Group overlapping lines together.
Parameters:
lines (list): List of Autodesk.DesignScript.Geometry.Line objects to group.
incr (int): Recursion increment counter.
Returns:
list: List of grouped lines.
"""
if len(lines) == 0 or incr > 1000 :
return []
group = [lines.pop(0)]
idx_to_remove = []
for idx, line in enumerate(lines):
if any(lines_are_overlap(line, x) for x in group):
group.append(line)
idx_to_remove.append(idx)
rest = [line for idx, line in enumerate(lines) if idx not in idx_to_remove]
return [group] + group_lines(rest, incr + 1)
def lines_are_overlap(lineA, lineB):
"""
Check if two lines overlap with each other.
Parameters:
lineA (Autodesk.DesignScript.Geometry.Line): First line to check for overlap.
lineB (Autodesk.DesignScript.Geometry.Line): Second line to check for overlap.
Returns:
bool: True if lines overlap, False otherwise.
"""
# make sure the lineA is the longest
if lineB.Length > lineA.Length:
lineA, lineB = lineB, lineA
if abs(lineA.Direction.Cross(lineB.Direction).Z) < 0.01:
lstptsB = [lineB.StartPoint, lineB.EndPoint]
for pt in lstptsB:
# if lines are overlapped
if abs((pt.DistanceTo(lineA.EndPoint) + pt.DistanceTo(lineA.StartPoint)) - lineA.Length) < 0.001:
return True
return False
def subract_lines_overlap2(lines):
"""
Subtract overlapping lines from the input list.
Parameters:
lines (list): List of Autodesk.DesignScript.Geometry.Line objects to process.
Returns:
list: List of non-overlapping lines.
"""
out = []
groups_lines = group_lines(lines)
#return groups_lines
for group_line in groups_lines:
if len(group_line) > 1:
pts = [[l.StartPoint, l.EndPoint] for l in group_line]
# flat the list
pts = sum(pts, [])
base_line = Line.ByBestFitThroughPoints(pts)
pts.sort(key = lambda p : base_line.ParameterAtPoint(p))
iter_pts = iter(pts)
for pta, ptb in zip(iter_pts, iter_pts):
if pta.DistanceTo(ptb) > 0.01:
out.append(Line.ByStartPointEndPoint(pta, ptb))
else:
out.extend(group_line)
return out
lines = IN[0]
OUT = subract_lines_overlap2(lines)