fix: strip closing duplicate points in triangulation (segfault fix), batch line creation for NX speed, 6mm endmill params

This commit is contained in:
2026-02-16 19:29:41 +00:00
parent 61dcefb5ea
commit c93239c9c6
3 changed files with 34482 additions and 86728 deletions

View File

@@ -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)

View File

@@ -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