diff --git a/OpenNest.Engine/DefaultNestEngine.cs b/OpenNest.Engine/DefaultNestEngine.cs index 0ee2ab0..1183b41 100644 --- a/OpenNest.Engine/DefaultNestEngine.cs +++ b/OpenNest.Engine/DefaultNestEngine.cs @@ -295,6 +295,7 @@ namespace OpenNest foreach (var strategy in FillStrategyRegistry.Strategies) { context.Token.ThrowIfCancellationRequested(); + context.ActivePhase = strategy.Phase; var sw = Stopwatch.StartNew(); var result = strategy.Fill(context); diff --git a/OpenNest.Engine/Fill/FillExtents.cs b/OpenNest.Engine/Fill/FillExtents.cs index a058e24..579944f 100644 --- a/OpenNest.Engine/Fill/FillExtents.cs +++ b/OpenNest.Engine/Fill/FillExtents.cs @@ -24,10 +24,8 @@ namespace OpenNest.Engine.Fill } public List Fill(Drawing drawing, double rotationAngle = 0, - int plateNumber = 0, CancellationToken token = default, - IProgress progress = null, - List bestFits = null) + Action, string> reportProgress = null) { var pair = BuildPair(drawing, rotationAngle); if (pair == null) @@ -37,14 +35,7 @@ namespace OpenNest.Engine.Fill if (column.Count == 0) return new List(); - NestEngineBase.ReportProgress(progress, new ProgressReport - { - Phase = NestPhase.Extents, - PlateNumber = plateNumber, - Parts = column, - WorkArea = workArea, - Description = $"Extents: initial column {column.Count} parts", - }); + reportProgress?.Invoke(column, $"Extents: initial column {column.Count} parts"); var adjusted = AdjustColumn(pair.Value, column, token); @@ -56,25 +47,11 @@ namespace OpenNest.Engine.Fill adjusted = column; } - NestEngineBase.ReportProgress(progress, new ProgressReport - { - Phase = NestPhase.Extents, - PlateNumber = plateNumber, - Parts = adjusted, - WorkArea = workArea, - Description = $"Extents: column {adjusted.Count} parts", - }); + reportProgress?.Invoke(adjusted, $"Extents: column {adjusted.Count} parts"); var result = RepeatColumns(adjusted, token); - NestEngineBase.ReportProgress(progress, new ProgressReport - { - Phase = NestPhase.Extents, - PlateNumber = plateNumber, - Parts = result, - WorkArea = workArea, - Description = $"Extents: {result.Count} parts total", - }); + reportProgress?.Invoke(result, $"Extents: {result.Count} parts total"); return result; } diff --git a/OpenNest.Engine/Fill/PairFiller.cs b/OpenNest.Engine/Fill/PairFiller.cs index 52a4f33..11f7f2a 100644 --- a/OpenNest.Engine/Fill/PairFiller.cs +++ b/OpenNest.Engine/Fill/PairFiller.cs @@ -45,9 +45,8 @@ namespace OpenNest.Engine.Fill } public PairFillResult Fill(NestItem item, Box workArea, - int plateNumber = 0, CancellationToken token = default, - IProgress progress = null) + Action, string> reportProgress = null) { var bestFits = BestFitCache.GetOrCompute( item.Drawing, plateSize.Length, plateSize.Width, partSpacing); @@ -58,7 +57,7 @@ namespace OpenNest.Engine.Fill var targetCount = item.Quantity > 0 ? item.Quantity : 0; var parts = EvaluateCandidates(candidates, item.Drawing, workArea, targetCount, - plateNumber, token, progress); + token, reportProgress); return new PairFillResult { Parts = parts, BestFits = bestFits }; } @@ -66,7 +65,7 @@ namespace OpenNest.Engine.Fill private List EvaluateCandidates( List candidates, Drawing drawing, Box workArea, int targetCount, - int plateNumber, CancellationToken token, IProgress progress) + CancellationToken token, Action, string> reportProgress) { List best = null; var sinceImproved = 0; @@ -112,14 +111,8 @@ namespace OpenNest.Engine.Fill sinceImproved++; } - NestEngineBase.ReportProgress(progress, new ProgressReport - { - Phase = NestPhase.Pairs, - PlateNumber = plateNumber, - Parts = best, - WorkArea = workArea, - Description = $"Pairs: {batchStart + j + 1}/{candidates.Count} candidates, best = {best?.Count ?? 0} parts", - }); + reportProgress?.Invoke(best, + $"Pairs: {batchStart + j + 1}/{candidates.Count} candidates, best = {best?.Count ?? 0} parts"); } if (batchEnd >= EarlyExitMinTried && sinceImproved >= EarlyExitStaleLimit) diff --git a/OpenNest.Engine/Fill/StripeFiller.cs b/OpenNest.Engine/Fill/StripeFiller.cs index 4150f4f..1e1fdc6 100644 --- a/OpenNest.Engine/Fill/StripeFiller.cs +++ b/OpenNest.Engine/Fill/StripeFiller.cs @@ -95,14 +95,8 @@ public class StripeFiller } } - NestEngineBase.ReportProgress(_context.Progress, new ProgressReport - { - Phase = NestPhase.Custom, - PlateNumber = _context.PlateNumber, - Parts = bestParts, - WorkArea = workArea, - Description = $"{strategyName}: {i + 1}/{bestFits.Count} pairs, best = {bestParts?.Count ?? 0} parts", - }); + _context.ReportProgress(bestParts, + $"{strategyName}: {i + 1}/{bestFits.Count} pairs, best = {bestParts?.Count ?? 0} parts"); } return bestParts ?? new List(); diff --git a/OpenNest.Engine/Strategies/ExtentsFillStrategy.cs b/OpenNest.Engine/Strategies/ExtentsFillStrategy.cs index 4530df3..e47f4b9 100644 --- a/OpenNest.Engine/Strategies/ExtentsFillStrategy.cs +++ b/OpenNest.Engine/Strategies/ExtentsFillStrategy.cs @@ -24,8 +24,8 @@ namespace OpenNest.Engine.Strategies return FillHelpers.BestOverAngles(context, angles, angle => filler.Fill(context.Item.Drawing, angle, - context.PlateNumber, context.Token, context.Progress), - NestPhase.Extents, "Extents"); + context.Token, context.ReportProgress), + "Extents"); } } } diff --git a/OpenNest.Engine/Strategies/FillContext.cs b/OpenNest.Engine/Strategies/FillContext.cs index 733b39a..d03495e 100644 --- a/OpenNest.Engine/Strategies/FillContext.cs +++ b/OpenNest.Engine/Strategies/FillContext.cs @@ -23,9 +23,26 @@ namespace OpenNest.Engine.Strategies /// For progress reporting only; comparisons use Policy.Comparer. public FillScore CurrentBestScore { get; set; } public NestPhase WinnerPhase { get; set; } + public NestPhase ActivePhase { get; set; } public List PhaseResults { get; } = new(); public List AngleResults { get; } = new(); public Dictionary SharedState { get; } = new(); + + /// + /// Standard progress reporting for strategies and fillers. Reports intermediate + /// results using the current ActivePhase, PlateNumber, and WorkArea. + /// + public void ReportProgress(List parts, string description) + { + NestEngineBase.ReportProgress(Progress, new ProgressReport + { + Phase = ActivePhase, + PlateNumber = PlateNumber, + Parts = parts, + WorkArea = WorkArea, + Description = description, + }); + } } } diff --git a/OpenNest.Engine/Strategies/FillHelpers.cs b/OpenNest.Engine/Strategies/FillHelpers.cs index a951aa1..024122e 100644 --- a/OpenNest.Engine/Strategies/FillHelpers.cs +++ b/OpenNest.Engine/Strategies/FillHelpers.cs @@ -113,13 +113,12 @@ namespace OpenNest.Engine.Strategies /// /// Sweeps a list of angles, calling fillAtAngle for each, and returns /// the best result according to the context's comparer. Handles - /// cancellation and progress reporting. + /// cancellation and progress reporting via context.ReportProgress. /// public static List BestOverAngles( FillContext context, IReadOnlyList angles, Func> fillAtAngle, - NestPhase phase, string phaseLabel) { var workArea = context.WorkArea; @@ -140,14 +139,8 @@ namespace OpenNest.Engine.Strategies best = result; } - NestEngineBase.ReportProgress(context.Progress, new ProgressReport - { - Phase = phase, - PlateNumber = context.PlateNumber, - Parts = best, - WorkArea = workArea, - Description = $"{phaseLabel}: {i + 1}/{angles.Count} angles, {angleDeg:F0}° best = {best?.Count ?? 0} parts", - }); + context.ReportProgress(best, + $"{phaseLabel}: {i + 1}/{angles.Count} angles, {angleDeg:F0}° best = {best?.Count ?? 0} parts"); } return best ?? new List(); diff --git a/OpenNest.Engine/Strategies/LinearFillStrategy.cs b/OpenNest.Engine/Strategies/LinearFillStrategy.cs index a9a7265..8c1c278 100644 --- a/OpenNest.Engine/Strategies/LinearFillStrategy.cs +++ b/OpenNest.Engine/Strategies/LinearFillStrategy.cs @@ -40,7 +40,7 @@ namespace OpenNest.Engine.Strategies return result; }, - NestPhase.Linear, "Linear"); + "Linear"); } } } diff --git a/OpenNest.Engine/Strategies/PairsFillStrategy.cs b/OpenNest.Engine/Strategies/PairsFillStrategy.cs index e9b7f0a..76a9d44 100644 --- a/OpenNest.Engine/Strategies/PairsFillStrategy.cs +++ b/OpenNest.Engine/Strategies/PairsFillStrategy.cs @@ -30,7 +30,7 @@ namespace OpenNest.Engine.Strategies var dedup = GridDedup.GetOrCreate(context.SharedState); var filler = new PairFiller(context.Plate, comparer, dedup); var result = filler.Fill(context.Item, context.WorkArea, - context.PlateNumber, context.Token, context.Progress); + context.Token, context.ReportProgress); context.SharedState["BestFits"] = result.BestFits;