diff --git a/OpenNest.Engine/FillLinear.cs b/OpenNest.Engine/FillLinear.cs index 431947d..c6cae63 100644 --- a/OpenNest.Engine/FillLinear.cs +++ b/OpenNest.Engine/FillLinear.cs @@ -338,15 +338,23 @@ namespace OpenNest var rowPattern = new Pattern(); rowPattern.Parts.AddRange(result); rowPattern.UpdateBounds(); - var gridResult = FillRecursive(rowPattern, PerpendicularAxis(direction), depth + 1); + var perpAxis = PerpendicularAxis(direction); + var gridResult = FillRecursive(rowPattern, perpAxis, depth + 1); // Fill the remaining strip (after the last full row/column) // with individual parts from the seed pattern. - var remaining = FillRemainingStrip(gridResult, pattern, PerpendicularAxis(direction), direction); + var remaining = FillRemainingStrip(gridResult, pattern, perpAxis, direction); if (remaining.Count > 0) gridResult.AddRange(remaining); + // Try one fewer row/column — the larger remainder strip may + // fit more parts than the extra row contained. + var fewerResult = TryFewerRows(gridResult, rowPattern, pattern, perpAxis, direction); + + if (fewerResult != null && fewerResult.Count > gridResult.Count) + return fewerResult; + return gridResult; } @@ -359,6 +367,35 @@ namespace OpenNest return result; } + /// + /// Tries removing the last row/column from the grid and re-filling the + /// larger remainder strip. Returns null if this doesn't improve the total. + /// + private List TryFewerRows( + List fullResult, Pattern rowPattern, Pattern seedPattern, + NestDirection tiledAxis, NestDirection primaryAxis) + { + var rowPartCount = rowPattern.Parts.Count; + + // Need at least 2 rows for this to make sense (remove 1, keep 1+). + if (fullResult.Count < rowPartCount * 2) + return null; + + // Remove the last row's worth of parts. + var fewerParts = new List(fullResult.Count - rowPartCount); + + for (var i = 0; i < fullResult.Count - rowPartCount; i++) + fewerParts.Add(fullResult[i]); + + var remaining = FillRemainingStrip(fewerParts, seedPattern, tiledAxis, primaryAxis); + + if (remaining.Count <= rowPartCount) + return null; + + fewerParts.AddRange(remaining); + return fewerParts; + } + /// /// After tiling full rows/columns, fills the remaining strip with individual /// parts. The strip is the leftover space along the tiled axis between the