fix: improve arc-tangency fitting and add layered engrave/cut passes for GravographIS

GeometrySimplifier/ArcFit now fit arcs that pass exactly through run
endpoints while balancing tangency error between trusted and estimated
directions, fixing arcs that previously bulged or broke tangent
continuity at fillet/compound-curve junctions.

GravographIS post processor gains per-layer (engrave/cut) tool passes
via a new GravographISPostConfig, so ENGRAVE/ETCH-tagged geometry runs
as a separate scribe pass with its own feed/depth and an operator
pause before the cut pass (spring-floated spindle needs a tool swap).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
aj
2026-08-06 23:15:18 -04:00
co-authored by Claude Opus 4.6
parent e493d83899
commit a085339ba9
15 changed files with 1084 additions and 138 deletions
@@ -34,4 +34,45 @@ public class NestPolylineExtractorTests
Assert.Equal(new Vector(0.25, 47.75), poly[3]);
Assert.Equal(new Vector(0.25, 46.75), poly[4]);
}
[Fact]
public void ExtractPartLayered_SplitsContinuousChainAtLayerChange()
{
// A single continuous chain (no rapid) that switches from Scribe to Cut
// must be split into two layer-uniform polylines sharing the seam vertex,
// so the post can emit a tool-change pause between engrave and cut.
var program = new Program(Mode.Absolute);
program.Codes.Add(new LinearMove(1, 0) { Layer = LayerType.Scribe });
program.Codes.Add(new LinearMove(2, 0) { Layer = LayerType.Scribe });
program.Codes.Add(new LinearMove(2, 1) { Layer = LayerType.Cut });
program.Codes.Add(new LinearMove(3, 1) { Layer = LayerType.Cut });
var drawing = new Drawing("Mixed", program);
var part = new Part(drawing, new Vector(0, 0));
var polylines = new NestPolylineExtractor().ExtractPartLayered(part);
Assert.Equal(2, polylines.Count);
Assert.Equal(LayerType.Scribe, polylines[0].Layer);
Assert.Equal(new[] { new Vector(0, 0), new Vector(1, 0), new Vector(2, 0) }, polylines[0].Points);
Assert.Equal(LayerType.Cut, polylines[1].Layer);
Assert.Equal(new[] { new Vector(2, 0), new Vector(2, 1), new Vector(3, 1) }, polylines[1].Points);
}
[Fact]
public void ExtractPartLayered_UniformChain_IsSinglePolyline()
{
var program = new Program(Mode.Absolute);
program.Codes.Add(new LinearMove(1, 0));
program.Codes.Add(new LinearMove(1, 1));
var part = new Part(new Drawing("Cut", program), new Vector(0, 0));
var polylines = new NestPolylineExtractor().ExtractPartLayered(part);
Assert.Single(polylines);
Assert.Equal(LayerType.Cut, polylines[0].Layer);
}
}