fix(posts): post CI Fiber cut-offs in their sequence, not last

b0997f6 moved every cut-off after the parts. Plate.Parts order is the
cut sequence, and the user sets each cut-off's place in it (Set
Sequence), so the post must follow it rather than reorder. Cut-offs
still post as uncompensated open lines with no lead-in.
This commit is contained in:
aj
2026-09-28 18:41:06 -04:00
parent 86dbd8819b
commit 6803d7519f
3 changed files with 38 additions and 17 deletions
@@ -223,7 +223,7 @@ public class CIFiberPostProcessorTests
}
[Fact]
public void Post_CutOff_PostsLastWithoutCompensationOrLeadIn()
public void Post_CutOff_PostsWithoutCompensationOrLeadIn()
{
var nest = MakeSquareWithHoleNest();
var plate = nest.Plates[0];
@@ -231,17 +231,12 @@ public class CIFiberPostProcessorTests
// Vertical cut-off at X=20: a bare rapid + line, no lead-in.
var cutOff = new CutOff(new Vector(20, 0), CutOffAxis.Vertical);
cutOff.Regenerate(plate, new CutOffSettings());
plate.Parts.Insert(0, new Part(cutOff.Drawing, Vector.Zero));
plate.Parts.Add(new Part(cutOff.Drawing, Vector.Zero));
var lines = Lines(Post(nest));
// Cut-off follows the real part despite being first in plate order.
var partEnd = lines.IndexOf("( PART END )");
var cutOffPart = lines.IndexOf("( Part #2 )");
Assert.True(partEnd >= 0 && cutOffPart > partEnd);
var n3 = lines.IndexOf("N3:");
Assert.True(n3 > cutOffPart);
Assert.True(n3 > lines.IndexOf("( PART:CutOff-V-20.00 )"));
Assert.Equal("/L \"L0\"", lines[n3 + 1]);
Assert.Equal("V.E.R3=3", lines[n3 + 2]);
Assert.StartsWith("G0X20Y", lines[n3 + 3]);
@@ -251,6 +246,34 @@ public class CIFiberPostProcessorTests
Assert.Equal("/L \"ZHSOFF\"", lines[n3 + 7]);
}
[Fact]
public void Post_CutOff_FollowsPlateSequence()
{
// Plate order is the cut sequence: part, cut-off, part. The cut-off is
// sequence 2, so it posts second, not after every part.
var nest = MakeSquareWithHoleNest();
var plate = nest.Plates[0];
plate.Parts.Add(new Part(plate.Parts[0].BaseDrawing, new Vector(40, 2)));
var cutOff = new CutOff(new Vector(20, 0), CutOffAxis.Vertical);
cutOff.Regenerate(plate, new CutOffSettings());
plate.Parts.Insert(1, new Part(cutOff.Drawing, Vector.Zero));
var lines = Lines(Post(nest));
Assert.Equal(
new[] { "( PART:square-hole )", "( PART:CutOff-V-20.00 )", "( PART:square-hole )" },
lines.Where(l => l.StartsWith("( PART:")).ToArray()
);
// Part number and restart label run in the same order: the first
// part's hole and perimeter are N1/N2, so the cut-off is N3.
var cutOffBlock = lines.IndexOf("( PART:CutOff-V-20.00 )");
Assert.Equal("( Part #2 )", lines[cutOffBlock - 1]);
Assert.Equal("V.E.R4=2", lines[cutOffBlock + 1]);
Assert.Equal("N3:", lines[cutOffBlock + 2]);
}
[Fact]
public void Post_ValidatesTableSize()
{
@@ -196,14 +196,10 @@ namespace OpenNest.Posts.CincinnatiCIFiber
private int WriteSheet(Plate plate, TextWriter w, int contourNumber)
{
// Cut-offs run last: severing the sheet first would free the
// skeleton before the parts are cut (matches the CL post).
var ordered = plate
.Parts.Where(p => !p.BaseDrawing.IsCutOff)
.Concat(plate.Parts.Where(p => p.BaseDrawing.IsCutOff));
// Plate order is the cut sequence, cut-offs included: the user sets
// where each cut-off runs, so the post must not reorder them.
var partNumber = 0;
foreach (var part in ordered)
foreach (var part in plate.Parts)
{
partNumber++;
contourNumber = WritePart(part, partNumber, w, contourNumber);
+4 -2
View File
@@ -28,7 +28,9 @@ uses the Cincinnati machine-sample convention, not a generic TF5200 laser API:
and `%`.
- Motion endpoints are sheet-absolute XY. Arc `I`/`J` are offsets from the arc
start, matching the G162 convention; the post does not explicitly emit G162.
- Sheet cut-offs post after every part on their sheet. Each segment is an open
- Parts and sheet cut-offs post in the plate's cut sequence (`Plate.Parts`
order, as set by Set Sequence or a sequencer). A cut-off is not moved after
the parts. Each segment is an open
line with no lead-in: rapid to its start, `/L "L4"`, `/L "L6"`, the `G1`,
and `/L "ZHSOFF"`. No `G41`/`G42` is selected, because the line is the beam
centreline and has no inside or outside. Whether the `L4` macro runs
@@ -85,7 +87,7 @@ validated and saved only when OK is pressed.
[Output-contract tests](../OpenNest.Tests/CincinnatiCIFiber/CIFiberPostProcessorTests.cs)
cover a square with a hole, coordinate transforms/formatting, lead-in rejection,
cut-off ordering and output, table bounds, suppression/scribe handling, and
cut-off sequencing and output, table bounds, suppression/scribe handling, and
multi-sheet output in both modes. Run:
```sh