fix(cutting): exclude scribes from downstream pierce targets

This commit is contained in:
aj committed 2026-10-07 14:46:30 -04:00
1 parent 6b7d0d7f90
commit 76f73f7a87
2 files changed
+22 -2

No files matched your search

@@ -89,11 +89,13 @@ internal static class PreferredContourEntries
/// first non-rapid motion (lead-in when present — that is where the next rapid must
/// arrive), which reflects native rounding and clamping of a nominal entry.
/// </summary>
private static Vector Pierce(PreparedContours prepared, ContourChoice choice, CancellationToken token)
internal static Vector Pierce(PreparedContours prepared, ContourChoice choice, CancellationToken token)
{
var program = prepared.EmitCandidateForValidation(choice);
var execution = ExecutionMotionReader.Read(program, Vector.Zero, null, token);
var first = execution.Motions.First(m => !m.Rapid);
// The diagnostic emission includes the part's scribes before the selected contour.
// Those marks are not the downstream cut's pierce.
var first = execution.Motions.First(m => !m.Rapid && m.Layer != LayerType.Scribe);
return first.Start ?? first.End;
}
}
@@ -201,6 +201,24 @@ public class PreferredContourEntriesTests
Assert.All(proposal.HoleChoices, c => Assert.NotEqual(3, c.ContourOrdinal)); // never the perimeter
}
[Fact]
public void ScribesDoNotBecomeTheDownstreamPierceTarget()
{
var clean = RectHolesProgram((3, 3, 5, 5), (7, 3, 9, 5));
var centres = new[] { new Vector(4, 4), new Vector(8, 4), new Vector(5, 5) };
var prepared = PreparedContours.Capture(clean, ExplicitContourTests.Parameters());
var entry = prepared.Entry(2, 2, new Vector(10, 4));
var baseline = PreferredContourEntries.TryPlan(prepared, entry, new[] { 0, 1 },
centres, Arrival, _ => new(ContourFeasibilityStatus.Clear, null));
clean.MoveTo(-20, -20);
clean.Codes.Add(new LinearMove(-19, -19) { Layer = LayerType.Scribe });
var marked = PreparedContours.Capture(clean, ExplicitContourTests.Parameters());
var actual = PreferredContourEntries.TryPlan(marked, marked.Entry(2, 2, new Vector(10, 4)),
new[] { 0, 1 }, centres, Arrival, _ => new(ContourFeasibilityStatus.Clear, null));
Assert.True(actual.IsPreferred, actual.Reason);
Assert.Equal(baseline.HoleChoices.Select(c => c.Point), actual.HoleChoices.Select(c => c.Point));
}
[Fact]
public void ChainingIsDeterministic()
{