feat: add remnant filling to PairFiller for better part density

PairFiller previously only filled the main grid with pair patterns,
leaving narrow waste strips unfilled. Row/Column strategies filled
their remnants, winning on count despite worse base grids.

Now PairFiller evaluates grid+remnant together for each angle/direction
combination, picking the best total. Uses a two-phase approach: fast
grid evaluation first, then remnant filling only for grids within
striking distance of the current best. Remnant results are cached
via FillResultCache.

Constructor now takes Plate (needed to create remnant engine).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-21 15:19:19 -04:00
parent 560105f952
commit 00e7866506
3 changed files with 147 additions and 14 deletions
+8 -6
View File
@@ -16,11 +16,15 @@ public class PairFillerTests
return new Drawing("rect", pgm);
}
private static Plate MakePlate(double width, double length, double spacing = 0.5)
{
return new Plate { Size = new Size(width, length), PartSpacing = spacing };
}
[Fact]
public void Fill_ReturnsPartsForSimpleDrawing()
{
var plateSize = new Size(120, 60);
var filler = new PairFiller(plateSize, 0.5);
var filler = new PairFiller(MakePlate(120, 60));
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var workArea = new Box(0, 0, 120, 60);
@@ -33,8 +37,7 @@ public class PairFillerTests
[Fact]
public void Fill_EmptyResult_WhenPartTooLarge()
{
var plateSize = new Size(10, 10);
var filler = new PairFiller(plateSize, 0.5);
var filler = new PairFiller(MakePlate(10, 10));
var item = new NestItem { Drawing = MakeRectDrawing(20, 20) };
var workArea = new Box(0, 0, 10, 10);
@@ -50,8 +53,7 @@ public class PairFillerTests
var cts = new System.Threading.CancellationTokenSource();
cts.Cancel();
var plateSize = new Size(120, 60);
var filler = new PairFiller(plateSize, 0.5);
var filler = new PairFiller(MakePlate(120, 60));
var item = new NestItem { Drawing = MakeRectDrawing(20, 10) };
var workArea = new Box(0, 0, 120, 60);