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>
Fill(NestItem) now uses actual part geometry instead of bounding boxes.
Also fixes Fill(NestItem, maxCount) which previously threw NotImplementedException.
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>
Cutouts wind opposite to the perimeter, so using the same OffsetSide
expands holes instead of shrinking them. Invert the side for cutouts
so the offset buffer correctly contracts holes inward.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Polygon chords are always inside the actual arc, making the offset
boundary smaller than intended. Add PushChordTolerance to the offset
distance so the polygon conservatively overestimates, ensuring the
real offset geometry never overlaps stationary parts.
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>
Add SegmentsForTolerance(double) to Arc and Circle that calculates the
minimum segments needed to keep sagitta within the given tolerance.
Add Shape.ToPolygonWithTolerance() that uses it per arc/circle.
Push distance now uses 0.08" chord tolerance instead of a fixed segment
count, giving appropriate resolution for each arc based on its radius.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ToPolygon() defaults to 1000 segments per arc, causing ~33k line
segments and O(n*m) slowdown. Use 36 segments (10° resolution) which
is more than sufficient for push distance accuracy.
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>
Replace bounding-box push with analytical polygon directional-distance
so parts nestle together based on actual cut geometry.
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>