Files
OpenNest/docs/geometry/lead-in-placement.md
T
ajandClaude Opus 5.5 8c7dc41ce8 feat(planning): warn about tipping parts and retire legacy lead-in assignment
Plan Cutting is now the only automatic lead-in assignment, and parts the
support grid cannot hold level are reported wherever they lack a
steadying tab.

- Remove Assign Lead-ins (plate and nest), LeadInAssigner, the lead-in
  tool's Auto-Assign button and the Auto Tab size range; old settings
  with autoTab sizes still load
- Manual Place Lead-in tabs the clicked entry when support tabs are on
  and the grid cannot hold the part (SupportTabSettings)
- New PartSupport finding: Plan Cutting replay and best-effort plans
  warn when a drawing pin, a lead-in that does not fit or no single tab
  leaves a part unsteady; the pre-post review checks each placed
  program's outside tab gap. These warnings replace the advisory
  weak-tab notes; only the inside-corner tab note stays advisory, and
  never for a pin
- Pinned perimeters keep their pin but carry the support analysis
- Draw grid points as pixel-snapped squares without anti-aliasing
- Post fixtures build lead-ins through a test-only TestLeadIns helper
- Docs: support tabs, pre-post verification and planner notes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 23:54:40 -04:00

4.2 KiB

Lead-in placement at corners

Straight (LineLeadIn) lead-ins at closed internal contour corners use the inward angle bisector instead of the normal of whichever edge was selected. With the default 90-degree approach angle, a rectangular cutout therefore gets a diagonal lead-in into the scrap, rather than one lying along the other edge. This applies to automatic assignment and manual placement. The manual preview uses the same Core calculation, including when the lead-in style changes while the cursor is stationary.

ContourCuttingStrategy.ComputeLeadInNormal combines the two adjacent inward unit normals. It handles either winding, either selected edge, rotated parts, and line/arc junctions using their local normals. Summing vectors avoids angle wraparound and edge-length weighting. Open contours, disconnected endpoints, zero-length edges, and cusps without a unique bisector retain the entity normal.

The configured approach-angle offset is still applied relative to the computed normal; 90 degrees follows the bisector. Lead-in length is unchanged. Mid-edge points, external contours, circles, curved/composite lead-in styles, and lead-outs keep their existing placement rules.

This is a local direction correction, not a whole-path clearance guarantee. An excessively long lead-in or an approach angle rotated away from the bisector can still leave a small cutout. General non-circular containment/length clamping and sharp-corner handling for curved/composite lead-ins remain separate work.

Outside perimeter corners

A straight (LineLeadIn) lead-in at a convex corner of the outside perimeter (interior angle under 180 degrees) extends the edge cut first: the pierce sits on that edge's line, behind the corner, and the torch travels straight into the corner and keeps cutting along the same line. Which of the two edges was picked (auto assignment or the manual cursor) does not matter; the cut direction never changes. The approach angle is ignored at such a corner.

The straight lead is used only while its pierce stays at least CuttingParameters.PierceClearance (or the pierce zone radius, when larger) from the contour and the lead crosses the contour nowhere but at the corner. Very flat corners (about 165 degrees and over for a 0.25 lead with 0.0625 clearance) fall back to the normal lead-in, perpendicular to the first-cut edge, so tessellated curves do not get straight leads. Reflex perimeter corners (the inside corner of an L) use the notch bisector, like cutout corners.

A LineLeadOut mirrors this: at a convex perimeter corner it runs straight on past the corner along the last-cut edge, with the same clearance fallback to the last-cut edge's normal and a bisector at reflex corners. A tabbed perimeter gets no run-out: every lead-out style leaves from where the trimmed cut actually ends, on that end's normal, so an arc lead-out starts on its own radius and the tab gap stays uncut. ContourCuttingStrategy.ResolveLeadIn/ResolveLeadOut own these rules; program generation and the manual preview share them. Other lead-in styles are unchanged.

Regression checks

Run dotnet test OpenNest.Tests/OpenNest.Tests.csproj --filter "FullyQualifiedName~CutoutCornerLeadInTests|FullyQualifiedName~PerimeterCornerLeadInTests". The cutout tests exercise generated part programs, default automatic placement, every rectangular corner with both adjoining edges and windings, part rotation, acute and obtuse angles, reflex corners, line/arc corners, preview agreement, and unchanged/fallback behavior. The perimeter tests cover every square corner under both windings and a rotation, auto and manual placement from either edge, preview agreement, approach-angle handling, the flat-corner clearance fallback, reflex notches, and straight lead-outs.

Windows manual check: import a part with small rectangular cutouts and use Plate > Plan Cutting. Confirm diagonal lead-ins at the cutout corners. Under Plate > Place Lead-in, select the part, lock a cutout, and hover a corner: the preview should point into the cutout and the committed lead-in should match. Hover a mid-edge point and confirm perpendicular placement is unchanged. Windows visual interaction is not verified by the Linux cross-build.