fix(diagnostics): read absolute subprogram holes and refuse unknown codes

PlateOverlapAnalyzer converted clean programs directly with
ConvertProgram.ToGeometry, which adds call offsets only to
incremental moves, so holes in absolute-mode subprograms were read at
their frame origin. A square with two absolute holes reported
"Native material contours cross or touch", and the Plan Cutting
overlap gate blocked it while the incremental twin passed. Convert an
owned incremental-mode copy instead (PreparedContours.CopyForGeometry,
now internal, the same normalization the cutting planner uses).

The analyzer also threw on a program whose Codes list was null and
cast or cloned instructions it does not know. It now refuses a
missing list and anything other than the exact built-in instruction
types as an incomplete check, before any copy or conversion runs.
Pre-post verification and the plate overlap overlay share this path.
This commit is contained in:
aj committed 2026-10-05 21:52:30 -04:00
1 parent faf3c9bcc4
commit 1b422ef99a
5 files changed
+127 -6

No files matched your search

@@ -43,7 +43,7 @@ internal sealed class OverlapSource
internal OverlapSource(Program program, List<Entity> entities, string error)
{
codeCount = program.Codes.Count;
codeCount = CodeCount(program);
rotation = BitConverter.DoubleToInt64Bits(program.Rotation);
Entities = entities;
Error = error;
@@ -54,7 +54,10 @@ internal sealed class OverlapSource
internal string Error { get; }
internal bool Matches(Program program) =>
program.Codes.Count == codeCount && BitConverter.DoubleToInt64Bits(program.Rotation) == rotation;
CodeCount(program) == codeCount && BitConverter.DoubleToInt64Bits(program.Rotation) == rotation;
// Program.Codes is a writable field; a missing list is a refused source, not a crash.
private static int CodeCount(Program program) => program.Codes?.Count ?? -1;
/// <summary>
/// Prepares once and shares the result. A geometry failure is cached like a success;