feat(desktop): show Auto Nest as a sheet strip with a Keep/Discard review

Auto Nest no longer draws parts on the plate view before they are kept:
its result is a set of sheets, possibly of several sizes, not parts on the
current plate. Ghost parts stay with interactive Fill and remnant tools.

- NestJobStage.PlanImproved carries an engine's best whole-job plan so far;
  Irregular reports one whenever a variant or the tail re-plan beats it.
- NestPipeline adds PlanSheets: the plan on detached drawings built from
  the job geometry (with the caller's names and colors), so previews never
  touch caller drawings or quantities.
- SheetStripControl draws every sheet side by side at one scale, repeats
  once with their count, captioned with size, parts and utilization.
- The progress window shows "Best plan so far"; a review window shows the
  final sheets, totals, cost summary and unplaced parts before commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ajandClaude Opus 5.5 committed 2026-10-18 23:56:38 -04:00
1 parent a2fb945669
commit cd2bea054b
13 files changed
+692 -47

No files matched your search

@@ -89,14 +89,29 @@ public sealed class IrregularNestingEngine : INestingEngine
break;
var plan = solver.Plan(demand, axis, beta);
if (best == null || plan.IsBetterThan(best))
{
best = plan;
ReportPlan(job, types, best, progress, token);
}
if (best.Unplaced == 0 && best.Sheets.Count == 0)
break;
}
// The last sheets hold the leftovers, which is where waste concentrates; re-plan them.
best = solver.ImproveTail(best!, WorkBudget * 2);
return BuildResult(job, types, best, progress, token);
var improved = solver.ImproveTail(best!, WorkBudget * 2);
if (!ReferenceEquals(improved, best))
ReportPlan(job, types, improved, progress, token);
return BuildResult(job, types, improved, progress, token);
}
/// <summary>Reports a new best whole-job plan; reporting never changes the search.</summary>
private static void ReportPlan(NestJob job, IReadOnlyList<PartType> types, Plan plan,
IProgress<NestJobProgress>? progress, CancellationToken token)
{
if (progress == null)
return;
var result = BuildResult(job, types, plan, null, token);
progress.Report(new NestJobProgress(NestJobStage.PlanImproved, string.Empty, -1, 0, 0, Plan: result));
}
/// <summary>Exercises the production physical-tail lifecycle from a test-owned incumbent.