mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 18:31:08 -04:00
Desktop Auto Nest's "Best plan so far" strip now fills in for every built-in whole-job engine except FlatBar, not only Irregular. - Rectangles makes one sheet-by-sheet run, so it reports the finished job as its one plan, then replays its plate commits (token checked as before). - Circles reports when a stock-preference run or a tail re-plan beats its best result so far. - Default scores each candidate plan as it ranks results (valid, fewest unplaced, lowest cost, candidate order) and reports it only when it beats every plan already shown, so a later candidate never shows a worse plan. The chosen result is always the last plan reported. - Shared ReportPlan/SameLayout helpers on CandidateProgress; Irregular uses them too. Reporting never changes the search. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
2.2 KiB
C#
50 lines
2.2 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using OpenNest.Engine.Jobs;
|
|
|
|
namespace OpenNest.Engine.NestingEngines;
|
|
|
|
/// <summary>Forwards a candidate run's progress except plate commits, which belong to the result
|
|
/// finally chosen; <see cref="ReportCommits"/> reports those once it is.</summary>
|
|
internal sealed class CandidateProgress(IProgress<NestJobProgress> inner) : IProgress<NestJobProgress>
|
|
{
|
|
public void Report(NestJobProgress value)
|
|
{
|
|
if (value != null && value.Stage != NestJobStage.PlateCommitted)
|
|
inner.Report(value);
|
|
}
|
|
|
|
/// <summary>Reports the plate commits of <paramref name="result"/> in order. The token is
|
|
/// observed before each commit and after the last, as while building a result.</summary>
|
|
public static void ReportCommits(NestJobResult result, IProgress<NestJobProgress>? progress,
|
|
CancellationToken token = default)
|
|
{
|
|
if (progress == null)
|
|
return;
|
|
var parts = 0;
|
|
for (var i = 0; i < result.Plates.Count; i++)
|
|
{
|
|
token.ThrowIfCancellationRequested();
|
|
var plate = result.Plates[i];
|
|
parts += plate.Placements.Count;
|
|
progress.Report(new NestJobProgress(NestJobStage.PlateCommitted, plate.StockId, plate.PlateIndex, i + 1, parts));
|
|
}
|
|
token.ThrowIfCancellationRequested();
|
|
}
|
|
|
|
/// <summary>Reports a whole-job plan as <see cref="NestJobStage.PlanImproved"/>: a proposal
|
|
/// with no committed counts. Reporting never changes the search.</summary>
|
|
public static void ReportPlan(NestJobResult plan, IProgress<NestJobProgress>? progress) =>
|
|
progress?.Report(new NestJobProgress(NestJobStage.PlanImproved, string.Empty, -1, 0, 0, Plan: plan));
|
|
|
|
/// <summary>True when both results place the same parts at the same poses on the same stock,
|
|
/// sheet by sheet.</summary>
|
|
public static bool SameLayout(NestJobResult a, NestJobResult b) =>
|
|
ReferenceEquals(a, b)
|
|
|| (a.Plates.Count == b.Plates.Count
|
|
&& a.Plates.Zip(b.Plates).All(p => p.First.StockId == p.Second.StockId
|
|
&& p.First.Placements.SequenceEqual(p.Second.Placements)));
|
|
}
|