perf(fill): prepare overlap polygons once per check

Both HasOverlappingParts loops rebuilt each part's polygon from its
Program on every pair. PartOverlapChecker prepares each distinct Program
(reference identity) once and each part's world polygon once per call,
then uses the overlap-only Collision.HasOverlap. Loop order, bounding-box
prefilter, early exit and returned indices are unchanged; Part.Intersects
shares the material/polygon recipe and still returns crossing points.

Verification:
- Frozen LegacyPartOverlap differential (original Intersects and both
  loops): verdicts, indices and world polygons bit-identical across fill
  grids, patterns, touching/epsilon gaps, scribe/rapid/empty programs.
- Debug OverlapPolygonPreparations: 246 -> 1 and 64 -> 2 per check.
- Corpus job (169 parts, --engines Default --parallel 1, with 1a):
  median 18,885 -> 13,464 ms over 4+4 alternating runs, identical
  outcomes; serialized layout byte-identical to the base.
This commit is contained in:
aj
2026-09-27 13:34:04 -04:00
parent f44a1a3d2c
commit a27290a29c
9 changed files with 672 additions and 17 deletions
+3 -1
View File
@@ -295,6 +295,8 @@ namespace OpenNest.Engine.Fill
out int overlapB
)
{
var checker = new PartOverlapChecker();
for (var i = 0; i < parts.Count; i++)
{
var b1 = parts[i].BoundingBox;
@@ -311,7 +313,7 @@ namespace OpenNest.Engine.Fill
if (overlapX <= Tolerance.Epsilon || overlapY <= Tolerance.Epsilon)
continue;
if (parts[i].Intersects(parts[j], out _))
if (checker.Overlaps(parts[i], parts[j]))
{
overlapA = i;
overlapB = j;
+3 -1
View File
@@ -170,6 +170,8 @@ namespace OpenNest.Engine.Strategies
/// </summary>
internal static bool HasOverlappingParts(List<Part> parts)
{
var checker = new PartOverlapChecker();
for (var i = 0; i < parts.Count; i++)
{
var b1 = parts[i].BoundingBox;
@@ -186,7 +188,7 @@ namespace OpenNest.Engine.Strategies
if (overlapX <= Tolerance.Epsilon || overlapY <= Tolerance.Epsilon)
continue;
if (parts[i].Intersects(parts[j], out _))
if (checker.Overlaps(parts[i], parts[j]))
return true;
}
}