From 1c994718fbcf70243e74e634511e71ae566e4d6c Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Mon, 27 Apr 2026 22:58:26 -0400 Subject: [PATCH] feat(io): add DWG file import support via ACadSharp DwgReader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ACadSharp already includes DwgReader, so this wires it up across the entire import pipeline — Dxf.Import, CadConverter drag-drop, nest import dialog, console CLI, BOM analyzer, and training data collector. Co-Authored-By: Claude Opus 4.6 --- OpenNest.Console/Program.cs | 7 ++++--- OpenNest.IO/Bom/BomAnalyzer.cs | 9 +++++++-- OpenNest.IO/Dxf.cs | 23 +++++++++++++++++++---- OpenNest.Training/Program.cs | 6 ++++-- OpenNest/Forms/BomImportForm.cs | 3 ++- OpenNest/Forms/CadConverterForm.cs | 3 ++- OpenNest/Forms/EditNestForm.cs | 2 +- 7 files changed, 39 insertions(+), 14 deletions(-) diff --git a/OpenNest.Console/Program.cs b/OpenNest.Console/Program.cs index 592a723..d3bc9e5 100644 --- a/OpenNest.Console/Program.cs +++ b/OpenNest.Console/Program.cs @@ -151,7 +151,8 @@ static class NestConsole f.EndsWith(NestFormat.FileExtension, StringComparison.OrdinalIgnoreCase) || f.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)); var dxfFiles = options.InputFiles.Where(f => - f.EndsWith(".dxf", StringComparison.OrdinalIgnoreCase)).ToList(); + f.EndsWith(".dxf", StringComparison.OrdinalIgnoreCase) || + f.EndsWith(".dwg", StringComparison.OrdinalIgnoreCase)).ToList(); // If we have a nest file, load it and optionally add DXFs. if (nestFile != null) @@ -187,7 +188,7 @@ static class NestConsole // DXF-only mode: create a fresh nest. if (dxfFiles.Count == 0) { - Console.Error.WriteLine("Error: no nest (.nest) or DXF (.dxf) files specified"); + Console.Error.WriteLine("Error: no nest (.nest) or CAD (.dxf/.dwg) files specified"); return null; } @@ -461,7 +462,7 @@ static class NestConsole Console.Error.WriteLine("Usage: OpenNest.Console [options]"); Console.Error.WriteLine(); Console.Error.WriteLine("Arguments:"); - Console.Error.WriteLine(" input-files One or more .nest nest files or .dxf drawing files"); + Console.Error.WriteLine(" input-files One or more .nest nest files or .dxf/.dwg drawing files"); Console.Error.WriteLine(); Console.Error.WriteLine("Modes:"); Console.Error.WriteLine(" Load nest and fill (existing behavior)"); diff --git a/OpenNest.IO/Bom/BomAnalyzer.cs b/OpenNest.IO/Bom/BomAnalyzer.cs index e630ec3..6873447 100644 --- a/OpenNest.IO/Bom/BomAnalyzer.cs +++ b/OpenNest.IO/Bom/BomAnalyzer.cs @@ -42,6 +42,11 @@ namespace OpenNest.IO.Bom var nameWithoutExt = Path.GetFileNameWithoutExtension(file); dxfFiles[nameWithoutExt] = file; } + foreach (var file in Directory.GetFiles(dxfFolder, "*.dwg")) + { + var nameWithoutExt = Path.GetFileNameWithoutExtension(file); + dxfFiles.TryAdd(nameWithoutExt, file); + } } // Partition items into: skipped, unmatched, or matched (grouped) @@ -57,8 +62,8 @@ namespace OpenNest.IO.Bom var lookupName = item.FileName; - // Strip .dxf extension if the BOM includes it - if (lookupName.EndsWith(".dxf", StringComparison.OrdinalIgnoreCase)) + if (lookupName.EndsWith(".dxf", StringComparison.OrdinalIgnoreCase) + || lookupName.EndsWith(".dwg", StringComparison.OrdinalIgnoreCase)) lookupName = Path.GetFileNameWithoutExtension(lookupName); if (!folderExists) diff --git a/OpenNest.IO/Dxf.cs b/OpenNest.IO/Dxf.cs index b60b147..5c2548c 100644 --- a/OpenNest.IO/Dxf.cs +++ b/OpenNest.IO/Dxf.cs @@ -27,8 +27,7 @@ namespace OpenNest.IO /// public static DxfImportResult Import(string path) { - using var reader = new DxfReader(path); - var doc = reader.Read(); + var doc = ReadDocument(path); return new DxfImportResult { @@ -41,8 +40,7 @@ namespace OpenNest.IO { try { - using var reader = new DxfReader(path); - var doc = reader.Read(); + var doc = ReadDocument(path); return ConvertEntities(doc); } catch (Exception ex) @@ -113,6 +111,23 @@ namespace OpenNest.IO #region Private + private static bool IsDwg(string path) => + Path.GetExtension(path).Equals(".dwg", StringComparison.OrdinalIgnoreCase); + + private static CadDocument ReadDocument(string path) + { + if (IsDwg(path)) + { + using var reader = new DwgReader(path); + return reader.Read(); + } + else + { + using var reader = new DxfReader(path); + return reader.Read(); + } + } + private static List ConvertEntities(CadDocument doc) { var entities = new List(); diff --git a/OpenNest.Training/Program.cs b/OpenNest.Training/Program.cs index c3cd6ed..b288a38 100644 --- a/OpenNest.Training/Program.cs +++ b/OpenNest.Training/Program.cs @@ -89,8 +89,10 @@ int RunDataCollection(string dir, string dbPath, string saveDir, double s, strin new Size(48, 24), new Size(120, 10) }; - var dxfFiles = Directory.GetFiles(dir, "*.dxf", SearchOption.AllDirectories); - Console.WriteLine($"Found {dxfFiles.Length} DXF files"); + var dxfFiles = Directory.GetFiles(dir, "*.dxf", SearchOption.AllDirectories) + .Concat(Directory.GetFiles(dir, "*.dwg", SearchOption.AllDirectories)) + .ToArray(); + Console.WriteLine($"Found {dxfFiles.Length} CAD files"); var resolvedDb = dbPath.EndsWith(".db", StringComparison.OrdinalIgnoreCase) ? dbPath : dbPath + ".db"; Console.WriteLine($"Database: {Path.GetFullPath(resolvedDb)}"); Console.WriteLine($"Sheet sizes: {sheetSuite.Length} configurations"); diff --git a/OpenNest/Forms/BomImportForm.cs b/OpenNest/Forms/BomImportForm.cs index 60fbca0..7218d85 100644 --- a/OpenNest/Forms/BomImportForm.cs +++ b/OpenNest/Forms/BomImportForm.cs @@ -165,7 +165,8 @@ namespace OpenNest.Forms else { var lookupName = item.FileName; - if (lookupName.EndsWith(".dxf", StringComparison.OrdinalIgnoreCase)) + if (lookupName.EndsWith(".dxf", StringComparison.OrdinalIgnoreCase) + || lookupName.EndsWith(".dwg", StringComparison.OrdinalIgnoreCase)) lookupName = Path.GetFileNameWithoutExtension(lookupName); if (matchedPaths.TryGetValue(lookupName, out var dxfPath)) diff --git a/OpenNest/Forms/CadConverterForm.cs b/OpenNest/Forms/CadConverterForm.cs index 7958bca..b069363 100644 --- a/OpenNest/Forms/CadConverterForm.cs +++ b/OpenNest/Forms/CadConverterForm.cs @@ -473,7 +473,8 @@ namespace OpenNest.Forms { var files = (string[])e.Data.GetData(DataFormats.FileDrop); var dxfFiles = files.Where(f => - f.EndsWith(".dxf", StringComparison.OrdinalIgnoreCase)).ToArray(); + f.EndsWith(".dxf", StringComparison.OrdinalIgnoreCase) || + f.EndsWith(".dwg", StringComparison.OrdinalIgnoreCase)).ToArray(); if (dxfFiles.Length > 0) AddFiles(dxfFiles); } diff --git a/OpenNest/Forms/EditNestForm.cs b/OpenNest/Forms/EditNestForm.cs index ab71d89..f45ba36 100644 --- a/OpenNest/Forms/EditNestForm.cs +++ b/OpenNest/Forms/EditNestForm.cs @@ -329,7 +329,7 @@ namespace OpenNest.Forms { var dlg = new OpenFileDialog(); dlg.Multiselect = true; - dlg.Filter = "DXF Files (*.dxf) | *.dxf"; + dlg.Filter = "CAD Files (*.dxf;*.dwg)|*.dxf;*.dwg|DXF Files (*.dxf)|*.dxf|DWG Files (*.dwg)|*.dwg"; if (dlg.ShowDialog() != DialogResult.OK) return;