Commit Graph
100 Commits
Author SHA1 Message Date
ajandClaude Sonnet 4.6 f83df3a55a test: add PartClassifier unit tests for all shape types
Covers all 9 cases: pure rectangle, rounded rectangle, rect with notch,
circle, L-shape, triangle, serrated edge (perimeter ratio), tilted rect
(primary angle), and empty drawing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 22:12:40 -04:00
ajandClaude Sonnet 4.6 84ad39414a feat: add PartClassifier with rectangle/circle/irregular detection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 22:09:33 -04:00
ajandClaude Opus 4.6 fdb4a2373a fix: simplify Shape.OffsetOutward winding normalization and sync designer
OffsetOutward now normalizes to CW winding before offsetting instead of
trial-and-error with bounding box comparison. CadConverterForm designer
regenerated with new entityView1 properties.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:01:46 -04:00
ajandClaude Opus 4.6 3a0267c041 chore: add docs/ to gitignore and remove tracked superpowers docs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:01:20 -04:00
ajandClaude Opus 4.6 036f723876 fix: update PlateView fill path and sync stats with preview
- Route best-result updates to progress form preview in
  PlateView.FillWithProgress (Ctrl+F path) — was still using
  the old SetStationaryParts approach
- Only update results stats (parts, density, area) when
  IsOverallBest so they match the preview display

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:56:41 -04:00
ajandClaude Opus 4.6 21a5d3b026 feat: route best-result updates to progress form preview
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 19:59:51 -04:00
ajandClaude Opus 4.6 0607c6c7c5 feat: add UpdatePreview method and PreviewPlate property
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 19:58:47 -04:00
ajandClaude Opus 4.6 c8cfeb3c6b feat: add SplitContainer and PlateView to NestProgressForm layout
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 19:57:12 -04:00
ajandClaude Opus 4.6 d4f424f274 refactor: simplify FillExtents with PartPair record and FillLinear delegation
Replace verbose value tuple with named PartPair record struct, extract
AnchorToWorkArea/PairBbox helpers to eliminate duplication, and delegate
RepeatColumns to FillLinear.Fill which already handles geometry-aware
column tiling with overlap fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 19:16:16 -04:00
ajandClaude Opus 4.6 028b1fabfc fix: move bend line action links above list for more vertical space
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 18:32:53 -04:00
aj a7c2fcffe6 test: add edge case tests for Collision; update CLAUDE.md 2026-03-29 09:43:31 -04:00
aj b834813889 refactor: delegate Part.Intersects to Collision.Check 2026-03-29 09:41:40 -04:00
ajandClaude Sonnet 4.6 4fa6100722 test: add hole subtraction and batch collision tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 09:40:28 -04:00
ajandClaude Opus 4.6 8f2fbee02c feat: add Collision static class with Sutherland-Hodgman clipping and tests
Polygon-polygon collision detection using convex decomposition (ear-clipping
triangulation) followed by Sutherland-Hodgman clipping on each triangle pair.
Handles overlapping, non-overlapping, edge-touching, containment, and concave
polygons. Includes hole subtraction support for future use.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:35:41 -04:00
ajandClaude Opus 4.6 230a11d32e feat: add CollisionResult data class for polygon collision detection
Immutable result type that holds overlap flag, overlap regions (as polygons),
intersection points, and computed overlap area.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:32:51 -04:00
ajandClaude Opus 4.6 953429dae9 fix: add overlap safety check and diagnostics to FillGrid Step 2
FillGrid had no overlap check after perpendicular tiling of the row
pattern (Step 2), unlike Step 1 which had one. When geometry-aware
FindPatternCopyDistance underestimated row spacing, overlapping parts
were returned unchecked.

Changes:
- Make FillLinear.HasOverlappingParts shape-aware (bbox pre-filter +
  Part.Intersects) instead of bbox-only, preventing false positives on
  interlocking pairs while catching real overlaps
- Add missing overlap safety check after Step 2 perpendicular tiling
  with bbox fallback
- Add diagnostic Debug.WriteLine logging when overlap fallback triggers,
  including engine label, step, direction, work area, spacing, pattern
  details, and overlapping part locations/rotations for reproduction
