Replace recursive FillRecursive with flat FillGrid that tiles along primary
axis, then perpendicular. Extract FindPlacedEdge, BuildRemainingStrip,
BuildRotationSet, FindBestFill helpers. Use array-based DirectionalDistance
to eliminate allocations in FindCopyDistance and FindPatternCopyDistance.
Simplify FindSinglePartPatternCopyDistance to delegate to FindCopyDistance.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Vector implements IEquatable<Vector> with proper GetHashCode for HashSet usage.
Polygon.FindCrossing uses bounding-box pruning to skip non-overlapping edge pairs.
Helper.DirectionalDistance deduplicates vertices via HashSet, sorts edges for
early-exit pruning, and adds a new array-based overload that avoids allocations.
PartBoundary sorts directional edges and exposes GetEdges for zero-alloc access.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Refactor flat top-level statements into NestConsole class with Options
and focused methods. Add support for passing .dxf files directly as
input — auto-imports geometry via DxfImporter and creates a fresh nest
with a plate when --size is specified. Supports three modes: nest-only,
DXF-only (requires --size), and mixed nest+DXF.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Linear phase shows "Linear: 12/36 angles, 45° = 48 parts" with a
running count. Pairs phase shows "Pairs: 8/50 candidates, best = 252
parts" tracking the best result seen so far. Reports on every
completion so the UI always reflects current state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Parallel loops were flooding the UI with per-angle/per-candidate reports
faster than WinForms could render them. Use Interlocked timestamp checks
to report at most every 150ms, keeping descriptions readable.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Don't overwrite the Detail label with phase-level reports — let the
per-angle and per-candidate descriptions from the parallel loops remain
visible. Only clear the label on completion.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ReportProgress was not setting Description, so the Detail row always
showed the default em-dash. Now each phase report includes a meaningful
description, and UpdateProgress always updates the label (resetting to
em-dash when null).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Mark _loadAttempted as volatile for correct double-checked locking
- Add Content item to copy Models/ directory to output for ONNX inference
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Design for training an XGBoost model to predict which rotation
angles are worth trying during FillLinear, reducing the 36-angle
sweep to 4-8 predicted angles in narrow-work-area cases.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move brute-force data collection, TrainingDatabase, and GPU init from
OpenNest.Console into a dedicated OpenNest.Training project. Replaces
raw Microsoft.Data.Sqlite with EF Core. Console is now a pure nesting
CLI with template support and cleaned-up usage output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds PerimeterToAreaRatio (perimeter / area) as a spacing sensitivity
indicator for ML feature extraction.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add FeatureExtractor for computing geometric part features (convexity,
aspect ratio, circularity, bitmask) and BruteForceRunner for generating
training data by running the fill engine and recording results.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show a live elapsed-time counter that updates every second during
nesting. Rename "Remnant" label to "Unused" for clarity.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Calculate unused plate area by subtracting total part area from the
work area instead of relying on FillScore.UsableRemnantArea, which
could over-report available space.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace shape-list iteration with ShapeProfile.Perimeter in both
Part.Intersects and PartBoundary, simplifying the logic and ensuring
only the outermost contour is used for collision detection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add G-code serialization via ToString() for debugging/ML workflows.
Fix Rotate(angle, origin) to propagate origin to sub-programs instead
of calling the single-argument overload.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add verbose per-file and per-sheet-size console output during collection
- Skip already-processed parts at the sheet-size level instead of all-or-nothing
- Precompute best-fits once per part and reuse across all sheet sizes
- Clear best-fit cache after each part to prevent memory growth
- Save best-fits in separate bestfits/ zip entries instead of embedding in nest.json
- Filter to Keep=true results only and scope to plate sizes in the nest
- Set nest name to match filename (includes sheet size and part count)
- Add TrainingDatabase with per-run skip logic and SQLite schema
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wire up GpuEvaluatorFactory in the Console app the same way the GUI app
does, so BestFitCache uses GPU-accelerated slide computation when a
CUDA/OpenCL device is detected.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Run pairs phase first to establish a baseline before linear and
rect-best-fit phases. Replace IsBetterFill with direct FillScore
comparison. Simplify FillPattern to sequential iteration, reusing a
single FillLinear engine instance.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Compute min/max bounds in a single pass alongside part area
accumulation, avoiding the separate GetBoundingBox() call and
redundant iteration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Store hull edge angles in BestFitResult at evaluation time so they
don't need to be recomputed during the fill phase. Extract
GetHullEdgeAngles(Polygon) overload from FindHullEdgeAngles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Offset-only copies don't modify program codes, so sharing the instance
avoids expensive cloning during large pattern tiling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace single scrollable grid with fixed 5x2 pages (10 items per page).
Add prev/next buttons and page label. Support Left/Right and PageUp/
PageDown keyboard navigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Thread ISlideComputer through BestFitCache → BestFitFinder →
RotationSlideStrategy. RotationSlideStrategy now collects all offsets
across 4 push directions and dispatches them in a single batch (GPU or
CPU fallback). Also improves rotation angle extraction: uses raw geometry
(line endpoints + arc cardinal extremes) instead of tessellation to avoid
flooding the hull with near-duplicate edge angles, and adds a 5-degree
deduplication threshold.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ISlideComputer abstracts batched directional-distance computation so GPU
implementations can process all slide offsets in a single kernel launch.
GpuSlideComputer uses ILGPU with prepared edge data (precomputed inverse
deltas and min/max bounds) and caches stationary/moving buffers across
calls. GpuEvaluatorFactory exposes a singleton factory method.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add primitive-parameter RayEdgeDistance overload with AggressiveInlining,
merge Left/Right and Up/Down cases. Add DirectionalDistance overload that
accepts (dx, dy) translation without creating Line objects, and FlattenLines
for packing segments into flat arrays for GPU transfer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Break deeply nested loop structure into focused helper methods,
reducing max nesting from 5 levels to 2. Uses GetRange/AddRange
for cleaner loop building.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address spec review issues: add third call site (Fill groupParts),
reuse ComputeCandidateRotations, fix step ordering for ToNestParts
before scoring, cap N to 500 and item.Quantity, clarify BoundingBox
is a property.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Spec for adding NFP-based placement as a competing strategy
in NestEngine.FindBestFill() for non-rectangular parts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Brings in the full NFP implementation: ConvexDecomposition, NoFitPolygon,
InnerFitPolygon, NfpCache, BottomLeftFill, SimulatedAnnealing optimizer,
and INestOptimizer interface. Resolves conflicts by keeping master's
progress reporting infrastructure alongside the new AutoNest methods,
and adapting RunAutoNest_Click to use NFP AutoNest with async/cancellation.
Co-Authored-By: Claude Opus 4.6 <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>
Avoids visual confusion with reserved UI colors (orange preview parts,
green/blue selection windows) by using a fixed 12-color palette that
skips those hue zones. Removes unused HSLColor and RandomColorGenerator.
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>