Show width x length and total part area on the "Nested:" row
in the nesting progress dialog, using the existing GetBoundingBox
extension to compute the extents.
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>
The BestFitFilter's aspect ratio cap of 5.0 was rejecting valid pair
candidates needed for narrow plates (e.g. 60x6.5, aspect 9.2) and
remainder strips on normal plates. Three fixes:
- BestFitFinder: derive MaxAspectRatio from the plate's own aspect
ratio so narrow plates don't reject all elongated pairs
- SelectPairCandidates: search the full unfiltered candidate list
(not just Keep=true) in strip mode, so pairs rejected by aspect
ratio for the main plate can still be used for narrow remainder
strips
- BestFitCache.Populate: skip caching empty result lists so stale
pre-computed data from nest files doesn't prevent recomputation
Also fixes console --size parsing to use LxW format matching
Size.Parse convention, and includes prior engine refactoring
(sequential fill loops, parallel FillPattern, pre-sorted edge
arrays in RotationSlideStrategy).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move NFP-based AutoNest logic (polygon extraction, rotation computation,
simulated annealing) into dedicated AutoNester class. Consolidate duplicate
FillWithPairs overloads, extract BuildCandidateAngles and BuildProgressSummary,
reorganize NestEngine into logical sections. Update callers in Console,
MCP tools, and MainForm to use AutoNester.Nest.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>