- Add FillLinear.Label property set at all callsites for log traceability
- Refactor LinearFillStrategy and ExtentsFillStrategy to use shared
  FillHelpers.BestOverAngles helper for angle-sweep logic

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 22:08:38 -04:00
ajandClaude Opus 4.6 1c2b569ff4 fix: eliminate endpoint gaps in EllipseConverter arc output
EllipseConverter computed arc radius from start point only, causing
~0.0009 unit gaps between consecutive arcs. Use circumcircle of
(start, mid, end) points so both endpoints lie exactly on the arc.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:37:01 -04:00
ajandClaude Opus 4.6 048b10a1e9 refactor: deduplicate BestFitHorizontal and BestFitVertical
Extract shared BestFitAxis helper parameterized by orientation,
eliminating 23-line duplicate in rectangle packing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:23:08 -04:00
ajandClaude Opus 4.6 3022982f6d refactor: consolidate HasOverlappingParts into FillHelpers
StripeFiller and FillExtents had identical 24-line overlap detection
methods; move to FillHelpers and delegate from both callers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:22:00 -04:00
ajandClaude Opus 4.6 cc85493a0c refactor: deduplicate EvenlyDistribute horizontal and vertical
Extract shared EvenlyDistribute helper parameterized by axis,
eliminating 27-line duplicate between the two methods.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:20:01 -04:00
ajandClaude Opus 4.6 3da287cdc0 refactor: extract generic MergePass from GeometryOptimizer
The arc and line Optimize methods had identical merge-loop structure;
extract a generic MergePass helper with type-specific delegates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:19:04 -04:00
ajandClaude Opus 4.6 d1a701a7f7 refactor: move shared GetRectangle to Action base class
Both ActionSelect and ActionZoomWindow had identical 29-line
GetRectangle methods; consolidate into the common base class.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:16:00 -04:00
ajandClaude Opus 4.6 17f786c9e8 refactor: delegate Program.Rotate(angle) to Rotate(angle, origin)
The parameterless rotation is equivalent to rotating around (0,0),
so delegate to the origin overload to eliminate 30-line duplicate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:14:51 -04:00
ajandClaude Opus 4.6 b7a8e2662c refactor: deduplicate FillHorizontal and FillVertical in FillEndOdd
Extract shared FillAxis helper parameterized by orientation,
eliminating 34-line duplicate between horizontal and vertical fills.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:13:00 -04:00
ajandClaude Opus 4.6 912a47c5e8 refactor: extract shared ArcFit utilities from SplineConverter and GeometrySimplifier
Move identical FitWithStartTangent and MaxRadialDeviation methods
to a shared ArcFit class, eliminating 40-line duplicate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:11:47 -04:00
ajandClaude Opus 4.6 a85213a524 refactor: deduplicate SortColumnsByHeight and SortRowsByWidth
Extract shared SortStrips helper parameterized by axis selectors,
eliminating 61-line near-duplicate between column and row sorting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:05:54 -04:00
ajandClaude Opus 4.6 fb696aaf58 refactor: remove dead code and deduplicate SpatialQuery
Remove 4 unused ClosestDistance methods and extract shared
FindVerticalLimits/FindHorizontalLimits helpers from the
GetLargestBox methods, eliminating 6 duplicate code groups.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:03:27 -04:00
ajandClaude Opus 4.6 d854a1f5d2 fix: use arc joins at convex corners in offset geometry
Convex corners were being miter-joined (lines extended to a point)
because IntersectsUnbounded always finds an intersection for non-parallel
lines. Now checks the cross product of original line directions to detect
convex corners and inserts an arc instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:53:20 -04:00
ajandClaude Opus 4.6 abc707f1d9 fix: allow line-on-line contact and remove extra spacing gap
- Part.Intersects: filter intersection points at a vertex of either
  shape (was both), so edge-touching parts are not flagged as overlapping
- NestEngineBase.HasOverlaps: use epsilon-based bounding box pre-filter
  consistent with FillExtents and Plate.HasOverlappingParts
- PartGeometry.GetOffsetPartLines: remove extra chordTolerance added to
  spacing offset — was causing 0.002" gap beyond the intended part spacing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:36:35 -04:00
