mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-10 19:04:13 -04:00
Default is the engine every front end uses when none is named. It now runs Irregular, then Rectangles, checks both layouts with NestLayoutCheck and keeps the best: valid first, then fewest unplaced parts, then lowest salvage-credited cost; ties keep Irregular. A candidate that throws or returns nothing is skipped, cancellation stops the search, and only the chosen layout's plate commits are reported. Neither engine wins every job in the lane benchmarks, and Rectangles adds little time while also covering Irregular's invalid layouts. The registry lists Default first and no longer maps the name to Fill; fill strategy callers still read Default as Fill. A future circle/ring engine joins as another candidate.
83 lines
2.9 KiB
C#
83 lines
2.9 KiB
C#
using OpenNest.Engine.Jobs;
|
|
using OpenNest.Engine.Jobs.Placement;
|
|
using OpenNest.Engine.NestingEngines.Default;
|
|
using OpenNest.Engine.Tests.Jobs;
|
|
using OpenNest.Geometry;
|
|
|
|
namespace OpenNest.Engine.Tests;
|
|
|
|
/// <summary>
|
|
/// The multi-phase fill engine and placement strategy are named "Fill". "Default" names the
|
|
/// router engine; fill-strategy callers still read "Default" as Fill.
|
|
/// </summary>
|
|
public class FillStrategyNameTests
|
|
{
|
|
[Fact]
|
|
public void FillIsListedBesideTheDefaultRouter()
|
|
{
|
|
var engines = NestingEngineRegistry.AvailableEngines.Select(e => e.Name).ToList();
|
|
|
|
Assert.Equal("Default", engines[0]);
|
|
Assert.Contains("Fill", engines);
|
|
Assert.IsType<FixedStrategyNestingEngine>(NestingEngineRegistry.Create("Fill"));
|
|
Assert.Equal(new[] { "Fill", "Strip", "Vertical Remnant", "Horizontal Remnant" },
|
|
PlateFillService.BuiltInStrategies);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("Default")]
|
|
[InlineData(" default ")]
|
|
public void DefaultNamesTheRouter(string name)
|
|
{
|
|
Assert.Equal("Default", NestingEngineRegistry.ResolveName(name));
|
|
Assert.IsType<DefaultNestingEngine>(NestingEngineRegistry.Create(name));
|
|
}
|
|
|
|
[Fact]
|
|
public void PlugInNamedDefaultCannotReplaceTheRouter()
|
|
{
|
|
var before = NestingEngineRegistry.AvailableEngines.Count;
|
|
|
|
NestingEngineRegistry.Register("Default", "stale plug-in", () => new FixedStrategyNestingEngine("Strip"));
|
|
|
|
Assert.Equal(before, NestingEngineRegistry.AvailableEngines.Count);
|
|
Assert.IsType<DefaultNestingEngine>(NestingEngineRegistry.Create("Default"));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(null, "Fill")]
|
|
[InlineData("", "Fill")]
|
|
[InlineData("fill", "Fill")]
|
|
[InlineData("Default", "Fill")]
|
|
[InlineData("DEFAULT", "Fill")]
|
|
public void PlacementStrategyResolvesFillAndItsLegacyName(string? strategy, string expected)
|
|
{
|
|
Assert.Equal(expected, PlateFillService.ResolveStrategy(strategy!));
|
|
}
|
|
|
|
[Fact]
|
|
public void LegacyStrategyNameStillFillsAPlate()
|
|
{
|
|
var plate = new Plate(new Size(60, 80));
|
|
var drawing = new Drawing("part", TestDrawingFactory.Rectangle(6, 4));
|
|
|
|
var parts = PlateFillService.FillItem("Default", plate,
|
|
new NestItem { Drawing = drawing, Quantity = 6 }, plate.WorkArea(), null, CancellationToken.None);
|
|
|
|
Assert.Equal(6, parts.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public void WholeJobRunnerAcceptsFillAndItsLegacyName()
|
|
{
|
|
Assert.IsType<DefaultPlateNester>(PlateNesterFactory.Create("Fill"));
|
|
Assert.IsType<DefaultPlateNester>(PlateNesterFactory.Create("Default"));
|
|
Assert.Equal("Fill", new NestJobOptions().PlacementStrategy);
|
|
|
|
var job = FiniteStockJobTests.Job(1);
|
|
var legacy = new NestJobRunner(PlateNesterFactory.Create)
|
|
.Solve(new NestJob(job.Parts, job.Plates, new NestJobOptions("Default")));
|
|
Assert.Equal(NestJobStatus.Complete, legacy.Status);
|
|
}
|
|
}
|