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