mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 08:21:05 -04:00
fix(geometry): end PolyLabel's starting grid where steps stop advancing
Far from the origin a grid step smaller than the coordinate's precision leaves x (or y) unchanged: at 1e16, 1e16 + 1 == 1e16. The starting grid loop then never ended and allocated cells without limit, even with the new maxCells budget (a hang dump reached 4.3 GB). Stop a row or column once its step no longer advances. Grids that advance are untouched, so the bit-identical differential against the former sorted-list implementation still passes. Found by the independent quality review of the Clipper2 overlap branch.
This commit is contained in:
1 parent
80d01839bd
commit
83b606c486
2 files changed
+25
No files matched your search
@@ -73,8 +73,18 @@ namespace OpenNest.Geometry
|
||||
var initial = new List<Cell>();
|
||||
|
||||
for (var x = minX; x < maxX; x += cellSize)
|
||||
{
|
||||
for (var y = minY; y < maxY; y += cellSize)
|
||||
{
|
||||
initial.Add(new Cell(x + halfCell, y + halfCell, halfCell, outer, holes));
|
||||
// Far from the origin a step smaller than the coordinate's precision
|
||||
// no longer advances; the grid would never end.
|
||||
if (y + cellSize == y)
|
||||
break;
|
||||
}
|
||||
if (x + cellSize == x)
|
||||
break;
|
||||
}
|
||||
|
||||
initial.Sort((a, b) => b.MaxDist.CompareTo(a.MaxDist));
|
||||
|
||||
|
||||
@@ -68,6 +68,21 @@ public class PolyLabelDifferentialTests
|
||||
Assert.True(Same(PolyLabel.Find(shape), PolyLabel.Find(shape, null, 0.5, int.MaxValue)));
|
||||
}
|
||||
|
||||
// Quality review: at 1e16 a 1-unit grid step no longer changes x (1e16 + 1 == 1e16), and
|
||||
// the starting grid loop never ended, allocating cells without limit even with a budget.
|
||||
[Fact]
|
||||
public async Task Find_FinishesWhenGridStepsStopAdvancingFarFromTheOrigin()
|
||||
{
|
||||
var far = Rectangle(1e16, 0, 8, 1);
|
||||
|
||||
var search = Task.Run(() => (PolyLabel.Find(far, null, 0.01, 4096), PolyLabel.Find(far, null, 0.01)));
|
||||
|
||||
Assert.Same(search, await Task.WhenAny(search, Task.Delay(TimeSpan.FromSeconds(20))));
|
||||
var (bounded, unbounded) = await search;
|
||||
Assert.InRange(bounded.Y, 0, 1);
|
||||
Assert.InRange(unbounded.Y, 0, 1);
|
||||
}
|
||||
|
||||
private static (Polygon outer, List<Polygon> holes) RandomShape(Random random)
|
||||
{
|
||||
var scale = System.Math.Pow(10, random.NextDouble() * 4 - 1);
|
||||
|
||||
Reference in new issue
Block a user