- Strategies now promote results to IsOverallBest when they beat the
pipeline best, so the UI updates immediately on improvement rather
than waiting for each phase to complete
- PlateView only updates the main view on overall-best results, fixing
intermediate angle-sweep layouts leaking to the plate display
- Skip Row/Column strategies for rectangle parts (redundant with Linear)
- Intercept Escape key at MainForm level via ProcessCmdKey so it always
reaches the active PlateView regardless of focus state
- Restore keyboard focus to PlateView after fill progress form closes
- Remnant engines use SelectBestFitPair for orientation-aware pair
selection; DefaultNestEngine tries both landscape and portrait pairs
- RemnantFiller preserves more parts during topmost-part removal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Strategies and fillers previously called NestEngineBase.ReportProgress
directly, each constructing ProgressReport structs with phase, plate
number, and work area manually. Some strategies (RectBestFit) reported
nothing at all. This made progress updates inconsistent and flakey.
Add FillContext.ReportProgress(parts, description) as the single
standard method for intermediate progress. RunPipeline sets ActivePhase
before each strategy, and the context handles common fields. Lower-level
fillers (PairFiller, FillExtents, StripeFiller) now accept an
Action<List<Part>, string> callback instead of raw IProgress, removing
their coupling to NestEngineBase and ProgressReport.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
For qty 1-2, skip the full 6-strategy pipeline: place a single part
or a best-fit pair directly. For larger low quantities, shrink the
work area in both dimensions (sqrt scaling with 2x margin) before
running strategies, with fallback to full area if insufficient.
- Add TryFillSmallQuantity fast path (qty=1 single, qty=2 best-fit pair)
- Add ShrinkWorkArea with proportional dual-axis reduction
- Extract RunFillPipeline helper from Fill()
- Make ShrinkFiller.EstimateStartBox internal with margin parameter
- Add MaxQuantity to FillContext for strategy-level access
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace RotationAnalysis.FindBestRotation with PartClassifier.Classify in
RunPipeline, propagate ClassificationResult through BuildAngles signatures and
FillContext.PartType, and rewrite AngleCandidateBuilder to dispatch on part type
(Circle=1 angle, Rectangle=2, Irregular=full sweep).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- FillContext gains a Policy property (init-only) carrying the IFillComparer
- DefaultNestEngine.Fill sets Policy = BuildPolicy() on every context
- RunPipeline now uses context.Policy.Comparer.IsBetter instead of IsBetterFill
- RunPipeline promoted to protected virtual so subclasses can override
- BuildAngles/RecordProductiveAngles overrides delegate to angleBuilder
- RunPipeline calls virtual BuildAngles/RecordProductiveAngles instead of angleBuilder directly
- TODO comment added in group-fill overload for Task 6 Comparer pass-through
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>