fix(cnc): stop double-counting first incremental rapid in rapid display
RapidEnumerator primed the walk position at the first pierce point, then the skipped first rapid advanced it again. Raw programs start with a zero rapid so this was invisible, but lead-in programs start with a real incremental offset to the pierce, which shifted every later rapid by that delta and drew rapids off the sheet. Start the walk at the program origin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,13 +12,14 @@ namespace OpenNest.CNC
|
|||||||
var results = new List<Segment>();
|
var results = new List<Segment>();
|
||||||
|
|
||||||
// Draw the rapid from the previous tool position to the program's first
|
// Draw the rapid from the previous tool position to the program's first
|
||||||
// pierce point. This also primes pos so the interior walk interprets
|
// pierce point. The walk then starts at the program origin (basePos), not
|
||||||
// Incremental deltas from the correct absolute location (basePos), which
|
// the pierce: the skipped first rapid still advances pos, so starting at
|
||||||
// matters for raw pre-lead-in programs that are emitted Incremental.
|
// the pierce would apply a nonzero Incremental first delta twice (as in
|
||||||
|
// lead-in programs) and shift every later rapid by it.
|
||||||
var firstPierce = FirstPiercePoint(pgm, basePos);
|
var firstPierce = FirstPiercePoint(pgm, basePos);
|
||||||
results.Add(new Segment(startPos, firstPierce));
|
results.Add(new Segment(startPos, firstPierce));
|
||||||
|
|
||||||
var pos = firstPierce;
|
var pos = basePos;
|
||||||
Walk(pgm, basePos, ref pos, skipFirst: true, results);
|
Walk(pgm, basePos, ref pos, skipFirst: true, results);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,28 @@ namespace OpenNest.Tests.CNC
|
|||||||
Assert.Equal(new Vector(106, 206), segments[1].To);
|
Assert.Equal(new Vector(106, 206), segments[1].To);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Enumerate_IncrementalProgramWithNonZeroFirstRapid_DoesNotDoubleCountIt()
|
||||||
|
{
|
||||||
|
// Lead-in programs (ContourCuttingStrategy output) are Incremental and
|
||||||
|
// start with a nonzero rapid from the part origin to the first pierce.
|
||||||
|
var pgm = new Program(Mode.Incremental);
|
||||||
|
pgm.Codes.Add(new RapidMove(2, 3));
|
||||||
|
pgm.Codes.Add(new LinearMove(5, 0));
|
||||||
|
pgm.Codes.Add(new RapidMove(1, 1));
|
||||||
|
|
||||||
|
var segments = RapidEnumerator.Enumerate(
|
||||||
|
pgm,
|
||||||
|
basePos: new Vector(100, 200),
|
||||||
|
startPos: new Vector(0, 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
Assert.Equal(2, segments.Count);
|
||||||
|
Assert.Equal(new Vector(102, 203), segments[0].To);
|
||||||
|
Assert.Equal(new Vector(107, 203), segments[1].From);
|
||||||
|
Assert.Equal(new Vector(108, 204), segments[1].To);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Enumerate_SubProgramCall_RapidEndsAtAbsoluteHolePierce()
|
public void Enumerate_SubProgramCall_RapidEndsAtAbsoluteHolePierce()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user