perf(fill): reuse validation for an unchanged row

Skip FillGrid's Step 2 overlap check only when Step 1 checked this exact
row clean and the perpendicular tiling appended zero parts, so gridResult
still holds the same Part objects in the same order and poses. The local
rowIsVerified flag is cleared by every Step 1 skip or bbox fallback, and
any nonzero append (including partial-copy parts) keeps the eager check.

Debug work assertions pin the reduced overlap work (horizontal stripe
8->4 exact calls, 4->2 preparations, 16->8 triangulations; vertical
stripe 36->18, 4->2, 38->19) and keep single-seed, Horizontal full-grid,
partial-only and PerpOnly work at base; the invalid overlapping-seed
control pins both fallback stages plus the retained exact-call total.
Three mutants (forced eager check, dropped flag, complete-rows-only)
are caught by their designated controls. Serial whole-job layout is
byte-identical to the frozen 62b5a8d0 oracle before and after.
This commit is contained in:
aj
2026-09-30 17:01:11 -04:00
parent dbcf7dea65
commit 5e9eaf8a4c
3 changed files with 148 additions and 9 deletions
+12 -1
View File
@@ -362,6 +362,9 @@ namespace OpenNest.Engine.Fill
{
var perpAxis = PerpendicularAxis(direction);
// Set only when Step 1's check executed, passed, and no fallback replaced the row.
var rowIsVerified = false;
// Step 1: Tile along primary axis
var row = new List<Part>(pattern.Parts);
row.AddRange(TilePattern(pattern, direction, cache));
@@ -372,6 +375,10 @@ namespace OpenNest.Engine.Fill
row = new List<Part>(pattern.Parts);
row.AddRange(TilePatternBbox(pattern, direction));
}
else if (pattern.Parts.Count > 1)
{
rowIsVerified = true;
}
// If primary tiling didn't produce copies, just tile along perpendicular
if (row.Count <= pattern.Parts.Count)
@@ -396,7 +403,11 @@ namespace OpenNest.Engine.Fill
var gridResult = new List<Part>(rowPattern.Parts);
gridResult.AddRange(TilePattern(rowPattern, perpAxis, cache));
if (HasOverlappingParts(gridResult, out var a3, out var b3))
// Only the unchanged row is covered by Step 1's clean verdict: skip Step 2
// only when the perpendicular tiling appended zero parts, so gridResult
// still contains the same Part objects, in the same order and poses.
if ((!rowIsVerified || gridResult.Count != row.Count)
&& HasOverlappingParts(gridResult, out var a3, out var b3))
{
LogOverlap("Step2-Perp", perpAxis, rowPattern, gridResult, a3, b3);
gridResult = new List<Part>(rowPattern.Parts);