Extract magic numbers into named constants (MaxTopCandidates,
EarlyExitMinTried, etc.), extract candidate evaluation into
EvaluateCandidate method, and expose BestFits property so
PairsFillStrategy can reuse without redundant BestFitCache call.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The pattern bounding box already computes max(upper) - min(lower), so the
manual loop was redundant. Extract the N×N pair distance loop into a static
FindMaxPairDistance helper. Drop pre-cached edge arrays since GetEdges()
returns stored references with zero allocation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Also fix missing using for FillHelpers in FillLinear and FillExtents,
and update callers (CompactorTests, PatternTileForm) for the new
Vector parameter.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move known-good pruning check before sweep/ML to avoid wasted work,
extract ContainsAngle, NeedsSweep, AddSweepAngles, ApplyMlPrediction,
and BuildPrunedList so Build reads as a clear pipeline.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FillExtents vertical copy distance was not clamped, allowing rows to be
placed overlapping each other when slide calculations returned large
values. Clamp to pairHeight + partSpacing minimum, matching FillLinear.
Also add FillStrategyRegistry.SetEnabled() to restrict which strategies
run — useful for isolating individual strategies during troubleshooting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Single-part group fills now delegate to Fill(NestItem) which runs
the full strategy pipeline, eliminating ~70 lines of duplicated
manual phase logic. Multi-part group fills retain the linear
pattern fill (unique to multi-part groups).
PairFiller now references FillHelpers directly instead of
bouncing through DefaultNestEngine helper methods.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move AutoNester, BottomLeftFill, NfpCache, SimulatedAnnealing,
and INestOptimizer/NestResult to OpenNest.Engine.Nfp. These are
not yet integrated into the engine registry.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move fill algorithms to OpenNest.Engine.Fill namespace:
FillLinear, FillExtents, PairFiller, ShrinkFiller, Compactor,
RemnantFiller, RemnantFinder, FillScore, Pattern, PatternTiler,
PartBoundary, RotationAnalysis, AngleCandidateBuilder, and
AccumulatingProgress.
Move strategy layer to OpenNest.Engine.Strategies namespace:
IFillStrategy, FillContext, FillStrategyRegistry, FillHelpers,
and all built-in strategy implementations.
Add using directives to all consuming files across Engine, UI,
MCP, and Tests projects.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DefaultNestEngine.Fill(NestItem, ...) now delegates to RunPipeline
which iterates FillStrategyRegistry.Strategies in order.
Removed: FindBestFill, FillRectangleBestFit, QuickFillCount.
Kept: AngleCandidateBuilder, ForceFullAngleSweep, group-fill overload.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wraps FillLinear in an IFillStrategy, sweeping all AngleCandidates
from SharedState (falling back to 0° and 90°) in both directions and
recording AngleResults for UI inspection.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wraps FillExtents in an IFillStrategy, trying both bestRotation and
bestRotation+90° angles and picking the better result. Reads
BestFits from SharedState (populated by PairsFillStrategy) to allow
FillExtents to search the best-fit cache for improved pair geometry.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wraps FillBestFit rectangle packer in an IFillStrategy so the rect
best-fit phase participates in the pluggable pipeline.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wraps PairFiller in an IFillStrategy so the pairs phase participates
in the pluggable pipeline. Stores BestFitResults in SharedState for
downstream strategies (Extents) to reuse.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move BuildRotatedPattern and FillPattern static methods into a new
public FillHelpers class in Strategies/. DefaultNestEngine retains
internal static forwarding stubs so existing callsites are unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Vector-based overloads to SpatialQuery (ray casting, edge distance,
directional gap, perpendicular overlap) and PartGeometry (directional
line filtering) to support pushing parts along any angle, not just
cardinal directions.
Add Compactor.PushBoundingBox for fast coarse positioning using only
bounding box gaps. ActionClone shift+click now uses a two-phase strategy:
BB push first to skip past irregular geometry snags, then geometry push
to settle against actual contours.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- FillExtents.Fill reported progress internally which overwrote the UI's
temporary parts even when a better result (e.g. Pairs with 70 parts)
won the competition. Added final ReportProgress call in FindBestFill
and Fill(groupParts) to ensure the UI always shows the actual winner.
- FillExtents vertical copy distance clamp (Math.Max with pairHeight +
spacing) prevented geometry-aware compaction from ever occurring,
causing visible gaps between rows. Boundaries are already inflated by
halfSpacing so the calculated distance is correct; only fall back to
bounding-box distance on non-positive results.
- PairFiller now sets RemainderPatterns on FillLinear so remainder strips
get pair-based filling instead of only individual parts (+1 part in
tight layouts).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds FillExtents as a fourth nesting phase in both FindBestFill and
Fill(groupParts, Box), running at bestRotation and bestRotation+90°.
Updates Description to reflect the new phase.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace RepeatColumns stub with real implementation: compacts a test column
left against column 1 to derive the copy distance, tiles further columns at
that interval, and clips partial columns to the work area bounds. Adds 4 new
FillExtentsTests covering multi-column fill, rect shapes, non-zero-origin
work areas, and cancellation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace AdjustColumn stub with a convergence loop that distributes the
remaining gap between the topmost part and the work area top edge across
all pairs. TryAdjustPair/TryShiftDirection try shifting part2 up (or down
as fallback) and compact left, rejecting moves that widen the pair.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The Size fix (d4222db) changed Size.Width to Y axis and Size.Length to
X axis but only updated DrawPlate/LayoutViewGL. BoundingBox, WorkArea,
rotations, DXF export, and engine code still used the old Width=X
convention, causing the fill engine to get a swapped work area (60x120
instead of 120x60) and parts to fill in the wrong direction.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Longest edges produce the flattest tiling rows and should be tried
first. Also deduplicates angles before sorting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FillLinear now accepts optional RemainderPatterns that are tried in
leftover strips after the main grid fill, improving packing density
when pair patterns fit the narrow residual space.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>