fix: apply SubProgramCall offset additively and restore curpos after expansion

ConvertMode.ToIncremental skips SubProgramCalls when computing deltas,
so all code paths that expand SubProgramCalls must: (1) set curpos to
savedPos + Offset before expanding, and (2) restore curpos afterward
so subsequent incremental codes get correct deltas.

Fixed in ConvertProgram, GraphicsHelper (AddProgram, AddProgramSplit),
PlateRenderer (DrawRapids, DrawProgramPiercePoints, GetFirstPiercePoint),
and CutDirectionArrows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-09 17:40:05 -04:00
parent bc859aa28c
commit 92461deb98
5 changed files with 156 additions and 3 deletions

View File

@@ -43,13 +43,20 @@ namespace OpenNest.Converters
case CodeType.SubProgramCall:
var subpgm = (SubProgramCall)code;
var savedMode = mode;
var savedPos = curpos;
// Apply offset: sub-program executes at the call's offset position
if (subpgm.Offset.X != 0 || subpgm.Offset.Y != 0)
curpos = subpgm.Offset;
// Position the sub-program at savedPos + Offset.
// savedPos is the base position ((0,0) here, Part.Location in rendering).
// Offset is the hole center in drawing-local coordinates.
curpos = new Vector(savedPos.X + subpgm.Offset.X, savedPos.Y + subpgm.Offset.Y);
AddProgram(subpgm.Program, ref mode, ref curpos, ref geometry);
mode = savedMode;
// Restore curpos: ConvertMode.ToIncremental skips SubProgramCalls
// when computing deltas, so subsequent incremental codes expect
// curpos to be where it was before the call.
curpos = savedPos;
break;
}
}