Root cause: typed segment offsetting created self-intersecting geometry at
concave corners (notches). Triangle's PSLG boundary didn't match the plotted
inset contour, allowing vertices 7+ mm outside.
Changes:
- _build_inner_plate: always use Shapely buffer(-w_frame) (robust at concavities)
- _sample_ring: use simplified polygon vertices + interpolated points on long edges
(preserves tight features without vertex clustering)
- Plot uses same inner_plate from triangulation (no mismatch)
- Post-process: snap any residual outside vertices to boundary
- Result: 0 vertices outside inner plate (was 10, up to 7.45mm)
- Add explicit corner vertices of the inset boundary (w_frame offset) to Delaunay point set
- This guarantees no triangle can cross a boundary corner
- Updated test_data geometry files to v2.0 format with typed segments
- Sandbox 2 now has proper arc curves (4 arc segments) from extract_sandbox
- Preserved holes from v1.0 geometry
- Boundary vertices also enforced on keepout boundaries
Complete rewrite of triangulation engine:
- Regular hexagonal-packed vertex grid (equilateral triangles)
- Density-adaptive refinement: denser near holes, coarser in open areas
- Boundary-conforming vertices along frame edge and hole keepouts
- Delaunay on point set + clip to valid region (inside frame, outside keepouts)
- Result: proper isogrid layout, 87 pockets from 234 triangles
- 553 NX entities, min fillet 4.89mm, mass 2770g
- No more dependency on Shewchuk Triangle library (scipy.spatial.Delaunay)
- Switched to uniform triangulation (no density-adaptive refinement for
initial pass — saves that for stress-informed iterations)
- s_min=45mm, s_max=55mm (was 12/35) — larger triangles fit 6mm fillets
- Boss keepout circles: 12 segments (was 32) — less boundary clutter
- Fillet must be >= 80% of r_f at every corner or pocket is skipped
- Result: 75 pockets, 481 NX entities, min fillet 4.85mm, mass 4066g
- adaptive_density=True param enables density refinement for future stress iterations