Enables a "move" workflow: clone parts to a new position, then
press Delete to remove the originals. Previously Delete just
cancelled the clone action.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ObservableList.Remove fired ItemRemoved even when the item wasn't in
the list, causing Plate to decrement Quantity.Nested for clone preview
parts that were never added — producing -1 counts. Delete in PlateView
now cancels ActionClone instead of trying to remove its preview parts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Material and thickness are properties of the nest (all plates share the
same material/gauge), not individual plates. This moves them to the Nest
class, removes them from Plate and PlateSettings, and updates the UI so
EditNestInfoForm has a material field while EditPlateForm no longer shows
thickness. The nest file format gains top-level thickness/material fields
with backward-compatible reading from PlateDefaults for old files.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a "Draw Cut Direction" toggle to the View menu that draws small
arrowheads along cutting paths to indicate the direction of travel.
Arrows are placed on both linear and arc moves, spaced ~60px apart,
and correctly follow CW/CCW arc tangents.
Extract all rendering methods (~660 lines) from PlateView into a new
PlateRenderer class, reducing PlateView from 1640 to 979 lines.
PlateView retains input handling, selection, zoom, and part management.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The approach rapid from sheet origin was drawing to part.Location (the
program coordinate origin) then a second rapid to the actual first
pierce point. This created a dog-leg through the part origin instead
of a single straight rapid to the lead-in. Also fixed PlateProcessor
using the original program's start point instead of the processed one
when the cutting strategy is applied on-the-fly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Refresh PlateView preview with settled parts after Compactor.Settle
so the accepted layout matches what was shown, not the pre-settle
positions from the last progress report.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Route best-result updates to progress form preview in
PlateView.FillWithProgress (Ctrl+F path) — was still using
the old SetStationaryParts approach
- Only update results stats (parts, density, area) when
IsOverallBest so they match the preview display
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Etch marks for up bends are now real geometry entities on an ETCH layer
instead of being drawn dynamically. They flow through the full pipeline:
entities → FilterPanel layers → ConvertGeometry (tagged as Scribe) →
post-processor sequencing before cut geometry.
Also includes ShapeProfile normalization (CW perimeter, CCW cutouts)
applied consistently across all import paths, and inward offset support
for cutout shapes in overlap/offset polygon calculations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add toggleable pierce point drawing to PlateView that shows small red
filled circles at each rapid move endpoint (where cutting begins). Wire
through View menu, EditNestForm toggle, and MainForm handler.
Also rename RectangleShape/RoundedRectangleShape Width/Height to
Length/Width for consistency with CNC conventions, update MCP tools and
tests accordingly. Fix SplitDrawingForm designer layout ordering and
EntityView bend line selection styling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Select cut-offs by clicking their lines instead of a grip point.
Drag is axis-constrained with live regeneration during movement.
Selected cut-off highlighted with bright blue 3.5px line.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Regenerate cut-off programs after RotateSelectedParts so cut lines
update when parts are rotated, not just moved
- Change default CutDirection from TowardOrigin to AwayFromOrigin so
cuts start at the origin axis
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add DrawCutOffs and DrawCutOffGrip methods to PlateView for rendering
cut-off lines and selection grip handles. Includes CutOffSettings and
SelectedCutOff properties, plus GetCutOffAtPoint for hit-testing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
RotateSelectedParts was calling Program.Rotate() directly on shared
Program instances, bypassing Part's copy-on-write (EnsureOwnedProgram).
Parts created via CloneAtOffset share the same Program, so rotating one
part would rotate all parts with the same reference.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Compactor.Settle and AutoNester.Optimize post-passes to
NestEngineBase.Nest, StripNestEngine, and PlateView.FillWithProgress
so all fill paths benefit from geometry-aware compaction.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add SelectionChanged event to PlateView and display the selected part's
location and size in a new status bar label. Shows combined bounding box
when multiple parts are selected.
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>
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>
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>
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>
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>
Size.Parse and ToString now use WxL format (width first) matching the
natural convention. Fixed the Plate(w,l) constructor which was swapping
args when creating Size. Fixed PlateView.DrawPlate and DrawControl
ZoomToArea which had width/length mapped to the wrong screen axes.
Simplified Console --size parsing to use Size.TryParse instead of manual
split with confusing PlateHeight/PlateWidth fields. Added Command-Line
Interface section to README documenting all console options.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a toolbar button that opens a dockable remnant viewer showing
tiered remnants (priority, size, area, location) with color-coded
overlay rendering on the plate view.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Parts created by fill operations share a Program instance via
CloneAtOffset. RotateSelectedParts called Part.Rotate on each,
compounding Program.Rotate on the shared object (1x, 2x, 3x…)
and producing inconsistent bounding boxes. Fix tracks rotated
programs with a HashSet, rotates locations around the group center,
and anchors the bounding box corner to prevent drift.
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>
Moving BasePart locations via Compactor.Push bypassed LayoutPart.Offset
which sets IsDirty. Without it, graphics paths were stale until a zoom
triggered a full rebuild.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PushSelected now calls Compactor.Push instead of duplicating the push
logic. Compactor.Push moves parts as a group (single min distance) to
preserve grid layouts. Compact tries both left-first and down-first
orderings, iterating up to 20 times until movement drops below
threshold, and keeps whichever ordering traveled further.
Also includes a cancellation check in FillWithProgress to avoid
accepting parts after the user stops a nest.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract direction helpers to Helper class (EdgeDistance, DirectionalGap,
DirectionToOffset, IsHorizontalDirection) and use them to skip parts not
ahead in the push direction or further than the current best distance.
Defer line computation until parts survive bounding box checks.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cache offset polygon geometry on LayoutPart so DrawOffset no longer
recomputes the expensive offset pipeline every paint cycle. The costly
OffsetEntity/ToPolygonWithTolerance/RemoveSelfIntersections chain now
runs only when rotation, spacing, or tolerance actually changes.
Also update temporary parts in UpdateMatrix() so preview parts during
nesting scale correctly with zoom.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Moves async fill+progress orchestration into PlateView so ActionClone's
Ctrl+F fill shows the NestProgressForm dialog.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
"Length" is more natural than "height" for flat plate materials.
Renames the field on OpenNest.Geometry.Size, Box.Height property,
and all references across 38 files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add bounding box rejection in HasOverlaps to skip expensive
Part.Intersects (CNC→geometry conversion) for non-adjacent parts.
Eliminates ~35% CPU in IsBetterValidFill for grid layouts.
- Optimize RayEdgeDistance: access Line fields directly instead of
property getters (avoids Vector struct copies), inline IsEqualTo
with direct range comparison (avoids Math.Abs), and precompute
deltas for reuse in interpolation.
- Cache line endpoints in DirectionalDistance outer loop to avoid
repeated struct copies in the inner loop.
- Add fill timer to ActionClone.Fill, displayed in PlateView status
bar as "Fill: N parts in M ms".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- F key triggers ZoomToFit; Ctrl+F passes through for ActionClone fill
- Middle-button double-click ZoomToFit skipped when parts are selected
to avoid conflicting with middle-click 90° rotation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded PushChordTolerance constant with a configurable
OffsetTolerance property on PlateView (default 0.001), giving smoother
arc profiles in offset drawing and push-to-part collision detection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract a BestFitCell subclass from PlateView for the Best-Fit Viewer
grid cells. Text metadata is now painted in screen coordinates (after
resetting the graphics transform) so it stays fixed regardless of zoom.
Parts auto-zoom to fit on every resize.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pressing Escape from ActionSelect now restores the previous action
(e.g. ActionClone) instead of staying in Select mode. Adds
ConnectEvents() to the Action base class for action resume support.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SetPlate clears SelectedParts, which broke bounds drawing and rotation
for surviving actions. Add OnPlateChanged hook so ActionClone can
re-populate SelectedParts after a plate switch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SetPlate unconditionally reset the action to ActionSelect, clearing
the clone pattern when switching plates. Add SurvivesPlateChange
virtual property to Action base class so actions can opt in to
persisting across plate changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Polygon offset at concave corners creates geometry that folds back
through itself. Added RemoveSelfIntersections() to Polygon that
detects non-adjacent edge crossings and removes the smaller loop
at each crossing. Applied to both collision detection and rendering.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
RayEdgeDistance returned double.MaxValue for touching vertices (dist ≈ 0),
causing rays from other vertices to hit the far side of stationary parts
and allow movement through obstacles. Now returns 0 when touching so the
distance > 0 check in PushSelected correctly prevents further movement.
Added directional edge filtering using outward normals to discard
back-facing edges before ray checks, reducing line count by ~2/3.
DirectionalDistance now checks both StartPoint and EndPoint per line
to preserve vertices at filtered edge boundaries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows the offset geometry (PartSpacing buffer) around each part as a
semi-transparent red outline. Toggle via PlateView.DrawOffset property.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>