From 12f2ce5deb60fa7f02bf2d3d785e611cf9e61109 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Thu, 15 Oct 2026 23:31:14 -0400 Subject: [PATCH] fix(geometry): stop PolyLabel refinement when centres cannot advance --- OpenNest.Core/Geometry/PolyLabel.cs | 6 ++++++ .../Geometry/PolyLabelDifferentialTests.cs | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/OpenNest.Core/Geometry/PolyLabel.cs b/OpenNest.Core/Geometry/PolyLabel.cs index 92b92e2f..b7362044 100644 --- a/OpenNest.Core/Geometry/PolyLabel.cs +++ b/OpenNest.Core/Geometry/PolyLabel.cs @@ -120,6 +120,12 @@ namespace OpenNest.Geometry halfCell = cell.HalfSize / 2; + // Far from the origin a half-step may no longer move the centre; such a cell + // cannot be split, and its identical children would multiply without end. + if (cell.X - halfCell == cell.X || cell.X + halfCell == cell.X + || cell.Y - halfCell == cell.Y || cell.Y + halfCell == cell.Y) + continue; + var newCells = new[] { new Cell(cell.X - halfCell, cell.Y - halfCell, halfCell, outer, holes), diff --git a/OpenNest.Tests/Geometry/PolyLabelDifferentialTests.cs b/OpenNest.Tests/Geometry/PolyLabelDifferentialTests.cs index e010d96a..aca78883 100644 --- a/OpenNest.Tests/Geometry/PolyLabelDifferentialTests.cs +++ b/OpenNest.Tests/Geometry/PolyLabelDifferentialTests.cs @@ -83,6 +83,19 @@ public class PolyLabelDifferentialTests Assert.InRange(unbounded.Y, 0, 1); } + // Delta review: past the grid, refining a cell whose half-step no longer moves its centre + // made four identical children per level, so a fine unbounded search exhausted memory. + [Fact] + public async Task Find_UnboundedRefinementFinishesWhenSplitsStopAdvancing() + { + var far = Rectangle(1e16, 0, 8, 1); + + var search = Task.Run(() => PolyLabel.Find(far, null, 1e-6)); + + Assert.Same(search, await Task.WhenAny(search, Task.Delay(TimeSpan.FromSeconds(20)))); + Assert.InRange((await search).Y, 0, 1); + } + private static (Polygon outer, List holes) RandomShape(Random random) { var scale = System.Math.Pow(10, random.NextDouble() * 4 - 1);