Commit Graph

281 Commits

Author SHA1 Message Date
62140789a7 feat: add Part.HasManualLeadIns flag
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 00:23:21 -04:00
ad877383ce feat: add CuttingResult struct
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 00:22:50 -04:00
b49cdc3e55 chore: add shared test helpers for Engine tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 00:21:26 -04:00
1e093a8413 chore: add OpenNest.Engine.Tests xUnit project
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 00:21:07 -04:00
79c6ec340c docs: add plate processor implementation plan
16 tasks covering test infrastructure, core model changes, part sequencing
(6 strategies + factory), rapid planning (2 strategies), and the PlateProcessor
orchestrator. TDD approach with xUnit tests for each component.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 00:17:37 -04:00
37c76a720d docs: address spec review feedback for plate processor design
Fix coordinate transforms (translate-only, no rotation), make orchestrator
non-destructive (ProcessedPart holds result instead of mutating Part.Program),
use readonly structs consistently, add factory mapping and known limitations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 23:55:16 -04:00
c06758a2bd docs: add plate processor design spec for per-part lead-in assignment
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 23:52:42 -04:00
026227848b docs: add plans for ML angle pruning, fill-exact, and helper decomposition
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 23:06:12 -04:00
5cd2875b35 chore(ui): regenerate MainForm designer file
Visual Studio re-serialized the designer — removes `this.` prefixes,
modernizes event handler syntax, trims trailing whitespace in resx.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 23:06:04 -04:00
5e346270c6 fix: delegate Fill(groupParts) and PackArea to DefaultNestEngine
StripNestEngine only overrode Fill(NestItem), so ActionClone.Fill
and Pack operations fell through to the empty base class defaults.
Now all virtual methods delegate to DefaultNestEngine.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:43:42 -04:00
5c79fbe73d feat(ui): add Auto Nest button to toolstrip next to engine selector
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:36:54 -04:00
4e747a8e6c fix: show strip + remnant parts together during progress updates
Wrap IProgress with AccumulatingProgress so remnant fills prepend
previously placed strip parts to each report. The UI now shows the
full picture (red + purple) instead of replacing strip parts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:31:11 -04:00
310165db02 fix: add quantity deduction and progress reporting to StripNestEngine
Nest() now deducts placed counts from input NestItem.Quantity so the
UI loop doesn't create extra plates. All inner DefaultNestEngine.Fill
calls forward the IProgress parameter for live progress updates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:26:29 -04:00
48be4d5d46 feat: add virtual Nest method to NestEngineBase for polymorphic auto-nest
The auto-nest code paths (MainForm, MCP, Console) now call
engine.Nest(items, progress, token) instead of manually orchestrating
sequential fill+pack. The default implementation in NestEngineBase
does sequential FillExact+PackArea. StripNestEngine overrides with
its strip strategy. This makes the engine dropdown actually work.

