feat(io): add DWG file import support via ACadSharp DwgReader

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 <noreply@anthropic.com>
This commit is contained in:
2026-04-27 22:58:26 -04:00
parent 9d58e6fba8
commit 1c994718fb
7 changed files with 39 additions and 14 deletions
+4 -3
View File
@@ -151,7 +151,8 @@ static class NestConsole
f.EndsWith(NestFormat.FileExtension, StringComparison.OrdinalIgnoreCase) f.EndsWith(NestFormat.FileExtension, StringComparison.OrdinalIgnoreCase)
|| f.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)); || f.EndsWith(".zip", StringComparison.OrdinalIgnoreCase));
var dxfFiles = options.InputFiles.Where(f => 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 we have a nest file, load it and optionally add DXFs.
if (nestFile != null) if (nestFile != null)
@@ -187,7 +188,7 @@ static class NestConsole
// DXF-only mode: create a fresh nest. // DXF-only mode: create a fresh nest.
if (dxfFiles.Count == 0) 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; return null;
} }
@@ -461,7 +462,7 @@ static class NestConsole
Console.Error.WriteLine("Usage: OpenNest.Console <input-files...> [options]"); Console.Error.WriteLine("Usage: OpenNest.Console <input-files...> [options]");
Console.Error.WriteLine(); Console.Error.WriteLine();
Console.Error.WriteLine("Arguments:"); 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();
Console.Error.WriteLine("Modes:"); Console.Error.WriteLine("Modes:");
Console.Error.WriteLine(" <nest.nest> Load nest and fill (existing behavior)"); Console.Error.WriteLine(" <nest.nest> Load nest and fill (existing behavior)");
+7 -2
View File
@@ -42,6 +42,11 @@ namespace OpenNest.IO.Bom
var nameWithoutExt = Path.GetFileNameWithoutExtension(file); var nameWithoutExt = Path.GetFileNameWithoutExtension(file);
dxfFiles[nameWithoutExt] = 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) // Partition items into: skipped, unmatched, or matched (grouped)
@@ -57,8 +62,8 @@ namespace OpenNest.IO.Bom
var lookupName = item.FileName; 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); lookupName = Path.GetFileNameWithoutExtension(lookupName);
if (!folderExists) if (!folderExists)
+19 -4
View File
@@ -27,8 +27,7 @@ namespace OpenNest.IO
/// </summary> /// </summary>
public static DxfImportResult Import(string path) public static DxfImportResult Import(string path)
{ {
using var reader = new DxfReader(path); var doc = ReadDocument(path);
var doc = reader.Read();
return new DxfImportResult return new DxfImportResult
{ {
@@ -41,8 +40,7 @@ namespace OpenNest.IO
{ {
try try
{ {
using var reader = new DxfReader(path); var doc = ReadDocument(path);
var doc = reader.Read();
return ConvertEntities(doc); return ConvertEntities(doc);
} }
catch (Exception ex) catch (Exception ex)
@@ -113,6 +111,23 @@ namespace OpenNest.IO
#region Private #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<Entity> ConvertEntities(CadDocument doc) private static List<Entity> ConvertEntities(CadDocument doc)
{ {
var entities = new List<Entity>(); var entities = new List<Entity>();
+4 -2
View File
@@ -89,8 +89,10 @@ int RunDataCollection(string dir, string dbPath, string saveDir, double s, strin
new Size(48, 24), new Size(120, 10) new Size(48, 24), new Size(120, 10)
}; };
var dxfFiles = Directory.GetFiles(dir, "*.dxf", SearchOption.AllDirectories); var dxfFiles = Directory.GetFiles(dir, "*.dxf", SearchOption.AllDirectories)
Console.WriteLine($"Found {dxfFiles.Length} DXF files"); .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"; var resolvedDb = dbPath.EndsWith(".db", StringComparison.OrdinalIgnoreCase) ? dbPath : dbPath + ".db";
Console.WriteLine($"Database: {Path.GetFullPath(resolvedDb)}"); Console.WriteLine($"Database: {Path.GetFullPath(resolvedDb)}");
Console.WriteLine($"Sheet sizes: {sheetSuite.Length} configurations"); Console.WriteLine($"Sheet sizes: {sheetSuite.Length} configurations");
+2 -1
View File
@@ -165,7 +165,8 @@ namespace OpenNest.Forms
else else
{ {
var lookupName = item.FileName; 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); lookupName = Path.GetFileNameWithoutExtension(lookupName);
if (matchedPaths.TryGetValue(lookupName, out var dxfPath)) if (matchedPaths.TryGetValue(lookupName, out var dxfPath))
+2 -1
View File
@@ -473,7 +473,8 @@ namespace OpenNest.Forms
{ {
var files = (string[])e.Data.GetData(DataFormats.FileDrop); var files = (string[])e.Data.GetData(DataFormats.FileDrop);
var dxfFiles = files.Where(f => 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) if (dxfFiles.Length > 0)
AddFiles(dxfFiles); AddFiles(dxfFiles);
} }
+1 -1
View File
@@ -329,7 +329,7 @@ namespace OpenNest.Forms
{ {
var dlg = new OpenFileDialog(); var dlg = new OpenFileDialog();
dlg.Multiselect = true; 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) if (dlg.ShowDialog() != DialogResult.OK)
return; return;