From 5761eefd376b219ce0dc990985e87ce85bc8f879 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Sun, 25 Oct 2026 23:06:18 -0400 Subject: [PATCH] refactor(engine): merge the plate fillers into one PlateFiller DefaultPlateFiller becomes PlateFiller(plate, policy, layout); PlateFillerBase and StripPlateFiller are gone. PlateLayout.FillThenPack is the old orchestrator path (Fill and both Remnants); PlateLayout.Strips is the old StripPlateFiller.Nest, and Strip is Fill policy plus Strips layout. Lifetimes are unchanged: a strip-layout filler runs every Fill, group Fill and PackArea on a fresh inner filler and gives each strip fresh remnant fillers, so learned angles and PlateNumber never leak into them. The comparer, preferred direction, trim axis and angle recording now read the policy directly. The base class's unsorted two-angle BuildAngles is dropped: only DefaultPlateFiller's pipeline called BuildAngles, and Strip never ran it. Layout-neutral: all 29 FillStackCharacterizationTests pins pass unchanged. Co-Authored-By: Claude Opus 5.5 --- .../Jobs/FillStackCharacterizationTests.cs | 2 +- .../Jobs/NestJobCancellationTests.cs | 4 +- .../Jobs/NestJobIdentityTests.cs | 21 +- .../Jobs/PlateFillerContractTests.cs | 38 ++-- .../Jobs/Placement/DefaultPlateNester.cs | 10 +- .../{DefaultPlateFiller.cs => PlateFiller.cs} | 195 ++++++++++++++++-- .../Jobs/Placement/Fillers/PlateFillerBase.cs | 121 ----------- .../Placement/Fillers/StripPlateFiller.cs | 128 ------------ .../Jobs/Placement/PlateFillService.cs | 16 +- .../Jobs/Placement/PrivatePlateFill.cs | 2 +- .../Jobs/Placement/RemnantPlateNester.cs | 8 +- .../Jobs/Placement/StripPlateNester.cs | 13 +- OpenNest.Engine/ML/BruteForceRunner.cs | 2 +- OpenNest.Engine/Strategies/FillContext.cs | 2 +- .../Engine/EngineRefactorSmokeTests.cs | 30 +-- OpenNest.Tests/Engine/NestInvarianceTests.cs | 4 +- OpenNest.Tests/Engine/RemnantEngineTests.cs | 12 +- .../Fill/IterativeShrinkFillerTests.cs | 10 +- OpenNest.Tests/Fill/RemnantFillerTests2.cs | 6 +- OpenNest.Tests/Fill/ShrinkFillerTests.cs | 8 +- .../Strategies/FillPipelineTests.cs | 14 +- 21 files changed, 286 insertions(+), 360 deletions(-) rename OpenNest.Engine/Jobs/Placement/Fillers/{DefaultPlateFiller.cs => PlateFiller.cs} (73%) delete mode 100644 OpenNest.Engine/Jobs/Placement/Fillers/PlateFillerBase.cs delete mode 100644 OpenNest.Engine/Jobs/Placement/Fillers/StripPlateFiller.cs diff --git a/OpenNest.Engine.Tests/Jobs/FillStackCharacterizationTests.cs b/OpenNest.Engine.Tests/Jobs/FillStackCharacterizationTests.cs index e2a61bde..dac42564 100644 --- a/OpenNest.Engine.Tests/Jobs/FillStackCharacterizationTests.cs +++ b/OpenNest.Engine.Tests/Jobs/FillStackCharacterizationTests.cs @@ -328,7 +328,7 @@ public class FillStackCharacterizationTests { string Solve(bool fullSweep) { - var filler = new DefaultPlateFiller(MakePlate()) { ForceFullAngleSweep = fullSweep }; + var filler = new PlateFiller(MakePlate()) { ForceFullAngleSweep = fullSweep }; return Layout(filler.Nest(LearnedAngleItems(), null, CancellationToken.None)); } diff --git a/OpenNest.Engine.Tests/Jobs/NestJobCancellationTests.cs b/OpenNest.Engine.Tests/Jobs/NestJobCancellationTests.cs index c8580a5c..5ee7f2a1 100644 --- a/OpenNest.Engine.Tests/Jobs/NestJobCancellationTests.cs +++ b/OpenNest.Engine.Tests/Jobs/NestJobCancellationTests.cs @@ -1,8 +1,8 @@ using OpenNest.CNC; -using OpenNest.Geometry; using OpenNest.Engine.Jobs; using OpenNest.Engine.Jobs.Placement; using OpenNest.Engine.Jobs.Placement.Fillers; +using OpenNest.Geometry; namespace OpenNest.Engine.Tests.Jobs; @@ -135,7 +135,7 @@ public class NestJobCancellationTests } } - private sealed class ReportingFiller(Plate plate) : DefaultPlateFiller(plate) + private sealed class ReportingFiller(Plate plate) : PlateFiller(plate) { public override List Nest( List items, diff --git a/OpenNest.Engine.Tests/Jobs/NestJobIdentityTests.cs b/OpenNest.Engine.Tests/Jobs/NestJobIdentityTests.cs index a551f4e7..68572c4c 100644 --- a/OpenNest.Engine.Tests/Jobs/NestJobIdentityTests.cs +++ b/OpenNest.Engine.Tests/Jobs/NestJobIdentityTests.cs @@ -1,9 +1,9 @@ using OpenNest.CNC; -using OpenNest.Geometry; using OpenNest.Engine.Jobs; using OpenNest.Engine.Jobs.Adapters; using OpenNest.Engine.Jobs.Placement; using OpenNest.Engine.Jobs.Placement.Fillers; +using OpenNest.Geometry; namespace OpenNest.Engine.Tests.Jobs; @@ -119,34 +119,34 @@ public class NestJobIdentityTests Assert.Equal(new[] { 0, 0 }, new[] { items[0].Quantity, items[1].Quantity }); } - /// Orchestrator probe whose fill/pack delegates run the Default filler. - private sealed class DefaultFillerProbe(Plate plate) : PlateFillerBase(plate) + /// Orchestrator probe whose fill/pack delegates each run a fresh Fill filler. + private sealed class DefaultFillerProbe(Plate plate) : PlateFiller(plate) { public override List Fill( NestItem item, Box workArea, IProgress progress, CancellationToken token - ) => new DefaultPlateFiller(Plate).Fill(item, workArea, progress, token); + ) => new PlateFiller(Plate).Fill(item, workArea, progress, token); public override List Fill( List groupParts, Box workArea, IProgress progress, CancellationToken token - ) => new DefaultPlateFiller(Plate).Fill(groupParts, workArea, progress, token); + ) => new PlateFiller(Plate).Fill(groupParts, workArea, progress, token); public override List PackArea( Box box, List items, IProgress progress, CancellationToken token - ) => new DefaultPlateFiller(Plate).PackArea(box, items, progress, token); + ) => new PlateFiller(Plate).PackArea(box, items, progress, token); } /// Places exactly 2 parts from the first multi-quantity item and none from the /// rest, forcing the orchestrator's deduction to run on an asymmetric placement result. - private sealed class StarvingProbe(Plate plate) : PlateFillerBase(plate) + private sealed class StarvingProbe(Plate plate) : PlateFiller(plate) { private int _first = -1; @@ -172,5 +172,12 @@ public class NestJobIdentityTests } return parts; } + + public override List PackArea( + Box box, + List items, + IProgress progress, + CancellationToken token + ) => new List(); } } diff --git a/OpenNest.Engine.Tests/Jobs/PlateFillerContractTests.cs b/OpenNest.Engine.Tests/Jobs/PlateFillerContractTests.cs index d83196e8..a75c2b59 100644 --- a/OpenNest.Engine.Tests/Jobs/PlateFillerContractTests.cs +++ b/OpenNest.Engine.Tests/Jobs/PlateFillerContractTests.cs @@ -30,10 +30,10 @@ public class PlateFillerContractTests } [Fact] - public void DefaultPlateFiller_UsesOverriddenAngleSelection() + public void PlateFiller_UsesOverriddenAngleSelection() { var plate = new Plate(new Size(30, 50)); - var filler = new AngleProbeDefaultPlateFiller(plate); + var filler = new AngleProbePlateFiller(plate); var parts = filler.Fill( new NestItem @@ -51,12 +51,12 @@ public class PlateFillerContractTests } [Fact] - public void DefaultPlateFiller_Nest_UsesOverriddenFillAndPackArea() + public void PlateFiller_Nest_UsesOverriddenFillAndPackArea() { var plate = new Plate(new Size(100, 100)); var fillDrawing = new Drawing("fill", TestDrawingFactory.Rectangle(10, 10)); var packDrawing = new Drawing("pack", TestDrawingFactory.Rectangle(10, 10)); - var filler = new FillAndPackProbeDefaultPlateFiller(plate, fillDrawing, packDrawing); + var filler = new FillAndPackProbePlateFiller(plate, fillDrawing, packDrawing); var parts = filler.Nest( new List @@ -74,7 +74,7 @@ public class PlateFillerContractTests } [Fact] - public void StripPlateFiller_Nest_ReturnsPlacedPartsAndDeductsInput() + public void StripLayout_Nest_ReturnsPlacedPartsAndDeductsInput() { var plate = new Plate(new Size(30, 50)); var items = new List @@ -95,7 +95,7 @@ public class PlateFillerContractTests Quantity = 3, }, }; - var filler = new StripPlateFiller(plate) { PlateNumber = 7 }; + var filler = new PlateFiller(plate, PlateFillPolicy.Fill, PlateLayout.Strips) { PlateNumber = 7 }; var parts = filler.Nest(items, null, CancellationToken.None); @@ -105,11 +105,11 @@ public class PlateFillerContractTests } [Fact] - public void StripPlateFiller_Nest_UsesOverriddenPackArea() + public void StripLayout_Nest_UsesOverriddenPackArea() { var plate = new Plate(new Size(100, 100)); var drawing = new Drawing("pack", TestDrawingFactory.Rectangle(10, 10)); - var filler = new PackProbeStripPlateFiller(plate, drawing); + var filler = new PackProbeStripFiller(plate, drawing); var parts = filler.Nest( new List { new() { Drawing = drawing, Quantity = 1 } }, @@ -260,12 +260,12 @@ public class PlateFillerContractTests Assert.Equal(10, item.Quantity); } - private sealed class FillAndPackProbeDefaultPlateFiller : DefaultPlateFiller + private sealed class FillAndPackProbePlateFiller : PlateFiller { private readonly Drawing fillDrawing; private readonly Drawing packDrawing; - internal FillAndPackProbeDefaultPlateFiller( + internal FillAndPackProbePlateFiller( Plate plate, Drawing fillDrawing, Drawing packDrawing @@ -308,9 +308,9 @@ public class PlateFillerContractTests } } - private sealed class AngleProbeDefaultPlateFiller : DefaultPlateFiller + private sealed class AngleProbePlateFiller : PlateFiller { - internal AngleProbeDefaultPlateFiller(Plate plate) + internal AngleProbePlateFiller(Plate plate) : base(plate) { } internal bool BuildAnglesCalled { get; private set; } @@ -326,12 +326,12 @@ public class PlateFillerContractTests } } - private sealed class PackProbeStripPlateFiller : StripPlateFiller + private sealed class PackProbeStripFiller : PlateFiller { private readonly Drawing drawing; - internal PackProbeStripPlateFiller(Plate plate, Drawing drawing) - : base(plate) + internal PackProbeStripFiller(Plate plate, Drawing drawing) + : base(plate, PlateFillPolicy.Fill, PlateLayout.Strips) { this.drawing = drawing; } @@ -351,11 +351,11 @@ public class PlateFillerContractTests } } - private static PlateFillerBase CreateFiller(string strategy, Plate plate) => strategy switch + private static PlateFiller CreateFiller(string strategy, Plate plate) => strategy switch { - "Fill" => new DefaultPlateFiller(plate), - "Vertical Remnant" => new DefaultPlateFiller(plate, PlateFillPolicy.VerticalRemnant), - "Horizontal Remnant" => new DefaultPlateFiller(plate, PlateFillPolicy.HorizontalRemnant), + "Fill" => new PlateFiller(plate), + "Vertical Remnant" => new PlateFiller(plate, PlateFillPolicy.VerticalRemnant), + "Horizontal Remnant" => new PlateFiller(plate, PlateFillPolicy.HorizontalRemnant), _ => throw new ArgumentOutOfRangeException(nameof(strategy)), }; diff --git a/OpenNest.Engine/Jobs/Placement/DefaultPlateNester.cs b/OpenNest.Engine/Jobs/Placement/DefaultPlateNester.cs index 9b855828..da56c09d 100644 --- a/OpenNest.Engine/Jobs/Placement/DefaultPlateNester.cs +++ b/OpenNest.Engine/Jobs/Placement/DefaultPlateNester.cs @@ -8,7 +8,7 @@ namespace OpenNest.Engine.Jobs.Placement; /// /// Built-in placement strategy for the whole-job runner. Fills each candidate trial with a -/// on a fresh private plate and owns its own run-scoped +/// on a fresh private plate and owns its own run-scoped /// bookkeeping: remaining demand is read from the request and placement counts are derived from /// returned placements, so the filler's private mutations never /// feed back into job accounting. @@ -23,15 +23,15 @@ namespace OpenNest.Engine.Jobs.Placement; /// public sealed class DefaultPlateNester : IPlateNester { - private readonly Func fillerFactory; + private readonly Func fillerFactory; private readonly OrderedPlateNester restrictedRotationNester = new(); private readonly CandidatePlacementContext context = new(); public DefaultPlateNester() - : this(static plate => new DefaultPlateFiller(plate)) { } + : this(static plate => new PlateFiller(plate)) { } - /// Injectable for tests; defaults to . - internal DefaultPlateNester(Func fillerFactory) + /// Injectable for tests; defaults to . + internal DefaultPlateNester(Func fillerFactory) { this.fillerFactory = fillerFactory ?? throw new ArgumentNullException(nameof(fillerFactory)); diff --git a/OpenNest.Engine/Jobs/Placement/Fillers/DefaultPlateFiller.cs b/OpenNest.Engine/Jobs/Placement/Fillers/PlateFiller.cs similarity index 73% rename from OpenNest.Engine/Jobs/Placement/Fillers/DefaultPlateFiller.cs rename to OpenNest.Engine/Jobs/Placement/Fillers/PlateFiller.cs index d1db0a5f..a5dc50a2 100644 --- a/OpenNest.Engine/Jobs/Placement/Fillers/DefaultPlateFiller.cs +++ b/OpenNest.Engine/Jobs/Placement/Fillers/PlateFiller.cs @@ -13,22 +13,64 @@ using OpenNest.Math; namespace OpenNest.Engine.Jobs.Placement.Fillers; -internal class DefaultPlateFiller : PlateFillerBase +/// How lays out a whole plate. +internal enum PlateLayout +{ + /// Fill each multi-quantity item, pack the leftovers, then best-fit pairs. + FillThenPack, + + /// + /// Iterative shrink-fill strips (each strip ranked by a fresh remnant filler), then pack the + /// leftovers into the first remnant. + /// + Strips, +} + +/// +/// The interactive and whole-job filler behind Fill, Strip and both Remnants. A +/// filler is reused for a whole (and +/// across clamp refills), so its learned angles carry over between items. A +/// filler runs every single-area fill and pack on a fresh +/// filler, so nothing it learns or its +/// reaches them. +/// +internal class PlateFiller { private readonly AngleCandidateBuilder angleBuilder = new(); private readonly PlateFillPolicy policy; + private readonly PlateLayout layout; + private IFillComparer comparer; - internal DefaultPlateFiller(Plate plate, PlateFillPolicy policy = null) - : base(plate) + internal PlateFiller( + Plate plate, + PlateFillPolicy policy = null, + PlateLayout layout = PlateLayout.FillThenPack + ) { + Plate = plate; this.policy = policy ?? PlateFillPolicy.Fill; + this.layout = layout; } - protected override IFillComparer CreateComparer() => policy.CreateComparer(); + public Plate Plate { get; } - public override NestDirection? PreferredDirection => policy.PreferredDirection; + public int PlateNumber { get; set; } - public override ShrinkAxis TrimAxis => policy.TrimAxis; + public NestDirection NestDirection { get; set; } + + public NestPhase WinnerPhase { get; private set; } + + public List PhaseResults { get; } = new(); + + public List AngleResults { get; } = new(); + + public NestDirection? PreferredDirection => policy.PreferredDirection; + + public ShrinkAxis TrimAxis => policy.TrimAxis; + + private IFillComparer Comparer => comparer ??= policy.CreateComparer(); + + private FillPolicy BuildPolicy() => new(Comparer, PreferredDirection); internal bool ForceFullAngleSweep { @@ -43,7 +85,7 @@ internal class DefaultPlateFiller : PlateFillerBase /// internal bool StopAtQuantity { get; init; } - public override List BuildAngles( + public virtual List BuildAngles( NestItem item, ClassificationResult classification, Box workArea @@ -52,18 +94,34 @@ internal class DefaultPlateFiller : PlateFillerBase ? angleBuilder.Build(item, classification, workArea) : policy.BuildFixedAngles(item, classification); - protected override void RecordProductiveAngles(List angleResults) + internal bool IsBetterFill(List candidate, List current, Box workArea) => + Comparer.IsBetter(candidate, current, workArea); + + /// A strip layout's single-area work runs here, never on the strip filler itself. + private PlateFiller CreateInnerFiller() => new(Plate, policy); + + private string BuildProgressSummary() { - angleBuilder.RecordProductive(angleResults); + if (PhaseResults.Count == 0) + return null; + + var parts = new List(PhaseResults.Count); + foreach (var result in PhaseResults) + parts.Add($"{result.Phase.ShortName()}: {result.PartCount}"); + + return string.Join(" | ", parts); } - public override List Fill( + public virtual List Fill( NestItem item, Box workArea, IProgress progress, CancellationToken token ) { + if (layout == PlateLayout.Strips) + return CreateInnerFiller().Fill(item, workArea, progress, token); + PhaseResults.Clear(); AngleResults.Clear(); @@ -366,13 +424,16 @@ internal class DefaultPlateFiller : PlateFillerBase return context.CurrentBest ?? new List(); } - public override List Fill( + public virtual List Fill( List groupParts, Box workArea, IProgress progress, CancellationToken token ) { + if (layout == PlateLayout.Strips) + return CreateInnerFiller().Fill(groupParts, workArea, progress, token); + if (groupParts == null || groupParts.Count == 0) return new List(); @@ -410,17 +471,123 @@ internal class DefaultPlateFiller : PlateFillerBase return best ?? new List(); } - public override List PackArea( + public virtual List PackArea( Box box, List items, IProgress progress, CancellationToken token ) { + if (layout == PlateLayout.Strips) + return CreateInnerFiller().PackArea(box, items, progress, token); + return AreaPacker.Pack(box, items, Plate.PartSpacing, Comparer, token, Plate.WorkArea()); } - protected virtual void RunPipeline(FillContext context) + public virtual List Nest( + List items, + IProgress progress, + CancellationToken token + ) + { + if (layout == PlateLayout.Strips) + return NestStrips(items, progress, token); + + return PlateFillOrchestrator.Nest( + Plate, + items, + Comparer, + (item, workArea, sink, cancellation) => Fill(item, workArea, sink, cancellation), + (workArea, packItems, sink, cancellation) => + PackArea(workArea, packItems, sink, cancellation), + progress, + token + ); + } + + private List NestStrips( + List items, + IProgress progress, + CancellationToken token + ) + { + if (items == null || items.Count == 0) + return new List(); + + var workArea = Plate.WorkArea(); + var fillItems = items + .Where(item => item.Quantity != 1) + .OrderBy(item => item.Priority) + .ThenByDescending(item => item.Drawing.Area) + .ToList(); + var packItems = items.Where(item => item.Quantity == 1).ToList(); + var allParts = new List(); + + if (fillItems.Count > 0) + { + // Each strip gets fresh remnant fillers: they run in parallel and carry no + // PlateNumber or learned angles. + Func> heightFillFunc = (item, box) => + { + var inner = new PlateFiller(Plate, PlateFillPolicy.HorizontalRemnant); + return inner.Fill(item, box, progress, token); + }; + Func> widthFillFunc = (item, box) => + { + var inner = new PlateFiller(Plate, PlateFillPolicy.VerticalRemnant); + return inner.Fill(item, box, progress, token); + }; + + var shrinkResult = IterativeShrinkFiller.Fill( + fillItems, + workArea, + heightFillFunc, + Plate.PartSpacing, + token, + progress, + PlateNumber, + widthFillFunc + ); + + allParts.AddRange(shrinkResult.Parts); + Compactor.Settle(allParts, workArea, Plate.PartSpacing); + packItems.AddRange(shrinkResult.Leftovers); + } + + packItems = packItems.Where(item => item.Quantity > 0).ToList(); + if (packItems.Count > 0 && !token.IsCancellationRequested) + { + var packArea = workArea; + if (allParts.Count > 0) + { + var obstacles = allParts + .Select(part => part.BoundingBox.Offset(Plate.PartSpacing)) + .ToList(); + var finder = new RemnantFinder(workArea, obstacles); + var remnants = finder.FindRemnants(); + packArea = remnants.Count > 0 ? remnants[0] : new Box(0, 0, 0, 0); + } + + if (packArea.Width > 0 && packArea.Length > 0) + { + var packParts = PackArea(packArea, packItems, progress, token); + allParts.AddRange(packParts); + } + } + + foreach (var item in items) + { + if (item.Quantity <= 0) + continue; + + var placed = allParts.Count(part => ReferenceEquals(part.BaseDrawing, item.Drawing)); + item.Quantity = System.Math.Max(0, item.Quantity - placed); + } + + return allParts; + } + + private void RunPipeline(FillContext context) { var classification = PartClassifier.Classify(context.Item.Drawing); context.PartType = classification.Type; @@ -502,7 +669,7 @@ internal class DefaultPlateFiller : PlateFillerBase } } - RecordProductiveAngles(context.AngleResults); + angleBuilder.RecordProductive(context.AngleResults); } /// diff --git a/OpenNest.Engine/Jobs/Placement/Fillers/PlateFillerBase.cs b/OpenNest.Engine/Jobs/Placement/Fillers/PlateFillerBase.cs deleted file mode 100644 index 8de79730..00000000 --- a/OpenNest.Engine/Jobs/Placement/Fillers/PlateFillerBase.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using OpenNest.Engine; -using OpenNest.Engine.Fill; -using OpenNest.Engine.Strategies; -using OpenNest.Geometry; - -namespace OpenNest.Engine.Jobs.Placement.Fillers; - -internal abstract class PlateFillerBase -{ - private IFillComparer comparer; - - protected PlateFillerBase(Plate plate) - { - Plate = plate; - } - - public Plate Plate { get; } - - public int PlateNumber { get; set; } - - public NestDirection NestDirection { get; set; } - - public NestPhase WinnerPhase { get; protected set; } - - public List PhaseResults { get; } = new(); - - public List AngleResults { get; } = new(); - - protected IFillComparer Comparer => comparer ??= CreateComparer(); - - protected virtual IFillComparer CreateComparer() => new DefaultFillComparer(); - - public virtual NestDirection? PreferredDirection => null; - - public virtual ShrinkAxis TrimAxis => ShrinkAxis.Width; - - public virtual List BuildAngles( - NestItem item, - ClassificationResult classification, - Box workArea - ) - { - return new List - { - classification.PrimaryAngle, - classification.PrimaryAngle + OpenNest.Math.Angle.HalfPI, - }; - } - - protected virtual void RecordProductiveAngles(List angleResults) { } - - protected FillPolicy BuildPolicy() => new(Comparer, PreferredDirection); - - protected string BuildProgressSummary() => BuildProgressSummary(PhaseResults); - - private static string BuildProgressSummary(IReadOnlyList phaseResults) - { - if (phaseResults.Count == 0) - return null; - - var parts = new List(phaseResults.Count); - foreach (var result in phaseResults) - parts.Add($"{result.Phase.ShortName()}: {result.PartCount}"); - - return string.Join(" | ", parts); - } - - internal bool IsBetterFill(List candidate, List current, Box workArea) => - Comparer.IsBetter(candidate, current, workArea); - - public virtual List Fill( - NestItem item, - Box workArea, - IProgress progress, - CancellationToken token - ) - { - return new List(); - } - - public virtual List Fill( - List groupParts, - Box workArea, - IProgress progress, - CancellationToken token - ) - { - return new List(); - } - - public virtual List PackArea( - Box box, - List items, - IProgress progress, - CancellationToken token - ) - { - return new List(); - } - - public virtual List Nest( - List items, - IProgress progress, - CancellationToken token - ) - { - return PlateFillOrchestrator.Nest( - Plate, - items, - Comparer, - (item, workArea, sink, cancellation) => Fill(item, workArea, sink, cancellation), - (workArea, packItems, sink, cancellation) => - PackArea(workArea, packItems, sink, cancellation), - progress, - token - ); - } -} diff --git a/OpenNest.Engine/Jobs/Placement/Fillers/StripPlateFiller.cs b/OpenNest.Engine/Jobs/Placement/Fillers/StripPlateFiller.cs deleted file mode 100644 index d031b6d0..00000000 --- a/OpenNest.Engine/Jobs/Placement/Fillers/StripPlateFiller.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using OpenNest.Engine; -using OpenNest.Engine.Fill; -using OpenNest.Geometry; - -namespace OpenNest.Engine.Jobs.Placement.Fillers; - -internal class StripPlateFiller : PlateFillerBase -{ - internal StripPlateFiller(Plate plate) - : base(plate) { } - - public override List Fill( - NestItem item, - Box workArea, - IProgress progress, - CancellationToken token - ) - { - var inner = new DefaultPlateFiller(Plate); - return inner.Fill(item, workArea, progress, token); - } - - public override List Fill( - List groupParts, - Box workArea, - IProgress progress, - CancellationToken token - ) - { - var inner = new DefaultPlateFiller(Plate); - return inner.Fill(groupParts, workArea, progress, token); - } - - public override List PackArea( - Box box, - List items, - IProgress progress, - CancellationToken token - ) - { - var inner = new DefaultPlateFiller(Plate); - return inner.PackArea(box, items, progress, token); - } - - public override List Nest( - List items, - IProgress progress, - CancellationToken token - ) - { - if (items == null || items.Count == 0) - return new List(); - - var workArea = Plate.WorkArea(); - var fillItems = items - .Where(item => item.Quantity != 1) - .OrderBy(item => item.Priority) - .ThenByDescending(item => item.Drawing.Area) - .ToList(); - var packItems = items.Where(item => item.Quantity == 1).ToList(); - var allParts = new List(); - - if (fillItems.Count > 0) - { - Func> heightFillFunc = (item, box) => - { - var inner = new DefaultPlateFiller(Plate, PlateFillPolicy.HorizontalRemnant); - return inner.Fill(item, box, progress, token); - }; - Func> widthFillFunc = (item, box) => - { - var inner = new DefaultPlateFiller(Plate, PlateFillPolicy.VerticalRemnant); - return inner.Fill(item, box, progress, token); - }; - - var shrinkResult = IterativeShrinkFiller.Fill( - fillItems, - workArea, - heightFillFunc, - Plate.PartSpacing, - token, - progress, - PlateNumber, - widthFillFunc - ); - - allParts.AddRange(shrinkResult.Parts); - Compactor.Settle(allParts, workArea, Plate.PartSpacing); - packItems.AddRange(shrinkResult.Leftovers); - } - - packItems = packItems.Where(item => item.Quantity > 0).ToList(); - if (packItems.Count > 0 && !token.IsCancellationRequested) - { - var packArea = workArea; - if (allParts.Count > 0) - { - var obstacles = allParts - .Select(part => part.BoundingBox.Offset(Plate.PartSpacing)) - .ToList(); - var finder = new RemnantFinder(workArea, obstacles); - var remnants = finder.FindRemnants(); - packArea = remnants.Count > 0 ? remnants[0] : new Box(0, 0, 0, 0); - } - - if (packArea.Width > 0 && packArea.Length > 0) - { - var packParts = PackArea(packArea, packItems, progress, token); - allParts.AddRange(packParts); - } - } - - foreach (var item in items) - { - if (item.Quantity <= 0) - continue; - - var placed = allParts.Count(part => ReferenceEquals(part.BaseDrawing, item.Drawing)); - item.Quantity = System.Math.Max(0, item.Quantity - placed); - } - - return allParts; - } -} diff --git a/OpenNest.Engine/Jobs/Placement/PlateFillService.cs b/OpenNest.Engine/Jobs/Placement/PlateFillService.cs index 82da30c9..778850ab 100644 --- a/OpenNest.Engine/Jobs/Placement/PlateFillService.cs +++ b/OpenNest.Engine/Jobs/Placement/PlateFillService.cs @@ -53,7 +53,7 @@ public static class PlateFillService demand, 1); } - private static List FillDroppingClampHits(PlateFillerBase filler, Plate plate, + private static List FillDroppingClampHits(PlateFiller filler, Plate plate, NestItem item, List demand, Box area, IProgress progress, CancellationToken token) { @@ -81,7 +81,7 @@ public static class PlateFillService /// spacing would, and keeps the better layout by the filler's own ranking; a tie keeps the /// first. Previews never fall below the layout already found. /// - private static List FillBesideClamps(PlateFillerBase filler, Plate plate, Box workArea, + private static List FillBesideClamps(PlateFiller filler, Plate plate, Box workArea, IProgress progress, CancellationToken token, Func, List> fill, List demand, int groupSize) { @@ -428,20 +428,20 @@ public static class PlateFillService } /// Builds the filler for an optional strategy (null/empty = Fill). - private static PlateFillerBase CreateFiller(string strategy, Plate plate) + private static PlateFiller CreateFiller(string strategy, Plate plate) { ArgumentNullException.ThrowIfNull(plate); return ResolveStrategy(strategy) switch { - "Fill" => new DefaultPlateFiller(plate), - "Strip" => new StripPlateFiller(plate), - "Vertical Remnant" => new DefaultPlateFiller(plate, PlateFillPolicy.VerticalRemnant), - _ => new DefaultPlateFiller(plate, PlateFillPolicy.HorizontalRemnant), + "Fill" => new PlateFiller(plate), + "Strip" => new PlateFiller(plate, PlateFillPolicy.Fill, PlateLayout.Strips), + "Vertical Remnant" => new PlateFiller(plate, PlateFillPolicy.VerticalRemnant), + _ => new PlateFiller(plate, PlateFillPolicy.HorizontalRemnant), }; } /// Public operations require an explicit strategy name (null is an argument error). - private static PlateFillerBase RequireFiller(string strategy, Plate plate) + private static PlateFiller RequireFiller(string strategy, Plate plate) { ArgumentNullException.ThrowIfNull(strategy); // An explicit empty string is an unknown strategy; only ResolveStrategy(string), diff --git a/OpenNest.Engine/Jobs/Placement/PrivatePlateFill.cs b/OpenNest.Engine/Jobs/Placement/PrivatePlateFill.cs index 9b41d0e8..6138eb9e 100644 --- a/OpenNest.Engine/Jobs/Placement/PrivatePlateFill.cs +++ b/OpenNest.Engine/Jobs/Placement/PrivatePlateFill.cs @@ -32,7 +32,7 @@ internal static class PrivatePlateFill fits.AddRange(sorted); // A positive quantity lets supporting strategies avoid surplus rows. Zero still // fills the whole area (the cutout lattice caller requires an uncapped lattice). - var filler = new DefaultPlateFiller(plate) { StopAtQuantity = true }; + var filler = new PlateFiller(plate) { StopAtQuantity = true }; return filler.Fill(new NestItem { Drawing = drawing, diff --git a/OpenNest.Engine/Jobs/Placement/RemnantPlateNester.cs b/OpenNest.Engine/Jobs/Placement/RemnantPlateNester.cs index 3b3bc6ec..b8375bf6 100644 --- a/OpenNest.Engine/Jobs/Placement/RemnantPlateNester.cs +++ b/OpenNest.Engine/Jobs/Placement/RemnantPlateNester.cs @@ -6,7 +6,7 @@ namespace OpenNest.Engine.Jobs.Placement; /// /// Built-in remnant placement strategy for the whole-job runner. Fills one candidate per trial with -/// a with the vertical or horizontal remnant . Placement is +/// a with the vertical or horizontal remnant . Placement is /// 's with that filler: the same fresh private plate per trial and /// the same run-scoped identity, progress, and accounting boundaries. /// @@ -18,7 +18,7 @@ public sealed class RemnantPlateNester : IPlateNester { private readonly DefaultPlateNester nester; - internal RemnantPlateNester(Func fillerFactory) + internal RemnantPlateNester(Func fillerFactory) { nester = new DefaultPlateNester( fillerFactory ?? throw new ArgumentNullException(nameof(fillerFactory))); @@ -26,11 +26,11 @@ public sealed class RemnantPlateNester : IPlateNester /// Vertical-remnant policy: minimize X-extent, prefer horizontal placement. internal static RemnantPlateNester Vertical() => - new(plate => new DefaultPlateFiller(plate, PlateFillPolicy.VerticalRemnant)); + new(plate => new PlateFiller(plate, PlateFillPolicy.VerticalRemnant)); /// Horizontal-remnant policy: minimize Y-extent, prefer vertical placement. internal static RemnantPlateNester Horizontal() => - new(plate => new DefaultPlateFiller(plate, PlateFillPolicy.HorizontalRemnant)); + new(plate => new PlateFiller(plate, PlateFillPolicy.HorizontalRemnant)); public PlateCandidate Place( PlatePlacementRequest request, diff --git a/OpenNest.Engine/Jobs/Placement/StripPlateNester.cs b/OpenNest.Engine/Jobs/Placement/StripPlateNester.cs index 5b2aaf2b..9ba318a9 100644 --- a/OpenNest.Engine/Jobs/Placement/StripPlateNester.cs +++ b/OpenNest.Engine/Jobs/Placement/StripPlateNester.cs @@ -7,8 +7,9 @@ using OpenNest.Engine.Jobs.Placement.Fillers; namespace OpenNest.Engine.Jobs.Placement; /// -/// Built-in placement strategy for the whole-job runner. Runs the -/// iterative shrink-fill/pack geometry with the same run-scoped bookkeeping as +/// Built-in placement strategy for the whole-job runner. Runs a with the +/// layout (iterative shrink-fill strips, then a pack) +/// with the same run-scoped bookkeeping as /// : remaining demand is read from the request and placement counts /// are derived from returned placements. /// @@ -20,15 +21,15 @@ namespace OpenNest.Engine.Jobs.Placement; /// public sealed class StripPlateNester : IPlateNester { - private readonly Func fillerFactory; + private readonly Func fillerFactory; private readonly OrderedPlateNester restrictedRotationNester = new(); private readonly CandidatePlacementContext context = new(); public StripPlateNester() - : this(static plate => new StripPlateFiller(plate)) { } + : this(static plate => new PlateFiller(plate, PlateFillPolicy.Fill, PlateLayout.Strips)) { } - /// Injectable for tests; defaults to . - internal StripPlateNester(Func fillerFactory) + /// Injectable for tests; defaults to the strip-layout . + internal StripPlateNester(Func fillerFactory) { this.fillerFactory = fillerFactory ?? throw new ArgumentNullException(nameof(fillerFactory)); diff --git a/OpenNest.Engine/ML/BruteForceRunner.cs b/OpenNest.Engine/ML/BruteForceRunner.cs index 37aa9067..db77cd1d 100644 --- a/OpenNest.Engine/ML/BruteForceRunner.cs +++ b/OpenNest.Engine/ML/BruteForceRunner.cs @@ -31,7 +31,7 @@ namespace OpenNest.Engine.ML bool forceFullAngleSweep = false ) { - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); filler.ForceFullAngleSweep = forceFullAngleSweep; var item = new NestItem { Drawing = drawing }; diff --git a/OpenNest.Engine/Strategies/FillContext.cs b/OpenNest.Engine/Strategies/FillContext.cs index e4e39ea0..4c46a377 100644 --- a/OpenNest.Engine/Strategies/FillContext.cs +++ b/OpenNest.Engine/Strategies/FillContext.cs @@ -101,7 +101,7 @@ namespace OpenNest.Engine.Strategies /// the canonical drawing's baked source angle whenever it's non-zero. No-op when /// isn't set. Internal so callers that build their own /// outside (e.g. the fallback - /// report in DefaultPlateFiller.RunPipeline for strategies that don't self-report) + /// report in PlateFiller.RunPipeline for strategies that don't self-report) /// can apply the same rebind before reaching the UI. /// internal List ToOriginalFrame(List parts) diff --git a/OpenNest.Tests/Engine/EngineRefactorSmokeTests.cs b/OpenNest.Tests/Engine/EngineRefactorSmokeTests.cs index 4ee8a82b..df5eaff5 100644 --- a/OpenNest.Tests/Engine/EngineRefactorSmokeTests.cs +++ b/OpenNest.Tests/Engine/EngineRefactorSmokeTests.cs @@ -18,10 +18,10 @@ public class EngineRefactorSmokeTests } [Fact] - public void DefaultPlateFiller_FillNestItem_ProducesResults() + public void PlateFiller_FillNestItem_ProducesResults() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; var parts = filler.Fill( @@ -31,14 +31,14 @@ public class EngineRefactorSmokeTests System.Threading.CancellationToken.None ); - Assert.True(parts.Count > 0, "DefaultPlateFiller should fill parts"); + Assert.True(parts.Count > 0, "PlateFiller should fill parts"); } [Fact] - public void DefaultPlateFiller_FillGroupParts_ProducesResults() + public void PlateFiller_FillGroupParts_ProducesResults() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var drawing = MakeRectDrawing(20, 10); var groupParts = new List { new Part(drawing) }; @@ -49,14 +49,14 @@ public class EngineRefactorSmokeTests System.Threading.CancellationToken.None ); - Assert.True(parts.Count > 0, "DefaultPlateFiller group fill should produce parts"); + Assert.True(parts.Count > 0, "PlateFiller group fill should produce parts"); } [Fact] - public void DefaultPlateFiller_ForceFullAngleSweep_StillWorks() + public void PlateFiller_ForceFullAngleSweep_StillWorks() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); filler.ForceFullAngleSweep = true; var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; @@ -73,10 +73,10 @@ public class EngineRefactorSmokeTests [Theory] [InlineData(false)] [InlineData(true)] - public void DefaultPlateFiller_StopAtQuantity_StillDeliversExactlyTheQuantity(bool stopAtQuantity) + public void PlateFiller_StopAtQuantity_StillDeliversExactlyTheQuantity(bool stopAtQuantity) { var plate = new Plate(60, 120) { PartSpacing = 0.5 }; - var filler = new DefaultPlateFiller(plate) { StopAtQuantity = stopAtQuantity }; + var filler = new PlateFiller(plate) { StopAtQuantity = stopAtQuantity }; var item = new NestItem { Drawing = MakeRectDrawing(7, 3), Quantity = 23 }; var parts = filler.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None); @@ -92,10 +92,10 @@ public class EngineRefactorSmokeTests } [Fact] - public void StripPlateFiller_Nest_ProducesResults() + public void StripLayout_Nest_ProducesResults() { var plate = new Plate(60, 120); - var filler = new StripPlateFiller(plate); + var filler = new PlateFiller(plate, PlateFillPolicy.Fill, PlateLayout.Strips); var items = new List { new NestItem { Drawing = MakeRectDrawing(20, 10, "large"), Quantity = 10 }, @@ -104,14 +104,14 @@ public class EngineRefactorSmokeTests var parts = filler.Nest(items, null, System.Threading.CancellationToken.None); - Assert.True(parts.Count > 0, "StripPlateFiller should nest parts"); + Assert.True(parts.Count > 0, "Strip layout should nest parts"); } [Fact] - public void DefaultPlateFiller_Nest_ProducesResults() + public void PlateFiller_Nest_ProducesResults() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var items = new List { new NestItem { Drawing = MakeRectDrawing(20, 10, "a"), Quantity = 5 }, diff --git a/OpenNest.Tests/Engine/NestInvarianceTests.cs b/OpenNest.Tests/Engine/NestInvarianceTests.cs index 8d790095..af092a60 100644 --- a/OpenNest.Tests/Engine/NestInvarianceTests.cs +++ b/OpenNest.Tests/Engine/NestInvarianceTests.cs @@ -38,7 +38,7 @@ public class NestInvarianceTests private static int RunFillCount(Drawing drawing, Plate plate) { BestFitCache.Clear(); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var item = new NestItem { Drawing = drawing }; var parts = filler.Fill( item, @@ -72,7 +72,7 @@ public class NestInvarianceTests foreach (var theta in new[] { 0.0, 0.3, 0.8, 1.2 }) { BestFitCache.Clear(); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var item = new NestItem { Drawing = MakeImportedAt(theta) }; var parts = filler.Fill(item, workArea, progress: null, token: CancellationToken.None); diff --git a/OpenNest.Tests/Engine/RemnantEngineTests.cs b/OpenNest.Tests/Engine/RemnantEngineTests.cs index d685cbfa..e67895fc 100644 --- a/OpenNest.Tests/Engine/RemnantEngineTests.cs +++ b/OpenNest.Tests/Engine/RemnantEngineTests.cs @@ -23,7 +23,7 @@ public class RemnantEngineTests public void VerticalRemnantPlateFiller_UsesHorizontalPreferredDirection() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate, PlateFillPolicy.VerticalRemnant); + var filler = new PlateFiller(plate, PlateFillPolicy.VerticalRemnant); Assert.Equal(NestDirection.Horizontal, filler.PreferredDirection); } @@ -31,7 +31,7 @@ public class RemnantEngineTests public void HorizontalRemnantPlateFiller_UsesVerticalPreferredDirection() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate, PlateFillPolicy.HorizontalRemnant); + var filler = new PlateFiller(plate, PlateFillPolicy.HorizontalRemnant); Assert.Equal(NestDirection.Vertical, filler.PreferredDirection); } @@ -39,7 +39,7 @@ public class RemnantEngineTests public void VerticalRemnantPlateFiller_Fill_ProducesResults() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate, PlateFillPolicy.VerticalRemnant); + var filler = new PlateFiller(plate, PlateFillPolicy.VerticalRemnant); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; var parts = filler.Fill( @@ -56,7 +56,7 @@ public class RemnantEngineTests public void HorizontalRemnantPlateFiller_Fill_ProducesResults() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate, PlateFillPolicy.HorizontalRemnant); + var filler = new PlateFiller(plate, PlateFillPolicy.HorizontalRemnant); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; var parts = filler.Fill( @@ -83,8 +83,8 @@ public class RemnantEngineTests var drawing = MakeRectDrawing(20, 10); var item = new NestItem { Drawing = drawing }; - var defaultFiller = new DefaultPlateFiller(plate); - var remnantFiller = new DefaultPlateFiller(plate, PlateFillPolicy.VerticalRemnant); + var defaultFiller = new PlateFiller(plate); + var remnantFiller = new PlateFiller(plate, PlateFillPolicy.VerticalRemnant); var defaultParts = defaultFiller.Fill( item, diff --git a/OpenNest.Tests/Fill/IterativeShrinkFillerTests.cs b/OpenNest.Tests/Fill/IterativeShrinkFillerTests.cs index e35a04b7..08b0df22 100644 --- a/OpenNest.Tests/Fill/IterativeShrinkFillerTests.cs +++ b/OpenNest.Tests/Fill/IterativeShrinkFillerTests.cs @@ -1,7 +1,7 @@ +using OpenNest.Engine; using OpenNest.Engine.Fill; using OpenNest.Engine.Jobs.Placement.Fillers; using OpenNest.Geometry; -using OpenNest.Engine; namespace OpenNest.Tests.Fill; @@ -55,7 +55,7 @@ public class IterativeShrinkFillerTests Func> fillFunc = (ni, b) => { var plate = new Plate(b.Width, b.Length); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); return filler.Fill(ni, b, null, System.Threading.CancellationToken.None); }; @@ -76,7 +76,7 @@ public class IterativeShrinkFillerTests Func> fillFunc = (ni, b) => { var plate = new Plate(b.Width, b.Length); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); return filler.Fill(ni, b, null, System.Threading.CancellationToken.None); }; @@ -101,7 +101,7 @@ public class IterativeShrinkFillerTests Func> fillFunc = (ni, b) => { var plate = new Plate(b.Width, b.Length); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); return filler.Fill(ni, b, null, System.Threading.CancellationToken.None); }; @@ -123,7 +123,7 @@ public class IterativeShrinkFillerTests Func> fillFunc = (ni, b) => { var plate = new Plate(b.Width, b.Length); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); return filler.Fill(ni, b, null, System.Threading.CancellationToken.None); }; diff --git a/OpenNest.Tests/Fill/RemnantFillerTests2.cs b/OpenNest.Tests/Fill/RemnantFillerTests2.cs index fc7c00c6..5f5744ca 100644 --- a/OpenNest.Tests/Fill/RemnantFillerTests2.cs +++ b/OpenNest.Tests/Fill/RemnantFillerTests2.cs @@ -1,7 +1,7 @@ +using OpenNest.Engine; using OpenNest.Engine.Fill; using OpenNest.Engine.Jobs.Placement.Fillers; using OpenNest.Geometry; -using OpenNest.Engine; namespace OpenNest.Tests.Fill; @@ -36,7 +36,7 @@ public class RemnantFillerTests2 Func> fillFunc = (ni, b) => { var plate = new Plate(b.Width, b.Length); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); return filler.Fill(ni, b, null, System.Threading.CancellationToken.None); }; @@ -60,7 +60,7 @@ public class RemnantFillerTests2 Func> fillFunc = (ni, b) => { var plate = new Plate(b.Width, b.Length); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); return filler.Fill(ni, b, null, System.Threading.CancellationToken.None); }; diff --git a/OpenNest.Tests/Fill/ShrinkFillerTests.cs b/OpenNest.Tests/Fill/ShrinkFillerTests.cs index cbdba86c..e2472f90 100644 --- a/OpenNest.Tests/Fill/ShrinkFillerTests.cs +++ b/OpenNest.Tests/Fill/ShrinkFillerTests.cs @@ -1,7 +1,7 @@ +using OpenNest.Engine; using OpenNest.Engine.Fill; using OpenNest.Engine.Jobs.Placement.Fillers; using OpenNest.Geometry; -using OpenNest.Engine; namespace OpenNest.Tests.Fill; @@ -28,7 +28,7 @@ public class ShrinkFillerTests Func> fillFunc = (ni, b) => { var plate = new Plate(b.Width, b.Length); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); return filler.Fill(ni, b, null, System.Threading.CancellationToken.None); }; @@ -50,7 +50,7 @@ public class ShrinkFillerTests Func> fillFunc = (ni, b) => { var plate = new Plate(b.Width, b.Length); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); return filler.Fill(ni, b, null, System.Threading.CancellationToken.None); }; @@ -151,6 +151,6 @@ public class ShrinkFillerTests var trimmed = ShrinkFiller.TrimToCount(parts, 1, ShrinkAxis.Width); Assert.Equal(originalCount, parts.Count); - Assert.Equal(1, trimmed.Count); + Assert.Single(trimmed); } } diff --git a/OpenNest.Tests/Strategies/FillPipelineTests.cs b/OpenNest.Tests/Strategies/FillPipelineTests.cs index c74f3e59..66a43e31 100644 --- a/OpenNest.Tests/Strategies/FillPipelineTests.cs +++ b/OpenNest.Tests/Strategies/FillPipelineTests.cs @@ -26,7 +26,7 @@ public class FillPipelineTests public void Pipeline_PopulatesPhaseResults() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; filler.Fill(item, plate.WorkArea(), null, System.Threading.CancellationToken.None); @@ -41,7 +41,7 @@ public class FillPipelineTests public void Pipeline_SetsWinnerPhase() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; var parts = filler.Fill( @@ -65,7 +65,7 @@ public class FillPipelineTests public void Pipeline_RespectsCancellation() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; var cts = new System.Threading.CancellationTokenSource(); cts.Cancel(); @@ -81,7 +81,7 @@ public class FillPipelineTests public void Pipeline_ReportsBoxLayoutBeforeBestFitPairs() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; var reports = new List(); @@ -97,7 +97,7 @@ public class FillPipelineTests public void Pipeline_ReportsStatusWhileComputingBestFitPairs() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; var reports = new List(); @@ -113,7 +113,7 @@ public class FillPipelineTests public void Pipeline_AcceptedBeforeBestFitPairs_ReturnsBoxLayout() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; using var cts = new CancellationTokenSource(); NestProgress first = null; @@ -137,7 +137,7 @@ public class FillPipelineTests public void Pipeline_ShownLayoutNeverRegressesBelowBoxLayout() { var plate = new Plate(60, 120); - var filler = new DefaultPlateFiller(plate); + var filler = new PlateFiller(plate); var item = new NestItem { Drawing = MakeRectDrawing(20, 10) }; var shown = new List();