ajandClaude Opus 4.6 61b917c398 chore: remove docs/superpowers and add to gitignore
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:48:59 -04:00
ajandClaude Opus 4.6 e3e51611d5 fix: only remove bend-generated etch entities, preserve user etch lines
UpdateEtchEntities was removing all entities on the ETCH layer, which
also deleted user-added etch marks like part numbers. Now tags generated
bend etch lines with a BendEtch tag and filters on that instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:47:26 -04:00
ajandClaude Opus 4.6 8104bd3626 feat: rotate bend labels parallel to bend line and center them
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:36:10 -04:00
ajandClaude Opus 4.6 ae262b8a77 feat: add scrollbar and arrow key navigation to FileListControl
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:53:36 -04:00
ajandClaude Opus 4.6 afbbc9ed79 feat: improve EntityView labels for circles and small entities
Place circle labels on the circumference using golden angle distribution
so concentric circles don't overlap. Hide labels when the entity is too
small on screen to fit the badge.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 10:05:32 -04:00
ajandClaude Opus 4.6 6071e6fa14 refactor: remove Plate menu Fill and Fill Area items replaced by Ctrl+F
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 09:54:15 -04:00
ajandClaude Opus 4.6 afdd386456 feat: add entity index labels toggle to EntityView and CadConverterForm
Labels are drawn at each entity's midpoint with a filled background
circle for readability. Toggle via "Labels" checkbox in the detail bar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 09:49:07 -04:00
ajandClaude Opus 4.6 2db8c49838 feat: add etch mark entities from bend lines to CNC program pipeline
Etch marks for up bends are now real geometry entities on an ETCH layer
instead of being drawn dynamically. They flow through the full pipeline:
entities → FilterPanel layers → ConvertGeometry (tagged as Scribe) →
post-processor sequencing before cut geometry.

Also includes ShapeProfile normalization (CW perimeter, CCW cutouts)
applied consistently across all import paths, and inward offset support
for cutout shapes in overlap/offset polygon calculations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 00:42:49 -04:00
ajandClaude Opus 4.6 80e8693da3 fix: add overlap detection safety net for pair tiling
Shape.OffsetOutward produces inward offsets for certain rotated polygons,
causing geometry-aware copy distances to be too small and placing
overlapping parts. Root cause is in the offset winding direction
detection — this commit adds safety nets while that is investigated.

- FillLinear.FillGrid: detect bbox overlaps after geometry-aware tiling,
  fall back to bbox-based spacing when overlaps found
- FillExtents.RepeatColumns: detect overlaps after Compactor computes
  copy distance, fall back to columnWidth + spacing
- PairFiller/StripeFiller remnant fills: use FillLinear directly instead
  of spawning full engine pipeline (avoids strategies with the bug)
- Add PairOverlapDiagnosticTests reproducing the issue
- MCP config: use shadow-copy wrapper for dev hot-reload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 23:52:50 -04:00
ajandClaude Opus 4.6 d7eb3ebd7a fix: skip aspect ratio rejection when best-fit utilization is high
High-utilization pairs (>=75%) are no longer discarded for exceeding
the aspect ratio limit, since the material isn't being wasted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:15:45 -04:00
aj 4404d3a5d0 feat: add OpenNest.Data machine configuration system 2026-03-27 20:30:55 -04:00
ajandClaude Sonnet 4.6 d27dee3db9 feat: add MachineConfigForm editor with tree navigation and MainForm menu integration
Wires the OpenNest.Data layer into the UI: adds project reference, creates MachineConfigForm (tree-based editor for machines/materials/thicknesses with import/export), and adds Tools > Machine Configuration... menu item.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 20:27:44 -04:00
ajandClaude Sonnet 4.6 7081c7b4d0 feat: add embedded CL-980 default config with first-run EnsureDefaults
Embeds CL-980.json as a resource in OpenNest.Data and adds EnsureDefaults()
to LocalJsonProvider, which seeds the machines directory on first run when empty.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 20:23:00 -04:00
ajandClaude Sonnet 4.6 a6e813bc85 feat: add IDataProvider interface and LocalJsonProvider with JSON file CRUD
One JSON file per machine named by GUID, stored in a configurable directory.
Supports save, load, list (as summaries), and delete with IO-error retry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 20:19:56 -04:00
ajandClaude Opus 4.6 98453243fc feat: add MachineConfig, MaterialConfig, MachineSummary with parameter lookup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 20:16:59 -04:00
aj 64874857a1 feat: add LeadConfig, CutOffConfig, and ThicknessConfig data models 2026-03-27 20:14:39 -04:00
aj 5d3fcb2dc8 feat: add OpenNest.Data project with MachineType and UnitSystem enums 2026-03-27 20:13:54 -04:00
ajandClaude Opus 4.6 ae9a63b5ce feat: add Parts/Groups tabs with editable material, thickness, and per-group plate sizes
- Parts tab: shows all BOM items, editable Material/Thickness for
  matched rows, grayed-out rows for items without DXF files
- Groups tab: auto-computed from parts with editable Plate Width/Length
  per material+thickness group
- Editing Material/Thickness on Parts tab immediately re-groups
- Per-group plate sizes preserved across re-groups

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:50:06 -04:00
ajandClaude Opus 4.6 596328148d fix: correct dock z-order so Fill control gets remaining space
Fill must be at index 0 (front) so it's processed last by the
docking layout engine. Edge docks at higher indices process first.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:07:32 -04:00
ajandClaude Opus 4.6 6cd48a623d fix: use fixed height for input group instead of AutoSize
AutoSize with Dock.Fill child causes circular sizing and collapses
the GroupBox. Use fixed Height=200 instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:04:43 -04:00
ajandClaude Opus 4.6 42243c7df0 fix: rewrite BomImportForm layout using TableLayoutPanel for DPI safety
Replaced absolute-positioned controls with TableLayoutPanel in the input
section and Dock-based layout for bottom buttons. Fixes controls being
hidden at non-100% DPI scaling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:58:50 -04:00
ajandClaude Opus 4.6 4b10d4801c fix: correct dock order and make BomImportForm resizable
- Add Fill control last so edge-docked controls get space first
- Remove stale hardcoded Location on bottom panel
- Switch to Sizable border with MinimumSize so user can resize

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:55:18 -04:00
ajandClaude Opus 4.6 f0bdaa14e6 fix: increase BomImportForm size and enable font auto-scaling
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:50:23 -04:00
ajandClaude Opus 4.6 79ddce346b fix: move mnuFileImportBom construction before AddRange to avoid null reference
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:47:05 -04:00
ajandClaude Opus 4.6 20777541c0 fix: address review findings — MdiParent conflict, null guard, Drawing.Material
- Fix critical: use MdiParentForm (custom property) instead of MdiParent
  (WinForms property) in ImportBom_Click to avoid InvalidOperationException
