Replace expensive ShrinkFiller re-fill loop with axis-aware edge-sorted
trim. Also replaces blind Take(N) in DefaultNestEngine.Fill.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add drawing dropdown to switch between drawings without reopening the
form. Change color scheme to light backgrounds with blue/red part fills
and auto-detect text color. Fix swapped bounding box width/length. Run
best-fit computation on a background thread so the UI stays responsive
during long calculations, with cancellation on drawing switch.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add third row (5x3 grid, 15 items/page), remove 50-result cap so all
candidates are pageable, start maximized, replace page label with
editable textbox for direct page entry, center nav controls, and
eliminate flicker on page change via DoubleBuffered + WM_SETREDRAW.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CloneAtOffset shares the Program instance for tiling performance,
but rotating a part on the plate mutated the shared Program, causing
all parts from the same tile template to rotate together.
Added ownsProgram flag with EnsureOwnedProgram() that clones the
Program before first mutation, preserving tiling performance while
making user rotations independent.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The documented entries (info.json, drawing-info.json, plate-info.json,
plate-NNN) were from the old v1 format. Updated to reflect the actual v2
structure: nest.json, programs/program-N, and bestfits/bestfit-N.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PairFiller now returns PairFillResult (Parts + BestFits) instead of
using a mutable BestFits property. Extracted EvaluateCandidates,
TryReduceWorkArea, and BuildTilingAngles for clarity. Simplified the
candidate loop by leveraging FillScore comparison semantics.
Removed FillRemainingStrip and all its helpers (FindPlacedEdge,
BuildRemainingStrip, BuildRotationSet, FindBestFill, TryFewerRows,
RemainderPatterns) from FillLinear — these were a major bottleneck in
strip nesting, running expensive fills on undersized remnant strips.
ShrinkFiller + RemnantFiller already handle space optimization, making
the remainder strip fill redundant.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
StripNestEngine was passing progress directly to DefaultNestEngine.Fill
inside the ShrinkFiller loop, causing every per-angle/per-strategy report
to update the UI with overlapping layouts in the same work area.
Now inner fills are silent (null progress) and ShrinkFiller reports its
own progress when the best layout improves. IterativeShrinkFiller tracks
placed parts across items and includes them in reports. The trial box is
reported before the fill starts so the work area border updates immediately.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Draw only one set of preview parts at a time — active (current strategy)
takes precedence over stationary (overall best). Also clears active
parts when setting new stationary parts to prevent stale previews.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the first pair candidate places more parts than needed (e.g., 17
when target is 10), sort by BoundingBox.Top, trim from the top until
exactly targetCount remain, and use that Top as the new work area
height. All subsequent candidates fill this smaller area, dramatically
reducing fill time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a target count is known, ShrinkFiller now uses FillBestFit (fast
rectangle packing) to estimate how many parts fit on the full area,
then scales the shrink axis proportionally to avoid an expensive
full-area fill. Falls back to full box if estimate is too aggressive.
Also shrinks to targetCount (not full count) to produce tighter boxes
when fewer parts are needed than the area can hold.
IterativeShrinkFiller passes NestItem.Quantity as the target count.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PairEvaluator already computes OptimalRotation via RotatingCalipers on
the pair's convex hull, but PairFiller.EvaluateCandidate only passed
hull edge angles to FillPattern. Now includes the optimal rotation
angle (and +90°) so tiling can use the mathematically tightest fit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both types were only used internally by the old StripNestEngine.Nest
strip-orientation logic, which has been replaced by IterativeShrinkFiller.
No references remain outside of these files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the old orientation-based strip nesting (TryOrientation,
SelectStripItemIndex, EstimateStripDimension, ShrinkFill helpers) with
a call to IterativeShrinkFiller.Fill for multi-quantity items, plus a
RemnantFinder-based PackArea pass for singles and leftovers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces IterativeShrinkFiller.Fill, which composes RemnantFiller and
ShrinkFiller by wrapping the caller's fill function in a closure that tries
both ShrinkAxis.Height and ShrinkAxis.Width and picks the better FillScore.
Adds IterativeShrinkResult (Parts + Leftovers). Covers null/empty inputs and
single-item placement with three passing xUnit tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Includes fix for unlimited qty items (Quantity <= 0) that
RemnantFiller.FillItems silently skips. Workaround: convert
to estimated max capacity before passing in.
Also removes caliper angle sections from spec — RotationAnalysis
already feeds the caliper angle via FindBestRotation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Kept using OpenNest.Api in Timing.cs and EditNestForm.cs alongside
remote's reorganized usings and namespace changes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- NestRunner now assigns Material to plates from request.Material
- NestResponse.LoadAsync uses descriptive exceptions instead of null-forgiving operators
- Fix pre-existing FillExtents.Fill signature mismatch (add bestFits parameter)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Stateless orchestrator that takes a NestRequest and returns a NestResponse.
Imports DXFs, builds NestItems, runs the engine in a multi-plate loop until
all parts are placed, computes timing, and returns utilization metrics.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds NestResponse type to OpenNest.Api with SaveAsync/LoadAsync for .nestquote format — a ZIP containing request.json, response.json (metrics), and an embedded nest.nest.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a Write(Stream) overload that writes the ZIP archive to any stream
with leaveOpen: true so the caller can read back a MemoryStream after
the ZipArchive is disposed. Refactors Write(string) to delegate to the
new overload.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Relocates CutParameters from OpenNest namespace to OpenNest.Api, adds
LeadInLength and PostProcessor properties, and provides a typed Default
factory. Updates Timing.cs, the WinForms project reference, and the three
consuming forms to resolve the type from the new namespace.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Design for OpenNest.Api project providing a stateless NestRequest/NestResponse
facade over the engine, IO, and timing layers. Includes CutParameters unification,
multi-plate loop, .nestquote persistence format, and .opnest → .nest rename.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move PlateViews and labels to designer file so they show in VS.
Fix nest orientation by swapping Box(Width,Length) to Box(Length,Width)
matching plate convention (Length=X, Width=Y). Add ComboBox Format
handler to show Drawing.Name. Zoom to fit after moving parts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Replace SetTemporaryParts/ClearTemporaryParts/AcceptTemporaryParts in all
three progress callbacks (RunAutoNest, FillPlate, FillArea) with the new
two-bucket API: SetStationaryParts for IsOverallBest updates,
SetActiveParts for transient updates, AcceptPreviewParts(parts) and
ClearPreviewParts for completion. Also removes the now-redundant
highWaterMark guards from FillPlate_Click and FillArea_Click.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace single temporaryParts list with stationaryParts (overall best,
full opacity) and activeParts (current strategy, reduced opacity).
Update SetPlate, Refresh, UpdateMatrix, DrawParts, and FillWithProgress
accordingly. Replace SetTemporaryParts/ClearTemporaryParts/AcceptTemporaryParts
with SetStationaryParts/SetActiveParts/ClearPreviewParts/AcceptPreviewParts.
Co-Authored-By: Claude Sonnet 4.6 <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>
Promotes btnRemovePlate to a field and toggles Enabled based on
plate count in add/remove event handlers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DensityBar: clamp rounded rect radius for small fill widths to avoid
GDI+ artifacts at very low density values.
PhaseStepperControl: use float arithmetic for circle spacing to
handle DPI-scaled widths evenly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6-task plan covering PhaseStepperControl, DensityBar, form rewrite,
color-coded flash & fade, Accept/Stop buttons, and caller changes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase stepper, grouped panels, density sparkline bar,
color-coded flash & fade, and Accept/Stop buttons.
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>
Replace single preview PlateView with two stacked previews showing
horizontal and vertical FillLinear results. Each has a label showing
the part count. Apply uses the direction with more parts.
Co-Authored-By: Claude Opus 4.6 (1M context) <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>
Add FileExtension and FileFilter constants to NestFormat and update all
references across Console, MCP, Training, and WinForms projects.
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>