fix: track tool position through sub-programs in ConvertMode
ConvertMode.ToIncremental skipped SubProgramCall codes entirely when computing deltas, so parent motions after a sub-call were encoded as if the tool never moved. Several traversal sites (ConvertProgram, GraphicsHelper, PlateRenderer, CutDirectionArrows, Program.BoundingBox) worked around this with save/restore hacks that treated sub-calls as transparent — but DrawRapids legitimately tracks actual tool position, so after the last hole the first perimeter rapid was applied to the wrong base, drifting the rendered perimeter past the plate edge by roughly the distance to the last hole. Fix the root cause: ToIncremental and ToAbsolute now walk sub-programs to compute where they leave the tool, and advance pos accordingly. The other traversals capture a frameOrigin at entry and compute sub-call placement as frameOrigin + Offset, letting pos advance naturally through the sub recursion. All the save/restore workarounds are removed. Program.BoundingBox also picks up the same frame-origin treatment, which corrects a latent bug where absolute-mode endpoints and nested sub-calls dropped the parent's frame origin. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -288,6 +288,10 @@ namespace OpenNest.CNC
|
||||
|
||||
private Box BoundingBox(ref Vector pos)
|
||||
{
|
||||
// Capture the frame origin at entry. Sub-program Offsets and
|
||||
// absolute-mode endpoints are relative to this fixed origin.
|
||||
var frameOrigin = pos;
|
||||
|
||||
double minX = 0.0;
|
||||
double minY = 0.0;
|
||||
double maxX = 0.0;
|
||||
@@ -303,7 +307,7 @@ namespace OpenNest.CNC
|
||||
{
|
||||
var line = (LinearMove)code;
|
||||
var pt = Mode == Mode.Absolute ?
|
||||
line.EndPoint :
|
||||
frameOrigin + line.EndPoint :
|
||||
line.EndPoint + pos;
|
||||
|
||||
if (pt.X > maxX)
|
||||
@@ -325,7 +329,7 @@ namespace OpenNest.CNC
|
||||
{
|
||||
var line = (RapidMove)code;
|
||||
var pt = Mode == Mode.Absolute
|
||||
? line.EndPoint
|
||||
? frameOrigin + line.EndPoint
|
||||
: line.EndPoint + pos;
|
||||
|
||||
if (pt.X > maxX)
|
||||
@@ -358,8 +362,8 @@ namespace OpenNest.CNC
|
||||
}
|
||||
else
|
||||
{
|
||||
endpt = arc.EndPoint;
|
||||
centerpt = arc.CenterPoint;
|
||||
endpt = frameOrigin + arc.EndPoint;
|
||||
centerpt = frameOrigin + arc.CenterPoint;
|
||||
}
|
||||
|
||||
double minX1;
|
||||
@@ -433,10 +437,13 @@ namespace OpenNest.CNC
|
||||
case CodeType.SubProgramCall:
|
||||
{
|
||||
var subpgm = (SubProgramCall)code;
|
||||
var subPos = subpgm.Offset.X != 0 || subpgm.Offset.Y != 0
|
||||
? new Vector(subpgm.Offset.X, subpgm.Offset.Y)
|
||||
: pos;
|
||||
var box = subpgm.Program.BoundingBox(ref subPos);
|
||||
if (subpgm.Program == null)
|
||||
break;
|
||||
|
||||
// Sub-program frame origin in this program's frame
|
||||
// is frameOrigin + Offset, regardless of current pos.
|
||||
pos = frameOrigin + subpgm.Offset;
|
||||
var box = subpgm.Program.BoundingBox(ref pos);
|
||||
|
||||
if (box.Left < minX)
|
||||
minX = box.Left;
|
||||
|
||||
Reference in New Issue
Block a user