- Add null guard in CreateNests_Click
- Set Drawing.Material from BOM group
- Move DxfImporter creation outside loop
- Improve summary label text with reason descriptions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:40:18 -04:00
aj 7c8168b002 feat: add 'Import BOM...' menu item to MainForm File menu 2026-03-27 17:35:48 -04:00
ajandClaude Sonnet 4.6 203bd4eeea feat: add BomImportForm nest creation logic
Task 9: CreateNests_Click validates plate dimensions, then for each
MaterialGroup creates a Nest with name '{job} - {thickness} {material}',
sets PlateDefaults (size, thickness, material, quadrant=1, spacing),
imports each matched DXF via DxfImporter, converts entities to Program
with leading RapidMove offset handling (same pattern as CadConverterForm),
sets Quantity.Required from BOM qty, then opens an EditNestForm for each
nest that has drawings. Summary MessageBox reports count and import errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 17:34:15 -04:00
ajandClaude Sonnet 4.6 02d15dea9c feat: add BomImportForm file browsing and analysis logic
Task 8: BrowseBom_Click auto-fills DXF folder and derives job name by
stripping ' BOM' suffix; BrowseDxf_Click opens folder browser;
Analyze_Click reads BOM via BomReader, runs BomAnalyzer, populates
DataGridView with material/thickness/parts/qty columns, updates summary
label with skipped/unmatched counts, and enables Create Nests button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 17:33:39 -04:00
ajandClaude Sonnet 4.6 a88937b716 feat: add BomImportForm designer layout and shell
Task 7: WinForms dialog for BOM import with Input groupbox (job name,
BOM file, DXF folder, plate size, Analyze button), Material Groups
DataGridView, and bottom panel (summary label, Create Nests, Close).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 17:33:13 -04:00
ajandClaude Sonnet 4.6 986a0412b1 feat: add BomAnalyzer — groups BOM items by material+thickness and matches DXFs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 17:28:45 -04:00
ajandClaude Sonnet 4.6 e7f2ee80e2 test: add BomAnalyzer tests (red — implementation pending)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 17:27:24 -04:00
aj 31063d954d feat: add Fraction parsing utility for BOM descriptions 2026-03-27 17:24:55 -04:00
aj fc1fee54cd feat: add BomItem model and BomReader Excel parser 2026-03-27 17:24:43 -04:00
aj 094b522644 feat: add ColumnAttribute and CellExtensions for BOM parsing 2026-03-27 17:24:15 -04:00
ajandClaude Opus 4.6 45dea4ec2b chore: add ClosedXML NuGet package to OpenNest.IO for BOM import
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:23:41 -04:00
aj 743bb25f7b chore: add EPPlus NuGet package to OpenNest.IO for BOM import 2026-03-27 17:19:34 -04:00
ajandClaude Opus 4.6 a34811bb6d fix: address review findings — input validation, exception handling, cleanup
Add argument validation to EllipseConverter.Convert for tolerance and
semi-axis parameters. Narrow bare catch in Extensions.cs spline method
to log via Debug.WriteLine. Remove unused lineCount variable from
SolidWorksBendDetectorTests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:34:13 -04:00
ajandClaude Opus 4.6 9b460f77e5 test: add DXF import integration test for ellipse-to-arc conversion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:32:14 -04:00
ajandClaude Opus 4.6 85bf779f21 feat: wire up EllipseConverter and SplineConverter in DXF import pipeline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:24:58 -04:00
ajandClaude Opus 4.6 641c1cd461 feat: add SplineConverter with tangent-chained arc fitting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:16:12 -04:00
ajandClaude Opus 4.6 4a5ed1b9c0 feat: add EllipseConverter arc fitting with normal-constrained G1 continuity
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:01:55 -04:00
ajandClaude Opus 4.6 c40941ed35 feat: add EllipseConverter evaluation helpers with tests
Add EllipseConverter static class with foundational methods for converting
ellipse parameters to circular arcs: EvaluatePoint, EvaluateTangent,
EvaluateNormal, and IntersectNormals. All 8 unit tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:50:06 -04:00
ajandClaude Opus 4.6 d6184fdc8f docs: add implementation plan for direct arc conversion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:47:13 -04:00
ajandClaude Opus 4.6 d61ec1747a docs: add design spec for direct spline/ellipse to arc conversion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:39:10 -04:00
ajandClaude Opus 4.6 7b815c9579 feat: auto-detect simplifiable geometry in CAD converter
When a file is loaded, a background task analyzes the entities for
simplification candidates and highlights the Simplify button with a
count when candidates are found. Button resets after simplification
is applied.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:15:05 -04:00
ajandClaude Opus 4.6 5568789902 feat: add fill strategy enable/disable settings in options
OptionsForm now shows checkboxes for each fill strategy, persisted via
the new DisabledStrategies user setting. FillStrategyRegistry exposes
AllStrategies and DisabledNames for the UI. MainForm applies disabled
strategies on startup via OptionsForm.ApplyDisabledStrategies().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:14:10 -04:00
ajandClaude Opus 4.6 fd93cc9db2 test: add engine and strategy overlap tests, update stripe filler tests
New EngineOverlapTests verifies all engine types produce overlap-free
results. New StrategyOverlapTests checks each fill strategy individually.
StripeFillerTests updated to verify returned parts are overlap-free
rather than just asserting non-empty results. Remove obsolete FitCircle
tests from GeometrySimplifierTests (method was removed).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:13:47 -04:00
ajandClaude Opus 4.6 740fd79adc fix: add overlap validation guards to FillExtents and StripeFiller
FillExtents falls back to the unadjusted column when iterative pair
adjustment shifts parts enough to cause genuine overlap. StripeFiller
rejects grid results where bounding boxes overlap, which can occur when
angle convergence produces slightly off-axis rotations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:13:35 -04:00
ajandClaude Opus 4.6 e1b6752ede fix: improve overlap detection to ignore touch points and add bounding box pre-filtering
Part.Intersects now filters out intersection points that coincide with
vertices of both perimeters (shared corners/endpoints), which are touch
points rather than actual crossings. Plate.HasOverlappingParts adds a
bounding box pre-filter requiring overlap region to exceed Epsilon in
both dimensions before performing expensive shape intersection checks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:13:21 -04:00
ajandClaude Opus 4.6 18d9bbadfa refactor: extract SimplifierViewerForm designer file
Convert SimplifierViewerForm to partial class with standard WinForms
designer pattern. UI controls are now defined in the .Designer.cs file
with InitializeComponent(), enabling visual designer support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:11:12 -04:00
ajandClaude Opus 4.6 e27def388f fix: geometry simplifier arc connectivity and ellipse support
Three bugs prevented the simplifier from working on ellipse geometry:

