From c94beb51a43d5c91ac1e8d382ef5fac574b73b3f Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Mon, 16 Mar 2026 22:49:27 -0400 Subject: [PATCH] feat(engine): try interlocking pair patterns in remainder strips FillLinear now accepts optional RemainderPatterns that are tried in leftover strips after the main grid fill, improving packing density when pair patterns fit the narrow residual space. Co-Authored-By: Claude Opus 4.6 (1M context) --- OpenNest.Engine/FillLinear.cs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/OpenNest.Engine/FillLinear.cs b/OpenNest.Engine/FillLinear.cs index 92e6415..8fe1ef0 100644 --- a/OpenNest.Engine/FillLinear.cs +++ b/OpenNest.Engine/FillLinear.cs @@ -19,6 +19,11 @@ namespace OpenNest public double HalfSpacing => PartSpacing / 2; + /// + /// Optional multi-part patterns (e.g. interlocking pairs) to try in remainder strips. + /// + public List RemainderPatterns { get; set; } + private static Vector MakeOffset(NestDirection direction, double distance) { return direction == NestDirection.Horizontal @@ -408,7 +413,30 @@ namespace OpenNest return new List(); var rotations = BuildRotationSet(seedPattern); - return FindBestFill(rotations, remainingStrip); + var best = FindBestFill(rotations, remainingStrip); + + if (RemainderPatterns != null) + { + System.Diagnostics.Debug.WriteLine($"[FillRemainingStrip] Strip: {remainingStrip.Width:F1}x{remainingStrip.Length:F1}, individual best={best?.Count ?? 0}, trying {RemainderPatterns.Count} patterns"); + + foreach (var pattern in RemainderPatterns) + { + var filler = new FillLinear(remainingStrip, PartSpacing); + var h = filler.Fill(pattern, NestDirection.Horizontal); + var v = filler.Fill(pattern, NestDirection.Vertical); + + System.Diagnostics.Debug.WriteLine($"[FillRemainingStrip] Pattern ({pattern.Parts.Count} parts, bbox={pattern.BoundingBox.Width:F1}x{pattern.BoundingBox.Length:F1}): H={h?.Count ?? 0}, V={v?.Count ?? 0}"); + + if (h != null && h.Count > (best?.Count ?? 0)) + best = h; + if (v != null && v.Count > (best?.Count ?? 0)) + best = v; + } + + System.Diagnostics.Debug.WriteLine($"[FillRemainingStrip] Final best={best?.Count ?? 0}"); + } + + return best ?? new List(); } private static double FindPlacedEdge(List placedParts, NestDirection tiledAxis)