"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>
The GPU pair evaluator reported false-positive overlaps for all
candidates because the bitmap coordinate system didn't account for
Part.CreateAtOrigin's Location offset. When rotation produced negative
coordinates, CreateAtOrigin sets Location = -bbox.Location (non-zero),
but the offset formula assumed Location was always (0,0).
Two fixes:
- Rasterize bitmaps from Part.CreateAtOrigin directly (new FromPart
method) instead of separately rotating polygons and computing bbox,
eliminating any Polygon.Rotate vs Program.Rotate mismatch
- Correct offset formula to include the Location shift:
(Part2Offset - partB.Location) instead of raw Part2Offset
Also optimized post-kernel bounding computation: pre-compute vertices
once per rotation group and process results with Parallel.For, matching
the CPU evaluator's concurrency.
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>
Move DxfImporter, DxfExporter, NestReader, NestWriter, ProgramReader,
and Extensions into a new OpenNest.IO class library. The WinForms project
now references OpenNest.IO instead of ACadSharp directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The GPU bitmap evaluator produces false overlap detections due to
discretization errors at cell boundaries. Use the CPU PairEvaluator
(exact geometric intersection) for now. Also remove the double-counted
spacing dilation from GpuPairEvaluator for when GPU is revisited.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add PushDirection.Right and PushDirection.Up to RotationSlideStrategy so
parts can approach from all four directions. This discovers concave
interlocking arrangements (e.g. L-shaped parts nesting into each other's
cavities) that the original Left/Down-only slides could never reach.
Introduce BestFitCache so best-fit results are computed once at step size
0.25 and shared between the viewer and nesting engine. The GPU evaluator
factory is configured once at startup instead of being wired per call
site, and NestEngine.CreateEvaluator is removed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add LineTypeName to Layer and propagate resolved color/line-type
through all DXF entity conversions (Arc, Circle, Line, Spline,
Polyline, LwPolyline, Ellipse). Entities that inherit ByLayer
properties now correctly resolve to their layer's values.
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>
Add per-entity IsVisible flag and wire up the Colors and Line Types
checkedlistboxes to filter entities by exclusion — checking an item
hides matching entities from the preview and from drawing export.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GPU factory logic belongs with the GPU implementation, not the UI.
Changed from internal to public and updated namespace to OpenNest.Gpu.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move BuildPairParts to BestFitResult.BuildParts() instance method
- Extract BinConverter (RectanglePacking) for Part/NestItem/Bin conversions
- Extract RotationAnalysis for FindBestRotation and FindHullEdgeAngles
NestEngine reduced from 484 to 287 lines — now purely orchestration,
strategy selection, and comparison logic.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- GpuEvaluatorFactory probes for CUDA/OpenCL devices at startup
- Status bar shows "GPU : <device name>" (green) or "GPU : None (CPU)" (gray)
- Factory skips GPU evaluator creation entirely when no device found
- Logs actual exception message on failure for debugging
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>
ActionClone.Fill() now computes the largest open rectangle from the
cursor position (trying both vertical and horizontal) and passes it
to the engine, so fills no longer overlap existing parts.
Pattern fills try all convex hull edge angles to find the rotation
that maximizes part count.
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>
Merge ActionAddPart into ActionClone by adding a Drawing constructor,
eliminating the redundant class. ActionClone now handles both adding
new parts from a drawing and cloning selected part groups. Added
Ctrl+F fill support for groups using FillLinear pattern tiling, and
adopted quadrant-aware push directions from ActionAddPart. Refactored
FillLinear to extract shared helpers and add a Fill(Pattern) overload
for tiling arbitrary part groups across the work area.
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>
ProgramReader treats 'E' as a code letter, so values like
"6.66E-08" get split into X:"6.66" and E:"-08", corrupting
the parsed coordinate. Use fixed-point format string instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SetRotation always forced CW regardless of the requested rotation,
so cutouts (which should be CCW for kerf-left) were also set to CW.
Now uses the rotation parameter to set the correct winding direction.
Also reverts the Shape.OffsetEntity cutout side inversion since the
correct fix is proper winding from the converter.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Toggles offset geometry visualization from the View menu, matching
the existing Draw Rapids and Draw Bounds menu pattern.
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>
Parts now push based on actual cut geometry instead of bounding boxes,
allowing irregular shapes to nestle together with PartSpacing gap.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move all projects from Source/ to repository root for simpler navigation.
- Remove External/ dependency DLLs (will use NuGet packages)
- Remove Installer/ NSIS script
- Replace PartCollection/PlateCollection with ObservableList
- Add packages.config for NuGet dependencies
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>