1. Sweep angle check blocked initial fit — the 5-degree minimum sweep
   was inside TryFit(), killing candidates before the extension loop
   could accumulate enough segments. Moved to TryFitArcAt() after
   extension.

2. Layer reference equality split runs — entities from separate DXF
   ellipses had different Layer object instances for the same layer "0",
   splitting them into independent runs. Changed to compare Layer.Name.

3. Symmetrize replaced arcs with mirrored copies whose endpoints didn't
   match the target's original geometry, creating ~0.014 gaps. Now only
   applies mirrored arcs when endpoints are within tolerance of the
   target's boundary points.

Also: default tolerance 0.02 -> 0.004, Export DXF button in
CadConverterForm for debugging simplified geometry.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:49:27 -04:00
ajandClaude Opus 4.6 356b989424 feat: mirror axis simplifier, bend note propagation, ellipse fixes
Geometry Simplifier:
- Replace least-squares circle fitting with mirror axis algorithm
  that constrains center to perpendicular bisector of chord, guaranteeing
  zero-gap endpoint connectivity by construction
- Golden section search optimizes center position along the axis
- Increase default tolerance from 0.005 to 0.5 for practical CNC use
- Support existing arcs in simplification runs (sample arc points to
  find larger replacement arcs spanning lines + arcs together)
- Add tolerance zone visualization (offset original geometry ±tolerance)
- Show original geometry overlay with orange dashed lines in preview
- Add "Original" checkbox to CadConverter for comparing old vs new
- Store OriginalEntities on FileListItem to prevent tolerance creep
  when re-running simplifier with different settings

Bend Detection:
- Propagate bend notes to collinear bend lines split by cutouts
  using infinite-line perpendicular distance check
- Add bend note text rendering in EntityView at bend line midpoints

DXF Import:
- Fix trimmed ellipse closing chord: only close when sweep ≈ 2π,
  preventing phantom lines through slot cutouts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:27:46 -04:00