Also consolidates ComputeRemainderWithin into NestEngineBase,
removing duplicates from MainForm and StripNestEngine.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:16:08 -04:00
bb703ef8eb feat(ui): wire strip engine into UI auto-nest flow
When Strip is selected in the engine dropdown, RunAutoNest_Click
calls StripNestEngine.Nest() instead of sequential FillExact+Pack.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:09:29 -04:00
7462d1bdca feat(ui): add engine selector dropdown to main toolstrip
ToolStripComboBox populated from NestEngineRegistry.AvailableEngines.
Changing selection sets NestEngineRegistry.ActiveEngineName globally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:01:06 -04:00
cd85857816 feat: integrate StripNestEngine into autonest_plate MCP tool
Runs strip and sequential strategies in competition, picks the
denser result. Reports scores for both strategies in output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:40:21 -04:00
4d80710b48 feat: register StripNestEngine in NestEngineRegistry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:39:25 -04:00
42d404577b feat: add StripNestEngine with strip-based multi-drawing nesting
New NestEngineBase subclass that dedicates a tight strip to the
largest-area drawing and fills the remnant with remaining drawings.
Tries both bottom and left orientations, uses a shrink loop to find
the tightest strip, and picks the denser result.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:39:01 -04:00
81a57dc470 docs: update CLAUDE.md for abstract nest engine architecture
Document NestEngineBase hierarchy, NestEngineRegistry, and plugin
loading in the Engine section.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:12:53 -04:00
bd3984037c refactor: migrate WinForms callsites to NestEngineRegistry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:11:11 -04:00
01283d2b18 refactor: migrate Console Program to NestEngineRegistry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:10:10 -04:00
a26ab2ba28 refactor: migrate NestingTools to NestEngineRegistry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:09:46 -04:00
4baeb57e84 feat: add NestEngineInfo and NestEngineRegistry with plugin loading
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:07:59 -04:00
1bcfe5d031 feat: add NestEngineBase abstract class, rename NestEngine to DefaultNestEngine
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:06:28 -04:00
1d1cf41ba0 docs: update strip nester plan for abstract engine architecture
StripNester becomes StripNestEngine extending NestEngineBase.
Uses DefaultNestEngine internally via composition.
Registered in NestEngineRegistry.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:00:42 -04:00
9bd262dec0 docs: add abstract nest engine implementation plan
9 tasks across 4 chunks: NestEngineBase + DefaultNestEngine,
NestEngineRegistry + NestEngineInfo, callsite migration (16 sites),
verification and docs update.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 20:59:51 -04:00
068de63e83 docs: address spec review feedback for abstract nest engine
Fix MainForm callsite descriptions, clarify default implementations
return empty lists, make FillExact non-virtual, document PackArea
signature refactor, add AutoNester scope note, specify error handling
for plugin loading, document thread safety and instance lifetime.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 20:32:35 -04:00
6c2810ef80 docs: add abstract nest engine design spec
Pluggable engine architecture with NestEngineBase, DefaultNestEngine,
registry with plugin loading, and global engine switching.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 20:29:29 -04:00
7b01524934 docs: add strip nester implementation plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:53:11 -04:00
69da8c4632 docs: add strip nester design spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:40:09 -04:00
56a298d95c docs: update CLAUDE.md with current architecture
Reflects ~120 commits of changes: new projects (Console, Gpu, Training),
NFP best-fit pipeline, ML angle prediction, Compactor, CuttingStrategy,
JSON nest format, async progress/cancellation, and Helper decomposition
into focused classes (Intersect, ShapeBuilder, GeometryOptimizer,
SpatialQuery, PartGeometry, Rounding).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:56:35 -04:00
93bf15c27f chore: remove redundant using in Rounding.cs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:49:53 -04:00
e017723318 refactor: remove empty Helper class
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:46:36 -04:00
13b01240b1 refactor: extract SpatialQuery from Helper
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:46:14 -04:00
2881815c7a refactor: extract PartGeometry from Helper
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:44:17 -04:00
84d3f90549 refactor: extract Intersect from Helper
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:43:12 -04:00
7c4eac5460 refactor: extract ShapeBuilder from Helper
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:41:40 -04:00
be318bc1c1 refactor: extract GeometryOptimizer from Helper
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:39:52 -04:00
09cdb98dfc refactor: extract Rounding from Helper to OpenNest.Math
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:38:23 -04:00
823320e982 fix(engine): use reverse-gap check in Compactor to handle irregular shapes
The forward bounding-box gap check (gap < 0) incorrectly skipped obstacles
for irregular shapes like SULLYS-003 whose narrow handle extends past an
adjacent part's BB edge while the wide body still needs contact detection.
Replaced with a reverse-direction gap check that only skips obstacles the
moving part has entirely cleared. Also fixed edge distance check to prevent
overshooting the work area boundary when already at the limit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:29:29 -04:00
289a2044a6 fix(ui): mark LayoutParts dirty after PushSelected so paths rebuild
Moving BasePart locations via Compactor.Push bypassed LayoutPart.Offset
which sets IsDirty. Without it, graphics paths were stale until a zoom
triggered a full rebuild.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:20:18 -04:00
7508fbf715 refactor(engine): delegate PlateView.PushSelected to Compactor and add iterative compaction
PushSelected now calls Compactor.Push instead of duplicating the push
logic. Compactor.Push moves parts as a group (single min distance) to
preserve grid layouts. Compact tries both left-first and down-first
orderings, iterating up to 20 times until movement drops below
threshold, and keeps whichever ordering traveled further.

Also includes a cancellation check in FillWithProgress to avoid
accepting parts after the user stops a nest.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:16:35 -04:00
4525be302c fix(engine): compute remainder from just-placed parts within current work area
ComputeRemainderStrip used the bounding box of ALL plate parts against
the full plate, missing large interior gaps between drawing groups.
Now computes remainder within the current work area based on only the
parts that were just placed. This lets subsequent drawings fill the
gap between previous drawing groups instead of being forced into a
tiny strip at the plate edge.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:43:33 -04:00
2042c7d3f2 perf(engine): cap strip-mode pair candidates at 100 (sorted by utilization)
Strip mode was adding thousands of candidates (7600+) when the work area
was narrow. Now caps at 100 total, sorted by utilization descending so
the best candidates are tried first.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:35:30 -04:00
2af02096e0 fix(engine): pass progress through FillExact binary search iterations
The binary search was passing null for progress, so the NestProgressForm
showed all dashes during the entire search (potentially minutes). Now
each iteration reports progress — the user sees phases, part counts, and
density updating as the search runs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:30:39 -04:00
744062152e feat(engine): optimize FillExact with angle pruning and tight search range
- Track productive angles across Fill calls; subsequent fills skip
  angles that never produced results (knownGoodAngles)
- Binary search uses utilization-based range estimates (70%-25%)
  instead of starting from the full work area dimension
- Quick bounding-box capacity check skips binary search entirely
  when the plate can't fit more than the requested quantity
- Use full Fill (not rect-only) for binary search iterations so
  the search benefits from pairs/linear strategies

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:21:28 -04:00
ef12cf2966 fix(engine): Compactor treats pushed parts as obstacles for subsequent pushes
Previously each moving part only checked against the original stationary
set. Parts pushed earlier in the loop were invisible to later parts,
causing overlaps (utilization > 100%). Now each pushed part is added to
the obstacle set so subsequent parts collide correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 12:54:25 -04:00
56592f909a feat(mcp): use FillExact + Compactor in autonest_plate
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 12:43:41 -04:00
521ada17cc feat(console): use FillExact + Compactor in --autonest
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 12:43:38 -04:00