- 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>
After the main fill, detect if the last column/row is an "oddball"
with fewer parts than the main grid. If so, remove those parts and
re-fill the remainder strip independently using all strategies
(linear, rect best-fit, pairs). Improves 30→32 parts on the test
case (96x48 plate with 30x7.5 interlocking parts).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Narrow remnant strips now get more parts by:
- Sweeping rotations every 5° when the strip is narrower than the part
- Including all pairs that fit the strip width (not just top 50 by area)
- Placing individual parts from incomplete pattern copies that still fit
- Using finer polygon tolerance (0.01) for hull edge angle detection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract MakeSeedPattern for shared part creation, and replace the
two-step primary/perpendicular tiling with a single FillRecursive
method that tiles along one axis then recurses perpendicular.
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>
Extract offset polygon computation into PartBoundary, which builds
and caches inflated boundary polygons per unique part geometry.
FillLinear now uses symmetric half-spacing and reuses boundaries
across tiling passes, avoiding redundant offset calculations.
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>
- Fill(NestItem) and Fill(List<Part>) now delegate to their Box overloads
- Add Part.CreateAtOrigin() to replace repeated 4-line build-at-origin pattern
used in NestEngine, RotationSlideStrategy, and PairEvaluator
- Remove dead code: FillArea overloads, Fill(NestItem, int), FillWithPairs(NestItem),
ConvertTileResultToParts, PackBottomLeft.FindPointHorizontal, Pattern.GetLines/GetOffsetLines,
unused count variable in FillNoRotation
- Simplify IsBetterValidFill to delegate to IsBetterFill after overlap check
NestEngine reduced from 717 to 484 lines.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Consolidates two nearly-identical grid generation methods into a single
FillGrid method with a columnMajor parameter. Fixes bug in HPattern
where inner loop used rows instead of columns, and fixes FillNoRotation
silently discarding results by not adding them to Bin.Items.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
FindPatternCopyDistance now checks every pair of parts across adjacent
patterns so that multi-part patterns (e.g. interlocking pairs) maintain
correct spacing between ALL parts, not just the bounding boxes. The
original single-part logic is preserved as a fast path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove IsBetterValidFill overlap gate for FillLinear results; the
geometry-aware spacing in FillLinear is sufficient and the overlap
check produced false positives on parts with arcs/curves, causing
valid grid layouts to be rejected in favor of inferior pair fills.
- Add FillRectangleBestFit strategy that uses BestCombination to mix
normal and rotated orientations, filling remnant strips for higher
part counts on rectangular parts.
- All Fill overloads now compare linear, rectangle best-fit, and
pair-based strategies, picking whichever yields the most parts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The perpendicular sweep started at perpMin (e.g. -8.75) which with
coarse step sizes never landed on offset=0, missing the perfect
side-by-side and stacked same-orientation patterns for rectangular parts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Offset the moving shape's geometry by PartSpacing instead of adding
spacing linearly to the copy distance. This guarantees minimum clearance
in all directions for curved/complex shapes, not just along the slide axis.
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>
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>
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>