From 5668748f371b9e6b0f23466eb2fc5ca3a054ea20 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Wed, 18 Mar 2026 13:02:10 -0400 Subject: [PATCH] feat(engine): add ExtentsFillStrategy adapter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wraps FillExtents in an IFillStrategy, trying both bestRotation and bestRotation+90° angles and picking the better result. Reads BestFits from SharedState (populated by PairsFillStrategy) to allow FillExtents to search the best-fit cache for improved pair geometry. Co-Authored-By: Claude Sonnet 4.6 --- .../Strategies/ExtentsFillStrategy.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 OpenNest.Engine/Strategies/ExtentsFillStrategy.cs diff --git a/OpenNest.Engine/Strategies/ExtentsFillStrategy.cs b/OpenNest.Engine/Strategies/ExtentsFillStrategy.cs new file mode 100644 index 0000000..67f762e --- /dev/null +++ b/OpenNest.Engine/Strategies/ExtentsFillStrategy.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using OpenNest.Engine.BestFit; +using OpenNest.Math; + +namespace OpenNest +{ + public class ExtentsFillStrategy : IFillStrategy + { + public string Name => "Extents"; + public NestPhase Phase => NestPhase.Extents; + public int Order => 300; + + public List Fill(FillContext context) + { + var filler = new FillExtents(context.WorkArea, context.Plate.PartSpacing); + + var bestRotation = context.SharedState.TryGetValue("BestRotation", out var rot) + ? (double)rot + : RotationAnalysis.FindBestRotation(context.Item); + + var angles = new[] { bestRotation, bestRotation + Angle.HalfPI }; + + var bestFits = context.SharedState.TryGetValue("BestFits", out var cached) + ? (List)cached + : null; + + List best = null; + var bestScore = default(FillScore); + + foreach (var angle in angles) + { + context.Token.ThrowIfCancellationRequested(); + var result = filler.Fill(context.Item.Drawing, angle, + context.PlateNumber, context.Token, context.Progress, bestFits); + if (result != null && result.Count > 0) + { + var score = FillScore.Compute(result, context.WorkArea); + if (best == null || score > bestScore) + { + best = result; + bestScore = score; + } + } + } + + return best ?? new List(); + } + } +}