A tabbed cutout's slug stays attached while the sheet is cut, but nesting
saw a closed hole and could place parts inside it. Nesting and layout paths
now read material through NestingMaterial.ForNesting, which drops closed
contours with tab spans so the slug counts as part. That covers part
outlines and collision lines, the cutout router, fill expansion, best-fit,
NestLayoutCheck and the GPU bitmaps. Area, overlap diagnostics and cutting
keep the hole, and programs without tabs read exactly as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every nesting-geometry consumer filtered only rapids, so scribe/etch
moves counted as part material. An etch tick that ends a hair outside
the outline (PEP bend ticks start on the notch edge) made the part
"open geometry leaving the material region": the job validator threw
and every built-in engine plus Gpt6Astra crashed on real PEP jobs
(PT75, drawing 4980 A01 PT77). Marks are only on the surface, so they
should never affect placement, collision, area, or validation.
- SpecialLayers.IsMaterial excludes Rapid and Scribe; used by drawing
area, canonical angle, part collision, PartGeometry, plate perimeter,
best-fit/pair evaluation, rotation analysis, GPU evaluators, and both
validators. Timing, display, splitting and posts still see marks.
- ConvertGeometry also maps the saved SCRIBE layer name to Scribe, so
programs rebuilt from stored entities keep their marks.
- NestReader repairs older files (e.g. PepNestExport output) whose
programs saved etch as cut moves while source entities kept SCRIBE.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Repo-wide sweep with the pinned CSharpier 1.3.0 tool. Whitespace and
line-wrapping only; OpenNest.Engine.Tests (109) and OpenNest.IO.Tests
pass after reformat, full solution builds 0 errors.
Added .csharpierignore so csproj/config XML keeps its existing layout
(CSharpier's XML wrapping churns attributes with zero benefit).
Formatting is now enforceable: dotnet csharpier check . passes.
The GPU pair evaluator reported false-positive overlaps for all
candidates because the bitmap coordinate system didn't account for
Part.CreateAtOrigin's Location offset. When rotation produced negative
coordinates, CreateAtOrigin sets Location = -bbox.Location (non-zero),
but the offset formula assumed Location was always (0,0).
Two fixes:
- Rasterize bitmaps from Part.CreateAtOrigin directly (new FromPart
method) instead of separately rotating polygons and computing bbox,
eliminating any Polygon.Rotate vs Program.Rotate mismatch
- Correct offset formula to include the Location shift:
(Part2Offset - partB.Location) instead of raw Part2Offset
Also optimized post-kernel bounding computation: pre-compute vertices
once per rotation group and process results with Parallel.For, matching
the CPU evaluator's concurrency.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces the OpenNest.Gpu class library with ILGPU dependencies and a
PartBitmap class that rasterizes Drawing closed shapes into integer grids
for GPU-based overlap testing. Supports rotation and spacing dilation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>