diff --git a/tools/adaptive-isogrid/src/nx/import_profile.py b/tools/adaptive-isogrid/src/nx/import_profile.py index 2ee0b10a..ebc2bce5 100644 --- a/tools/adaptive-isogrid/src/nx/import_profile.py +++ b/tools/adaptive-isogrid/src/nx/import_profile.py @@ -877,93 +877,83 @@ def main(): continue # --- Draw geometry --- - rib_web = profile.get("rib_web", []) + # Strategy: draw outer boundary + pocket outlines (lines+arcs) + holes + # NX sketch regions: the rib web is the area BETWEEN outer boundary + # and pocket/hole outlines. Extrude picks the rib material regions. + pockets = profile.get("pockets", []) + outer_2d = profile.get("outer_boundary", []) - if rib_web: - # ===== RIB WEB MODE: draw the actual material profile ===== - # rib_web is a list of polygon rings, each with 'exterior' and 'interiors' - # The exterior is the outer boundary of the rib material - # Each interior is a cutout (pocket or bolt hole) - total_lines = 0 - for ring_idx, ring in enumerate(rib_web): - # Draw exterior ring - ext_pts = ring['exterior'] - ext_3d = unproject_to_3d(ext_pts, transform) - n = len(ext_3d) - # Close if needed - d = math.sqrt(sum((a - b)**2 for a, b in zip(ext_3d[0], ext_3d[-1]))) + # Check if pockets are structured (lines+arcs) or legacy (point lists) + is_structured = (len(pockets) > 0 and isinstance(pockets[0], dict) + and 'lines' in pockets[0]) + + if is_structured: + lister.WriteLine(f"[import] Structured format: {len(pockets)} pockets + outer boundary") + + # Outer boundary + outer_lines, outer_arcs = _draw_outer_boundary(work_part, outer_2d, transform, lister) + lister.WriteLine(f"[import] Outer boundary: {outer_lines} lines + {outer_arcs} arcs") + + # Pocket outlines (the red lines: 3 lines + 3 arcs each) + total_lines = outer_lines + total_arcs = outer_arcs + for idx, pocket in enumerate(pockets): + nl, na = _draw_structured_pocket(work_part, pocket, transform, lister) + total_lines += nl + total_arcs += na + if (idx + 1) % 50 == 0: + lister.WriteLine(f"[import] ... {idx+1}/{len(pockets)} pockets drawn") + + lister.WriteLine(f"[import] Pockets done: {total_lines} lines + {total_arcs} arcs") + + # Holes (bolt circles) — drawn as two semicircular arcs each + holes = profile.get("holes", []) + if holes: + holes_drawn = 0 + for hole in holes: + try: + cx, cy = hole["center"] + r = hole.get("radius", hole.get("diameter", 0) / 2.0) + p1 = [cx + r, cy] + p2 = [cx, cy + r] + p3 = [cx - r, cy] + p4 = [cx, cy - r] + p1_3d = unproject_point_to_3d(p1, transform) + p2_3d = unproject_point_to_3d(p2, transform) + p3_3d = unproject_point_to_3d(p3, transform) + p4_3d = unproject_point_to_3d(p4, transform) + _draw_arc_3pt(work_part, p1_3d, p2_3d, p3_3d) + _draw_arc_3pt(work_part, p3_3d, p4_3d, p1_3d) + holes_drawn += 1 + total_arcs += 2 + except Exception as exc: + lister.WriteLine(f"[import] WARN: hole failed: {exc}") + lister.WriteLine(f"[import] Holes: {holes_drawn}/{len(holes)} drawn ({holes_drawn*2} arcs)") + + lister.WriteLine(f"[import] Total: {total_lines} lines + {total_arcs} arcs") + + else: + # Legacy format: pockets are point lists + lister.WriteLine(f"[import] Legacy format: {len(pockets)} pocket polylines") + outer_lines, outer_arcs = _draw_outer_boundary(work_part, outer_2d, transform, lister) + total_lines = outer_lines + for pocket_pts in pockets: + if len(pocket_pts) < 3: + continue + pocket_3d = unproject_to_3d(pocket_pts, transform) + n = len(pocket_3d) + d = math.sqrt(sum((a - b)**2 for a, b in zip(pocket_3d[0], pocket_3d[-1]))) if d < 0.001: n -= 1 for i in range(n): try: - _draw_line(work_part, ext_3d[i], ext_3d[(i+1) % n]) + _draw_line(work_part, pocket_3d[i], pocket_3d[(i+1) % n]) total_lines += 1 except Exception: pass - lister.WriteLine(f"[import] Ring {ring_idx}: exterior {total_lines} lines") + lister.WriteLine(f"[import] Done: {total_lines} lines in sketch") - # Draw interior rings (pocket/hole cutouts) - for int_idx, interior in enumerate(ring.get('interiors', [])): - int_3d = unproject_to_3d(interior, transform) - m = len(int_3d) - d2 = math.sqrt(sum((a - b)**2 for a, b in zip(int_3d[0], int_3d[-1]))) - if d2 < 0.001: - m -= 1 - for i in range(m): - try: - _draw_line(work_part, int_3d[i], int_3d[(i+1) % m]) - total_lines += 1 - except Exception: - pass - if (int_idx + 1) % 50 == 0: - lister.WriteLine(f"[import] ... {int_idx+1}/{len(ring['interiors'])} interiors drawn") - - num_interiors = sum(len(r.get('interiors', [])) for r in rib_web) - lister.WriteLine(f"[import] Rib web: {len(rib_web)} ring(s), {num_interiors} interiors, {total_lines} total lines") - - else: - # ===== LEGACY FALLBACK: pocket-based drawing ===== - pockets = profile.get("pockets", []) - outer_2d = profile.get("outer_boundary", []) - - # Check if pockets are structured (lines+arcs) or legacy (point lists) - is_structured = (len(pockets) > 0 and isinstance(pockets[0], dict) - and 'lines' in pockets[0]) - - if is_structured: - lister.WriteLine(f"[import] Structured format: {len(pockets)} pockets + outer boundary") - outer_lines, outer_arcs = _draw_outer_boundary(work_part, outer_2d, transform, lister) - lister.WriteLine(f"[import] Outer boundary: {outer_lines} lines + {outer_arcs} arcs") - total_lines = outer_lines - total_arcs = outer_arcs - for idx, pocket in enumerate(pockets): - nl, na = _draw_structured_pocket(work_part, pocket, transform, lister) - total_lines += nl - total_arcs += na - if (idx + 1) % 50 == 0: - lister.WriteLine(f"[import] ... {idx+1}/{len(pockets)} pockets drawn") - lister.WriteLine(f"[import] Done: {total_lines} lines + {total_arcs} arcs in sketch") - else: - lister.WriteLine(f"[import] Legacy format: {len(pockets)} pocket polylines") - outer_lines, outer_arcs = _draw_outer_boundary(work_part, outer_2d, transform, lister) - total_lines = outer_lines - for pocket_pts in pockets: - if len(pocket_pts) < 3: - continue - pocket_3d = unproject_to_3d(pocket_pts, transform) - n = len(pocket_3d) - d = math.sqrt(sum((a - b)**2 for a, b in zip(pocket_3d[0], pocket_3d[-1]))) - if d < 0.001: - n -= 1 - for i in range(n): - try: - _draw_line(work_part, pocket_3d[i], pocket_3d[(i+1) % n]) - total_lines += 1 - except Exception: - pass - lister.WriteLine(f"[import] Done: {total_lines} lines in sketch") - - # Holes for legacy/structured fallback + # Holes for legacy fallback holes = profile.get("holes", []) if holes: holes_drawn = 0