feat(io): conservative opt-in bend repair with tests and console CLI

Add OpenNest.IO/Bending/BendRepair: opt-in repair of unambiguous paired
ETCH/SCRIBE bend ticks, bounded to <=3.175 mm endpoint movement with
explicit source units. Cut geometry is never modified.

- CadImportOptions.BendRepair configures it; CadImportResult exposes
  per-bend BendRepairReports; CadImporter/Dxf wire it into import.
- Console: --repair-bends-mm <limit> --cad-units inches|mm prints
  per-bend reports for newly imported DXFs.
- New OpenNest.IO.Tests project (net8.0, synthetic DXFs, 30 tests)
  covering bend detection and repair, added to the solution.
- Update README.md and CLAUDE.md for the new pipeline and build/test
  instructions.
This commit is contained in:
aj
2026-09-20 15:22:46 -04:00
parent 1a05391d94
commit 589d341455
14 changed files with 589 additions and 22 deletions
+15
View File
@@ -35,8 +35,11 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenNest.Data", "OpenNest.Data\OpenNest.Data.csproj", "{A0B4B48E-1DF0-4DD3-B42C-B9B7779EA8B0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenNest.Benchmark", "OpenNest.Benchmark\OpenNest.Benchmark.csproj", "{ACD8F725-829A-48A8-AA59-61DD90DE06CA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenNest.Engine.Tests", "OpenNest.Engine.Tests\OpenNest.Engine.Tests.csproj", "{F2EF39E0-1A95-4C32-B50B-3D71EC72F692}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenNest.IO.Tests", "OpenNest.IO.Tests\OpenNest.IO.Tests.csproj", "{BA93522B-8A93-4689-A850-D042483964B9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -227,6 +230,18 @@ Global
{F2EF39E0-1A95-4C32-B50B-3D71EC72F692}.Release|x64.Build.0 = Release|Any CPU
{F2EF39E0-1A95-4C32-B50B-3D71EC72F692}.Release|x86.ActiveCfg = Release|Any CPU
{F2EF39E0-1A95-4C32-B50B-3D71EC72F692}.Release|x86.Build.0 = Release|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Debug|x64.ActiveCfg = Debug|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Debug|x64.Build.0 = Debug|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Debug|x86.ActiveCfg = Debug|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Debug|x86.Build.0 = Debug|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Release|Any CPU.Build.0 = Release|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Release|x64.ActiveCfg = Release|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Release|x64.Build.0 = Release|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Release|x86.ActiveCfg = Release|Any CPU
{BA93522B-8A93-4689-A850-D042483964B9}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE