Add plate-free Push overload and CompactIndividual method that pushes
each part individually against all others as obstacles. Disabled in
StripNestEngine pending investigation — compaction opens irregular gaps
that the remnant finder scatters parts into.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Skip remnants that are too small to fit any remaining part, avoiding
wasted fill attempts. Recalculated each iteration as quantities deplete.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remainder items were being filled into the full remnant box without
compaction. Added ShrinkFill helper that fills then shrinks the box
horizontally and vertically while maintaining the same part count.
This matches the strip item's shrink behavior and produces tighter
layouts that leave more usable space for subsequent items.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The iterative remnant fill was mutating shared NestItem.Quantity objects,
causing the second TryOrientation call (left) to see depleted quantities
from the first call (bottom). Use a local dictionary instead so both
orientations start with the full quantities.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the single-pass guillotine split approach with RemnantFinder-based
iteration. After each fill, re-discover all free rectangles and try all
remaining items again until no more progress is made. This fills gaps that
were previously left empty after the initial strip + remainder layout.
Also change ActiveWorkArea border color from orange to red.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ComputeRemainderWithin only returned the larger of two possible free
rectangles, permanently losing usable area on the other axis after each
remainder item was placed. Replace the single shrinking box with a list
of free rectangles using guillotine cuts so both sub-areas remain
available for subsequent items.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
StripNestEngine only overrode Fill(NestItem), so ActionClone.Fill
and Pack operations fell through to the empty base class defaults.
Now all virtual methods delegate to DefaultNestEngine.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wrap IProgress with AccumulatingProgress so remnant fills prepend
previously placed strip parts to each report. The UI now shows the
full picture (red + purple) instead of replacing strip parts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nest() now deducts placed counts from input NestItem.Quantity so the
UI loop doesn't create extra plates. All inner DefaultNestEngine.Fill
calls forward the IProgress parameter for live progress updates.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The auto-nest code paths (MainForm, MCP, Console) now call
engine.Nest(items, progress, token) instead of manually orchestrating
sequential fill+pack. The default implementation in NestEngineBase
does sequential FillExact+PackArea. StripNestEngine overrides with
its strip strategy. This makes the engine dropdown actually work.
Also consolidates ComputeRemainderWithin into NestEngineBase,
removing duplicates from MainForm and StripNestEngine.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New NestEngineBase subclass that dedicates a tight strip to the
largest-area drawing and fills the remnant with remaining drawings.
Tries both bottom and left orientations, uses a shrink loop to find
the tightest strip, and picks the denser result.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>