The first fill of a new drawing was blamed on the best-fit pair search, but on the
reported nest that search takes ~3.4 s. The time goes to FillLinear.FillGrid, run
thousands of times by the Pairs, Row/Column and Linear strategies: pattern copy-distance
slides and the grid overlap check. Every change keeps the output bit for bit (part
poses compared on the benchmark nest; best-fit results unchanged).
- ConvexDecomposition.Triangulate: unlink clipped vertices from a circular list instead
of List.RemoveAt, and remember why a vertex failed the ear test (same neighbors, same
blocking vertex still present) instead of retesting it after every ear. Compared
bitwise against a frozen pre-change copy, including the blocker-clipped case.
- Collision: skip triangles whose box misses the other triangulation's union box (exact:
min/max and monotone subtraction), reuse each triangle's open vertices, and let the
overlap-only path stop at its first region when there are no holes. Check still
returns every region.
- SpatialQuery.ExtractEntityVertices presizes its set; FillLinear extracts each entity
list's vertices once per copy-distance search rather than once per pair.
- StripeFiller converges its stripe angles and tiles its grids in parallel. Dedup claims,
cached remnant fills, ranking and progress stay in candidate order, and grids are tiled
only for configurations a claim can still win (GridDedup.Contains), so results and
reports do not depend on the thread count.
- LinearFillStrategy fills its angles in parallel through
FillHelpers.BestOverAnglesInParallel; angle results, ranking and progress stay in order.
Benchmark (one drawing, 60x120, 0.25 spacing, cleared plate, interleaved runs):
FillItem Lattice 291/317 s -> 164/153 s, 132 parts both; PairFiller alone 48 s -> 38-42 s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Repo-wide sweep with the pinned CSharpier 1.3.0 tool. Whitespace and
line-wrapping only; OpenNest.Engine.Tests (109) and OpenNest.IO.Tests
pass after reformat, full solution builds 0 errors.
Added .csharpierignore so csproj/config XML keeps its existing layout
(CSharpier's XML wrapping churns attributes with zero benefit).
Formatting is now enforceable: dotnet csharpier check . passes.
- Evaluate pair candidates in parallel batches instead of sequentially
- Add GridDedup to skip duplicate pattern/direction/workArea combos
across PairFiller and StripeFiller strategies
- Replace crude 30% remnant area estimate with L-shaped geometry
calculation using actual grid extents and max utilization
- Move FillStrategyRegistry.SetEnabled to outer evaluation loop
to avoid repeated enable/disable per remnant fill
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>