mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-11 04:11:09 -05:00
Fill only tried 0 and 90 degrees for parts classified as rectangles, so a long part filling a 60 x 120 plate four high at 90 degrees left a 55 x 59 strip empty although two more fit tilted about 33 degrees (a reported nest: 4 placed, 6 fit). The second tilted part only fits with its corner tucked beside the grid, in the strip the grid's slack leaves, so a plain rectangular remnant fill finds one. TiltedRemnant runs after the other strategies. It moves the best layout flush to one end so leftover room becomes one remnant, and to either end of the other axis so its slack forms one strip; then tiles the part at the most upright angles that fit the remnant's height and keeps only copies at least the part spacing from the layout. It is skipped when the part fits the remnant upright, for circles, for an explicit rotation range and once the requested quantity is placed. Fill benchmark (--parallel 1): the synthetic set is unchanged (all valid, same cost and plates). The reported part needs 1 sheet instead of 2 for 6 parts and 2 instead of 3 for 12. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
2.3 KiB
C#
62 lines
2.3 KiB
C#
using System.Linq;
|
|
using OpenNest.Engine.Strategies;
|
|
|
|
namespace OpenNest.Tests.Strategies;
|
|
|
|
public class FillStrategyRegistryTests
|
|
{
|
|
[Fact]
|
|
public void Registry_DiscoversBuiltInStrategies()
|
|
{
|
|
var strategies = FillStrategyRegistry.Strategies;
|
|
|
|
Assert.True(
|
|
strategies.Count >= 6,
|
|
$"Expected at least 6 built-in strategies, got {strategies.Count}"
|
|
);
|
|
Assert.Contains(strategies, s => s.Name == "Pairs");
|
|
Assert.Contains(strategies, s => s.Name == "RectBestFit");
|
|
Assert.Contains(strategies, s => s.Name == "Extents");
|
|
Assert.Contains(strategies, s => s.Name == "Linear");
|
|
Assert.Contains(strategies, s => s.Name == "Row");
|
|
Assert.Contains(strategies, s => s.Name == "Column");
|
|
}
|
|
|
|
[Fact]
|
|
public void Registry_StrategiesAreOrderedByOrder()
|
|
{
|
|
var strategies = FillStrategyRegistry.Strategies;
|
|
|
|
for (var i = 1; i < strategies.Count; i++)
|
|
Assert.True(
|
|
strategies[i].Order >= strategies[i - 1].Order,
|
|
$"Strategy '{strategies[i].Name}' (Order={strategies[i].Order}) should not precede '{strategies[i - 1].Name}' (Order={strategies[i - 1].Order})"
|
|
);
|
|
}
|
|
|
|
[Fact]
|
|
public void Registry_LinearIsLastBeforeTiltedRemnant()
|
|
{
|
|
// TiltedRemnant adds to the best layout, so it follows every strategy that builds one.
|
|
var strategies = FillStrategyRegistry.Strategies;
|
|
|
|
Assert.Equal("TiltedRemnant", strategies[strategies.Count - 1].Name);
|
|
Assert.Equal("Linear", strategies[strategies.Count - 2].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Registry_RowAndColumnOrderedBetweenPairsAndRectBestFit()
|
|
{
|
|
var strategies = FillStrategyRegistry.Strategies;
|
|
var pairsOrder = strategies.First(s => s.Name == "Pairs").Order;
|
|
var rectOrder = strategies.First(s => s.Name == "RectBestFit").Order;
|
|
var rowOrder = strategies.First(s => s.Name == "Row").Order;
|
|
var colOrder = strategies.First(s => s.Name == "Column").Order;
|
|
|
|
Assert.True(rowOrder > pairsOrder, "Row should run after Pairs");
|
|
Assert.True(colOrder > pairsOrder, "Column should run after Pairs");
|
|
Assert.True(rowOrder < rectOrder, "Row should run before RectBestFit");
|
|
Assert.True(colOrder < rectOrder, "Column should run before RectBestFit");
|
|
}
|
|
}
|