refactor(brain): structured pocket output — 3 lines + 3 arcs per pocket

Replaced Shapely buffer-based fillet (59-pt polylines) with exact geometric
fillet computation. Each pocket now outputs:
- 3 straight edges (line start/end pairs)
- 3 fillet arcs (center, radius, tangent points, angles)

NX import updated to use SketchLineBuilder + SketchArcBuilder (3-point).
Total NX entities: ~2,600 (was ~13,000). Includes arc fallback to 2-line
segments if SketchArcBuilder fails.

Also outputs circular hole definitions for future NX circle creation.
This commit is contained in:
2026-02-16 20:17:49 +00:00
parent fdcafe96a9
commit da9b579bcf
7 changed files with 76328 additions and 389 deletions

View File

@@ -89,8 +89,10 @@ def _plot_final_profile(geometry, pockets, ribbed_plate, out_path: Path) -> None
ax.plot(np.r_[outer[:, 0], outer[0, 0]], np.r_[outer[:, 1], outer[0, 1]], "k-", lw=1.8, label="Outer boundary")
for pocket in pockets:
pv = np.asarray(pocket["vertices"])
ax.fill(pv[:, 0], pv[:, 1], color="#88ccee", alpha=0.35, lw=0.0)
polyline = pocket.get("polyline", pocket.get("vertices", []))
pv = np.asarray(polyline)
if len(pv) >= 3:
ax.fill(pv[:, 0], pv[:, 1], color="#88ccee", alpha=0.35, lw=0.0)
if ribbed_plate.geom_type == "Polygon":
geoms = [ribbed_plate]
@@ -122,7 +124,7 @@ def run_pipeline(geometry_path: Path, params_path: Path | None, output_dir: Path
ribbed_plate = assemble_profile(geometry, pockets, params)
is_valid, checks = validate_profile(ribbed_plate, params)
profile_json = profile_to_json(ribbed_plate, params)
profile_json = profile_to_json(ribbed_plate, pockets, geometry, params)
profile_json["checks"] = checks
profile_json["pipeline"] = {
"geometry_file": str(geometry_path),