ajandClaude Opus 4.6 c6652f7707 fix: remove 0 from nest name encoding and padding
Use chars.Length instead of hardcoded 36 for modulus/division since
the character set excludes 0 and O. Pad with '2' (first valid char)
instead of '0' to avoid ambiguity.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:11:09 -04:00
ajandClaude Opus 4.6 df008081d1 fix: persist simplified entities back to FileListItem
Without this, simplified geometry was lost on file switch and
not included in the final GetDrawings output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 23:50:07 -04:00
ajandClaude Opus 4.6 0a294934ae feat: integrate geometry simplifier into CadConverterForm
Add "Simplify..." button to the detail bar and wire up SimplifierViewerForm
as a tool window with lazy creation, positioning, and entity replacement on apply.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 23:44:10 -04:00
ajandClaude Opus 4.6 f711a2e4d6 feat: add SimplifierViewerForm tool window
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 23:41:37 -04:00
ajandClaude Opus 4.6 a4df4027f1 feat: add simplifier highlight and preview rendering to EntityView
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 23:37:45 -04:00
ajandClaude Opus 4.6 278bbe54ba feat: add GeometrySimplifier.Apply to replace lines with arcs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 23:35:08 -04:00
ajandClaude Opus 4.6 ca5eb53bc1 feat: add GeometrySimplifier.Analyze with incremental arc fitting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 23:30:10 -04:00
ajandClaude Opus 4.6 bbc02f6f3f feat: add ArcCandidate and Kasa circle fitting
Foundation for the geometry simplifier that will replace consecutive line
segments with fitted arcs. Adds ArcCandidate data class, GeometrySimplifier
with stub Analyze/Apply methods, and FitCircle using the Kasa algebraic
least-squares method. Also adds InternalsVisibleTo for OpenNest.Tests on
OpenNest.Core.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 23:22:05 -04:00
ajandClaude Opus 4.6 12173204d1 fix: prevent etch line layers from defaulting to layer 0 after split
DxfImporter now filters ETCH entities (like BEND) since etch marks are
generated from bends during export, not cut geometry. GeometryOptimizer
no longer merges lines/arcs across different layers and preserves layer
and color on merged entities. EntityView draws etch marks directly from
the Bends list so they remain visible without relying on imported ETCH
entities.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:31:28 -04:00
ajandClaude Opus 4.6 cbabf5e9d1 refactor: extract shared feature utilities and sub-program registry from CincinnatiPostProcessor
Consolidate duplicated static methods (SplitFeatures, ComputeCutDistance,
IsFeatureEtch, feature ordering) from CincinnatiSheetWriter and
CincinnatiPartSubprogramWriter into a shared FeatureUtils class. Move
inline sub-program registry building from Post() into
CincinnatiPartSubprogramWriter.BuildRegistry().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:54:04 -04:00
ajandClaude Opus 4.6 1aac03c9ef feat: add resizable split between sidebar and viewer in CadConverterForm
Wrap the left sidebar and right entity view in a SplitContainer so the
boundary can be dragged to resize. Fixed panel on the left with a 200px
minimum width.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:45:28 -04:00
ajandClaude Opus 4.6 f46bcd4e4b feat: add filter toggle to remnant viewer for showing all remnants
The remnant viewer previously always filtered by smallest part dimension,
hiding large remnants that were narrower than the smallest part. Added a
"Filter by part size" checkbox (on by default) so users can toggle this
off to see all remnants regardless of size.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:39:03 -04:00
ajandClaude Opus 4.6 f29f086080 feat: add pierce point visualization and rename shape dimensions to Length/Width
Add toggleable pierce point drawing to PlateView that shows small red
filled circles at each rapid move endpoint (where cutting begins). Wire
through View menu, EditNestForm toggle, and MainForm handler.

Also rename RectangleShape/RoundedRectangleShape Width/Height to
Length/Width for consistency with CNC conventions, update MCP tools and
tests accordingly. Fix SplitDrawingForm designer layout ordering and
EntityView bend line selection styling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:26:49 -04:00
ajandClaude Opus 4.6 19001ea5be fix: prevent GeometryOptimizer from merging semicircular arcs into invalid arc
After splitting a drawing with a circular hole, CadConverterForm writes
the split piece to DXF and re-imports it. The circle (decomposed into
two semicircular arcs by DrawingSplitter) was being incorrectly merged
back into a single zero-sweep arc by GeometryOptimizer.TryJoinArcs
during reimport.

Root cause: TryJoinArcs mutated input arc angles in-place and didn't
guard against merging two arcs that together form a full circle. When
arc2 had startAngle=π, endAngle=0 (DXF wrap-around from 360°→0°), the
mutation produced startAngle=-π, and the merge created an arc with
startAngle=π, endAngle=π (zero sweep), losing half the hole.

Fix: use local variables instead of mutating inputs, require arcs to be
adjacent (endpoints touching) rather than just overlapping, and refuse
to merge when the combined sweep would be a full circle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 20:34:38 -04:00
ajandClaude Opus 4.6 269746b8a4 feat: fit-to-plate splits use full plate work area with preview line
FitToPlate now places split lines at usable-width intervals so each
piece (except the last) fills the entire plate work area. Also adds a
live yellow preview line that follows the cursor during manual split
line placement, and piece dimension labels in the preview regions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 19:27:15 -04:00
ajandClaude Sonnet 4.6 35218a7435 feat: wire manual bend line pick → dialog → promote flow in CadConverterForm
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 18:38:12 -04:00
ajandClaude Sonnet 4.6 bd973c5f79 feat: add 'Add Bend Line' toggle and pick mode UI to FilterPanel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 18:36:40 -04:00
ajandClaude Sonnet 4.6 d042bd1844 feat: add bend line pick mode with hit-testing to EntityView
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 18:35:30 -04:00
ajandClaude Sonnet 4.6 ebdd489fdc feat: add BendLineDialog for manual bend line property entry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 18:34:14 -04:00