fix: preserve leading rapid in programs to prevent missing contour segment

The CAD converter and BOM import were stripping the leading RapidMove
after normalizing program coordinates to origin. This left programs
starting with a LinearMove, causing the post-processor to use that
endpoint as the pierce point — making the first contour edge zero-length
and losing the closing segment (e.g. the bottom line on curved parts).

Root cause: CadConverterForm.GetDrawings(), OnSplitClicked(), and
BomImportForm all called pgm.Codes.RemoveAt(0) after offsetting the
rapid to origin. The rapid at (0,0) is a harmless no-op that marks the
contour start point for downstream processing.

Also adds EnsureLeadingRapid() safety net in the Cincinnati post for
existing nest files that already have the rapid stripped.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-01 10:33:59 -04:00
parent fb067187b4
commit a8341e9e99
5 changed files with 101 additions and 4 deletions

View File

@@ -70,6 +70,26 @@ public sealed class CincinnatiPartSubprogramWriter
w.WriteLine($"M99 (END OF {drawingName})");
}
/// <summary>
/// If the program has no leading rapid, inserts a synthetic rapid at the
/// last motion endpoint (the contour return point). This ensures the feature
/// writer knows the true pierce location and preserves the first contour segment.
/// </summary>
internal static void EnsureLeadingRapid(Program pgm)
{
if (pgm.Codes.Count == 0 || pgm.Codes[0] is RapidMove)
return;
for (var i = pgm.Codes.Count - 1; i >= 0; i--)
{
if (pgm.Codes[i] is Motion lastMotion)
{
pgm.Codes.Insert(0, new RapidMove(lastMotion.EndPoint));
return;
}
}
}
/// <summary>
/// Creates a sub-program key for matching parts to their sub-programs.
/// </summary>
@@ -103,6 +123,13 @@ public sealed class CincinnatiPartSubprogramWriter
var bbox = pgm.BoundingBox();
pgm.Offset(-bbox.Location.X, -bbox.Location.Y);
// If the program has no leading rapid, the feature writer
// will use the first motion endpoint as the pierce point,
// losing the first contour segment. Insert a synthetic rapid
// at the contour's return point (last motion endpoint) so
// the full contour is preserved.
EnsureLeadingRapid(pgm);
entries.Add((subNum, part.BaseDrawing.Name, pgm));
}
}