fix: strip closing duplicate points in triangulation (segfault fix), batch line creation for NX speed, 6mm endmill params
This commit is contained in:
@@ -62,7 +62,12 @@ def build_pslg(geometry, params):
|
||||
hole_markers = []
|
||||
|
||||
# Outer boundary (no offset needed — frame is handled in profile assembly)
|
||||
outer = geometry['outer_boundary']
|
||||
outer = list(geometry['outer_boundary'])
|
||||
# Strip closing duplicate if last == first
|
||||
if len(outer) > 2:
|
||||
d = np.linalg.norm(np.array(outer[0]) - np.array(outer[-1]))
|
||||
if d < 0.01:
|
||||
outer = outer[:-1]
|
||||
v_start = len(vertices)
|
||||
vertices.extend(outer)
|
||||
n = len(outer)
|
||||
@@ -84,6 +89,11 @@ def build_pslg(geometry, params):
|
||||
# Fallback for non-circular holes
|
||||
keepout_boundary = offset_polygon(hole['boundary'], keepout_dist, inward=False)
|
||||
|
||||
# Strip closing duplicate if present
|
||||
if len(keepout_boundary) > 2:
|
||||
d = np.linalg.norm(np.array(keepout_boundary[0]) - np.array(keepout_boundary[-1]))
|
||||
if d < 0.01:
|
||||
keepout_boundary = keepout_boundary[:-1]
|
||||
v_start = len(vertices)
|
||||
vertices.extend(keepout_boundary)
|
||||
n_h = len(keepout_boundary)
|
||||
|
||||
@@ -246,69 +246,97 @@ def _find_or_create_sketch(
|
||||
return sketch
|
||||
|
||||
|
||||
def _draw_polyline_in_sketch(
|
||||
def _draw_polylines_batch(
|
||||
part: Any,
|
||||
sketch: Any,
|
||||
points_3d: List[Tuple[float, float, float]],
|
||||
polylines_3d: List[List[Tuple[float, float, float]]],
|
||||
lister: Any,
|
||||
close: bool = True,
|
||||
) -> int:
|
||||
"""
|
||||
Draw a closed polyline in the sketch using individual line segments.
|
||||
Returns number of lines created.
|
||||
Draw multiple closed polylines in the sketch efficiently.
|
||||
|
||||
Creates all lines as NX curves first (fast), then adds them
|
||||
to the sketch in one batch call (much faster than per-line builders).
|
||||
|
||||
Returns total number of lines created.
|
||||
"""
|
||||
import NXOpen
|
||||
|
||||
if len(points_3d) < 2:
|
||||
return 0
|
||||
all_lines = []
|
||||
total_lines = 0
|
||||
|
||||
lines_created = 0
|
||||
n = len(points_3d)
|
||||
for points_3d in polylines_3d:
|
||||
if len(points_3d) < 2:
|
||||
continue
|
||||
|
||||
# If last point == first point, don't double-close
|
||||
if close and len(points_3d) >= 3:
|
||||
d = math.sqrt(sum((a - b) ** 2 for a, b in zip(points_3d[0], points_3d[-1])))
|
||||
if d < 0.001:
|
||||
n = len(points_3d) - 1 # skip duplicate closing point
|
||||
n = len(points_3d)
|
||||
# Strip closing duplicate
|
||||
if close and n >= 3:
|
||||
d = math.sqrt(sum((a - b) ** 2 for a, b in zip(points_3d[0], points_3d[-1])))
|
||||
if d < 0.001:
|
||||
n = n - 1
|
||||
|
||||
segments = n if close else (n - 1)
|
||||
segments = n if close else (n - 1)
|
||||
|
||||
for i in range(segments):
|
||||
p1 = points_3d[i]
|
||||
p2 = points_3d[(i + 1) % n]
|
||||
for i in range(segments):
|
||||
p1 = points_3d[i]
|
||||
p2 = points_3d[(i + 1) % n]
|
||||
|
||||
try:
|
||||
# CurveCollection.CreateLine(start: Point, end: Point) -> Line
|
||||
start_obj = part.Points.CreatePoint(
|
||||
NXOpen.Point3d(p1[0], p1[1], p1[2])
|
||||
)
|
||||
end_obj = part.Points.CreatePoint(
|
||||
NXOpen.Point3d(p2[0], p2[1], p2[2])
|
||||
)
|
||||
line = part.Curves.CreateLine(start_obj, end_obj)
|
||||
all_lines.append(line)
|
||||
total_lines += 1
|
||||
except Exception as exc:
|
||||
if total_lines == 0:
|
||||
lister.WriteLine(f"[import] CreateLine failed: {exc}")
|
||||
# Try SketchLineBuilder as fallback for first line
|
||||
try:
|
||||
lb = part.Sketches.CreateLineBuilder()
|
||||
lb.SetStartPoint(NXOpen.Point3d(p1[0], p1[1], p1[2]))
|
||||
lb.SetEndPoint(NXOpen.Point3d(p2[0], p2[1], p2[2]))
|
||||
lb.Commit()
|
||||
lb.Destroy()
|
||||
total_lines += 1
|
||||
lister.WriteLine("[import] SketchLineBuilder fallback worked")
|
||||
except Exception as exc2:
|
||||
lister.WriteLine(f"[import] Both methods failed: {exc2}")
|
||||
return 0
|
||||
|
||||
# Add all curves to sketch in one batch call
|
||||
if all_lines:
|
||||
try:
|
||||
start_pt = NXOpen.Point3d(p1[0], p1[1], p1[2])
|
||||
end_pt = NXOpen.Point3d(p2[0], p2[1], p2[2])
|
||||
|
||||
# SketchCollection.CreateLineBuilder() -> SketchLineBuilder
|
||||
# SketchLineBuilder.SetStartPoint(Point3d), .SetEndPoint(Point3d)
|
||||
# Builder.Commit() -> NXObject, Builder.Destroy()
|
||||
line_builder = part.Sketches.CreateLineBuilder()
|
||||
line_builder.SetStartPoint(start_pt)
|
||||
line_builder.SetEndPoint(end_pt)
|
||||
line_builder.Commit()
|
||||
line_builder.Destroy()
|
||||
|
||||
lines_created += 1
|
||||
# Sketch.AddGeometry(infer, ellipse, curves)
|
||||
sketch.AddGeometry(
|
||||
NXOpen.Sketch.InferConstraintsOption.DoNotInferConstraints,
|
||||
NXOpen.Sketch.AddEllipseOption.None_,
|
||||
all_lines,
|
||||
)
|
||||
lister.WriteLine(f"[import] Added {len(all_lines)} lines to sketch via AddGeometry")
|
||||
except Exception as exc:
|
||||
if lines_created == 0:
|
||||
lister.WriteLine(f"[import] Line creation failed: {exc}")
|
||||
# Try fallback: create curve + add to sketch
|
||||
lister.WriteLine(f"[import] AddGeometry batch failed: {exc}")
|
||||
# Try adding one by one
|
||||
added = 0
|
||||
for line in all_lines:
|
||||
try:
|
||||
start_obj = part.Points.CreatePoint(NXOpen.Point3d(p1[0], p1[1], p1[2]))
|
||||
end_obj = part.Points.CreatePoint(NXOpen.Point3d(p2[0], p2[1], p2[2]))
|
||||
line = part.Curves.CreateLine(start_obj, end_obj)
|
||||
sketch.AddGeometry(
|
||||
NXOpen.Sketch.InferConstraintsOption.DoNotInferConstraints,
|
||||
NXOpen.Sketch.AddEllipseOption.None_,
|
||||
[line],
|
||||
)
|
||||
lines_created += 1
|
||||
except Exception as exc2:
|
||||
lister.WriteLine(f"[import] Fallback line also failed: {exc2}")
|
||||
added += 1
|
||||
except Exception:
|
||||
pass
|
||||
lister.WriteLine(f"[import] Added {added}/{len(all_lines)} lines individually")
|
||||
|
||||
return lines_created
|
||||
return total_lines
|
||||
|
||||
|
||||
def _draw_circle_in_sketch(
|
||||
@@ -479,28 +507,30 @@ def main():
|
||||
|
||||
total_lines = 0
|
||||
|
||||
# Draw outer boundary
|
||||
# Collect all polylines to draw
|
||||
all_polylines_3d = []
|
||||
|
||||
# Outer boundary
|
||||
outer_2d = profile.get("outer_boundary", [])
|
||||
if outer_2d:
|
||||
outer_3d = unproject_to_3d(outer_2d, transform)
|
||||
n = _draw_polyline_in_sketch(work_part, sketch, outer_3d, lister, close=True)
|
||||
total_lines += n
|
||||
lister.WriteLine(f"[import] Outer boundary: {n} lines")
|
||||
all_polylines_3d.append(outer_3d)
|
||||
|
||||
# Draw pocket cutouts
|
||||
# Pocket cutouts
|
||||
pockets = profile.get("pockets", [])
|
||||
lister.WriteLine(f"[import] Drawing {len(pockets)} pockets...")
|
||||
lister.WriteLine(f"[import] Preparing {len(pockets)} pockets + outer boundary...")
|
||||
|
||||
for pi, pocket_pts in enumerate(pockets):
|
||||
for pocket_pts in pockets:
|
||||
if len(pocket_pts) < 3:
|
||||
continue
|
||||
pocket_3d = unproject_to_3d(pocket_pts, transform)
|
||||
n = _draw_polyline_in_sketch(work_part, sketch, pocket_3d, lister, close=True)
|
||||
total_lines += n
|
||||
all_polylines_3d.append(pocket_3d)
|
||||
|
||||
# Progress every 50 pockets
|
||||
if (pi + 1) % 50 == 0:
|
||||
lister.WriteLine(f"[import] ... {pi + 1}/{len(pockets)} pockets drawn")
|
||||
# Draw everything in one batch
|
||||
lister.WriteLine(f"[import] Creating {len(all_polylines_3d)} polylines as NX curves...")
|
||||
total_lines = _draw_polylines_batch(
|
||||
work_part, sketch, all_polylines_3d, lister, close=True,
|
||||
)
|
||||
|
||||
# Deactivate sketch
|
||||
try:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user