refactor: merge DxfImporter and DxfExporter into single static Dxf class
Consolidated two stateless classes into one unified API: Dxf.Import(), Dxf.GetGeometry(), Dxf.ExportPlate(), Dxf.ExportProgram(). Export state moved into a private ExportContext. Removed bool+out pattern from GetGeometry in favor of returning empty list on failure. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,14 +25,13 @@ public static class NestRunner
|
|||||||
|
|
||||||
// 1. Import DXFs → Drawings
|
// 1. Import DXFs → Drawings
|
||||||
var drawings = new List<Drawing>();
|
var drawings = new List<Drawing>();
|
||||||
var importer = new DxfImporter();
|
|
||||||
|
|
||||||
foreach (var part in request.Parts)
|
foreach (var part in request.Parts)
|
||||||
{
|
{
|
||||||
if (!File.Exists(part.DxfPath))
|
if (!File.Exists(part.DxfPath))
|
||||||
throw new FileNotFoundException($"DXF file not found: {part.DxfPath}", part.DxfPath);
|
throw new FileNotFoundException($"DXF file not found: {part.DxfPath}", part.DxfPath);
|
||||||
|
|
||||||
if (!importer.GetGeometry(part.DxfPath, out var geometry) || geometry.Count == 0)
|
var geometry = Dxf.GetGeometry(part.DxfPath);
|
||||||
|
if (geometry.Count == 0)
|
||||||
throw new InvalidOperationException($"Failed to import DXF: {part.DxfPath}");
|
throw new InvalidOperationException($"Failed to import DXF: {part.DxfPath}");
|
||||||
|
|
||||||
var normalized = ShapeProfile.NormalizeEntities(geometry);
|
var normalized = ShapeProfile.NormalizeEntities(geometry);
|
||||||
|
|||||||
@@ -241,17 +241,11 @@ static class NestConsole
|
|||||||
|
|
||||||
static Drawing ImportDxf(string path)
|
static Drawing ImportDxf(string path)
|
||||||
{
|
{
|
||||||
var importer = new DxfImporter();
|
var geometry = Dxf.GetGeometry(path);
|
||||||
|
|
||||||
if (!importer.GetGeometry(path, out var geometry))
|
|
||||||
{
|
|
||||||
Console.Error.WriteLine($"Error: failed to read DXF file: {path}");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (geometry.Count == 0)
|
if (geometry.Count == 0)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine($"Error: no geometry found in DXF file: {path}");
|
Console.Error.WriteLine($"Error: failed to read DXF file or no geometry found: {path}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,378 @@
|
|||||||
|
using ACadSharp;
|
||||||
|
using ACadSharp.IO;
|
||||||
|
using CSMath;
|
||||||
|
using OpenNest.CNC;
|
||||||
|
using OpenNest.Geometry;
|
||||||
|
using OpenNest.Math;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace OpenNest.IO
|
||||||
|
{
|
||||||
|
using AcadArc = ACadSharp.Entities.Arc;
|
||||||
|
using AcadCircle = ACadSharp.Entities.Circle;
|
||||||
|
using AcadLine = ACadSharp.Entities.Line;
|
||||||
|
using Layer = ACadSharp.Tables.Layer;
|
||||||
|
|
||||||
|
public static class Dxf
|
||||||
|
{
|
||||||
|
#region Import
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Imports a DXF file, returning both converted entities and the raw CadDocument
|
||||||
|
/// for bend detection. The CadDocument is NOT disposed — caller can use it for
|
||||||
|
/// additional analysis (e.g., MText extraction for bend notes).
|
||||||
|
/// </summary>
|
||||||
|
public static DxfImportResult Import(string path)
|
||||||
|
{
|
||||||
|
using var reader = new DxfReader(path);
|
||||||
|
var doc = reader.Read();
|
||||||
|
|
||||||
|
return new DxfImportResult
|
||||||
|
{
|
||||||
|
Entities = ConvertEntities(doc),
|
||||||
|
Document = doc
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Entity> GetGeometry(string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var reader = new DxfReader(path);
|
||||||
|
var doc = reader.Read();
|
||||||
|
return ConvertEntities(doc);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine(ex.Message);
|
||||||
|
return new List<Entity>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Entity> GetGeometry(Stream stream)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var reader = new DxfReader(stream);
|
||||||
|
var doc = reader.Read();
|
||||||
|
return ConvertEntities(doc);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine(ex.Message);
|
||||||
|
return new List<Entity>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Export
|
||||||
|
|
||||||
|
public static void ExportProgram(Program program, string path)
|
||||||
|
{
|
||||||
|
using var stream = File.Create(path);
|
||||||
|
ExportProgram(program, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ExportProgram(Program program, Stream stream)
|
||||||
|
{
|
||||||
|
var ctx = new ExportContext();
|
||||||
|
ctx.AddProgram(program);
|
||||||
|
|
||||||
|
using var writer = new DxfWriter(stream, ctx.Document, false);
|
||||||
|
writer.Write();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ExportPlate(Plate plate, string path)
|
||||||
|
{
|
||||||
|
using var stream = File.Create(path);
|
||||||
|
ExportPlate(plate, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ExportPlate(Plate plate, Stream stream)
|
||||||
|
{
|
||||||
|
var ctx = new ExportContext();
|
||||||
|
ctx.AddPlateOutline(plate);
|
||||||
|
|
||||||
|
foreach (var part in plate.Parts)
|
||||||
|
{
|
||||||
|
var endpt = part.Location.ToAcadXYZ();
|
||||||
|
ctx.AddLine(ctx.CurPos, endpt, ctx.RapidLayer);
|
||||||
|
ctx.CurPos = part.Location.ToAcadXYZ();
|
||||||
|
ctx.AddProgram(part.Program);
|
||||||
|
}
|
||||||
|
|
||||||
|
using var writer = new DxfWriter(stream, ctx.Document, false);
|
||||||
|
writer.Write();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private
|
||||||
|
|
||||||
|
private static List<Entity> ConvertEntities(CadDocument doc)
|
||||||
|
{
|
||||||
|
var entities = new List<Entity>();
|
||||||
|
var lines = new List<Line>();
|
||||||
|
var arcs = new List<Arc>();
|
||||||
|
|
||||||
|
foreach (var entity in doc.Entities)
|
||||||
|
{
|
||||||
|
if (IsNonCutLayer(entity.Layer?.Name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (entity)
|
||||||
|
{
|
||||||
|
case ACadSharp.Entities.Line line:
|
||||||
|
lines.Add(line.ToOpenNest());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACadSharp.Entities.Arc arc:
|
||||||
|
arcs.Add(arc.ToOpenNest());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACadSharp.Entities.Circle circle:
|
||||||
|
entities.Add(circle.ToOpenNest());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACadSharp.Entities.Spline spline:
|
||||||
|
foreach (var e in spline.ToOpenNest())
|
||||||
|
{
|
||||||
|
if (e is Line l) lines.Add(l);
|
||||||
|
else if (e is Arc a) arcs.Add(a);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACadSharp.Entities.LwPolyline lwPolyline:
|
||||||
|
lines.AddRange(lwPolyline.ToOpenNest());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACadSharp.Entities.Polyline polyline:
|
||||||
|
lines.AddRange(polyline.ToOpenNest());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACadSharp.Entities.Ellipse ellipse:
|
||||||
|
foreach (var e in ellipse.ToOpenNest())
|
||||||
|
{
|
||||||
|
if (e is Line l) lines.Add(l);
|
||||||
|
else if (e is Arc a) arcs.Add(a);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GeometryOptimizer.Optimize(lines);
|
||||||
|
GeometryOptimizer.Optimize(arcs);
|
||||||
|
|
||||||
|
entities.AddRange(lines);
|
||||||
|
entities.AddRange(arcs);
|
||||||
|
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsNonCutLayer(string layerName)
|
||||||
|
{
|
||||||
|
return string.Equals(layerName, "BEND", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(layerName, "ETCH", StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ExportContext
|
||||||
|
{
|
||||||
|
public CadDocument Document { get; }
|
||||||
|
public XYZ CurPos { get; set; }
|
||||||
|
public Layer CutLayer { get; }
|
||||||
|
public Layer RapidLayer { get; }
|
||||||
|
public Layer PlateLayer { get; }
|
||||||
|
|
||||||
|
private Mode mode;
|
||||||
|
|
||||||
|
public ExportContext()
|
||||||
|
{
|
||||||
|
Document = new CadDocument();
|
||||||
|
|
||||||
|
CutLayer = new Layer("Cut") { Color = new Color(1) };
|
||||||
|
RapidLayer = new Layer("Rapid") { Color = new Color(5) };
|
||||||
|
PlateLayer = new Layer("Plate") { Color = new Color(4) };
|
||||||
|
|
||||||
|
Document.Layers.Add(CutLayer);
|
||||||
|
Document.Layers.Add(RapidLayer);
|
||||||
|
Document.Layers.Add(PlateLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddLine(XYZ start, XYZ end, Layer layer)
|
||||||
|
{
|
||||||
|
var ln = new AcadLine
|
||||||
|
{
|
||||||
|
StartPoint = start,
|
||||||
|
EndPoint = end,
|
||||||
|
Layer = layer
|
||||||
|
};
|
||||||
|
Document.Entities.Add(ln);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddPlateOutline(Plate plate)
|
||||||
|
{
|
||||||
|
XYZ pt1, pt2, pt3, pt4;
|
||||||
|
|
||||||
|
switch (plate.Quadrant)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
pt1 = new XYZ(0, 0, 0);
|
||||||
|
pt2 = new XYZ(0, plate.Size.Width, 0);
|
||||||
|
pt3 = new XYZ(plate.Size.Length, plate.Size.Width, 0);
|
||||||
|
pt4 = new XYZ(plate.Size.Length, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
pt1 = new XYZ(0, 0, 0);
|
||||||
|
pt2 = new XYZ(0, plate.Size.Width, 0);
|
||||||
|
pt3 = new XYZ(-plate.Size.Length, plate.Size.Width, 0);
|
||||||
|
pt4 = new XYZ(-plate.Size.Length, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
pt1 = new XYZ(0, 0, 0);
|
||||||
|
pt2 = new XYZ(0, -plate.Size.Width, 0);
|
||||||
|
pt3 = new XYZ(-plate.Size.Length, -plate.Size.Width, 0);
|
||||||
|
pt4 = new XYZ(-plate.Size.Length, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
pt1 = new XYZ(0, 0, 0);
|
||||||
|
pt2 = new XYZ(0, -plate.Size.Width, 0);
|
||||||
|
pt3 = new XYZ(plate.Size.Length, -plate.Size.Width, 0);
|
||||||
|
pt4 = new XYZ(plate.Size.Length, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddLine(pt1, pt2, PlateLayer);
|
||||||
|
AddLine(pt2, pt3, PlateLayer);
|
||||||
|
AddLine(pt3, pt4, PlateLayer);
|
||||||
|
AddLine(pt4, pt1, PlateLayer);
|
||||||
|
|
||||||
|
var m1 = new XYZ(pt1.X + plate.EdgeSpacing.Left, pt1.Y + plate.EdgeSpacing.Bottom, 0);
|
||||||
|
var m2 = new XYZ(m1.X, pt2.Y - plate.EdgeSpacing.Top, 0);
|
||||||
|
var m3 = new XYZ(pt3.X - plate.EdgeSpacing.Right, m2.Y, 0);
|
||||||
|
var m4 = new XYZ(m3.X, m1.Y, 0);
|
||||||
|
|
||||||
|
AddLine(m1, m2, PlateLayer);
|
||||||
|
AddLine(m2, m3, PlateLayer);
|
||||||
|
AddLine(m3, m4, PlateLayer);
|
||||||
|
AddLine(m4, m1, PlateLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddProgram(Program program)
|
||||||
|
{
|
||||||
|
mode = program.Mode;
|
||||||
|
|
||||||
|
for (var i = 0; i < program.Length; ++i)
|
||||||
|
{
|
||||||
|
var code = program[i];
|
||||||
|
|
||||||
|
switch (code.Type)
|
||||||
|
{
|
||||||
|
case CodeType.ArcMove:
|
||||||
|
AddArcMove((ArcMove)code);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CodeType.LinearMove:
|
||||||
|
AddLinearMove((LinearMove)code);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CodeType.RapidMove:
|
||||||
|
AddRapidMove((RapidMove)code);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CodeType.SubProgramCall:
|
||||||
|
var tmpmode = mode;
|
||||||
|
AddProgram(((SubProgramCall)code).Program);
|
||||||
|
mode = tmpmode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddLinearMove(LinearMove line)
|
||||||
|
{
|
||||||
|
var pt = line.EndPoint.ToAcadXYZ();
|
||||||
|
|
||||||
|
if (mode == Mode.Incremental)
|
||||||
|
pt = new XYZ(pt.X + CurPos.X, pt.Y + CurPos.Y, 0);
|
||||||
|
|
||||||
|
AddLine(CurPos, pt, CutLayer);
|
||||||
|
CurPos = pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddRapidMove(RapidMove rapid)
|
||||||
|
{
|
||||||
|
var pt = rapid.EndPoint.ToAcadXYZ();
|
||||||
|
|
||||||
|
if (mode == Mode.Incremental)
|
||||||
|
pt = new XYZ(pt.X + CurPos.X, pt.Y + CurPos.Y, 0);
|
||||||
|
|
||||||
|
AddLine(CurPos, pt, RapidLayer);
|
||||||
|
CurPos = pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddArcMove(ArcMove arc)
|
||||||
|
{
|
||||||
|
var center = arc.CenterPoint.ToAcadXYZ();
|
||||||
|
var endpt = arc.EndPoint.ToAcadXYZ();
|
||||||
|
|
||||||
|
if (mode == Mode.Incremental)
|
||||||
|
{
|
||||||
|
endpt = new XYZ(endpt.X + CurPos.X, endpt.Y + CurPos.Y, 0);
|
||||||
|
center = new XYZ(center.X + CurPos.X, center.Y + CurPos.Y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var startAngle = System.Math.Atan2(
|
||||||
|
CurPos.Y - center.Y,
|
||||||
|
CurPos.X - center.X);
|
||||||
|
|
||||||
|
var endAngle = System.Math.Atan2(
|
||||||
|
endpt.Y - center.Y,
|
||||||
|
endpt.X - center.X);
|
||||||
|
|
||||||
|
if (arc.Rotation == RotationType.CW)
|
||||||
|
Generic.Swap(ref startAngle, ref endAngle);
|
||||||
|
|
||||||
|
var dx = endpt.X - center.X;
|
||||||
|
var dy = endpt.Y - center.Y;
|
||||||
|
var radius = System.Math.Sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
|
if (startAngle.IsEqualTo(endAngle))
|
||||||
|
{
|
||||||
|
var circle = new AcadCircle
|
||||||
|
{
|
||||||
|
Center = center,
|
||||||
|
Radius = radius,
|
||||||
|
Layer = CutLayer
|
||||||
|
};
|
||||||
|
Document.Entities.Add(circle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var acadArc = new AcadArc
|
||||||
|
{
|
||||||
|
Center = center,
|
||||||
|
Radius = radius,
|
||||||
|
StartAngle = startAngle,
|
||||||
|
EndAngle = endAngle,
|
||||||
|
Layer = CutLayer
|
||||||
|
};
|
||||||
|
Document.Entities.Add(acadArc);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurPos = endpt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,297 +0,0 @@
|
|||||||
using ACadSharp;
|
|
||||||
using ACadSharp.IO;
|
|
||||||
using CSMath;
|
|
||||||
using OpenNest.CNC;
|
|
||||||
using OpenNest.Math;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace OpenNest.IO
|
|
||||||
{
|
|
||||||
using AcadArc = ACadSharp.Entities.Arc;
|
|
||||||
using AcadCircle = ACadSharp.Entities.Circle;
|
|
||||||
using AcadLine = ACadSharp.Entities.Line;
|
|
||||||
using Layer = ACadSharp.Tables.Layer;
|
|
||||||
|
|
||||||
public class DxfExporter
|
|
||||||
{
|
|
||||||
private CadDocument doc;
|
|
||||||
private XYZ curpos;
|
|
||||||
private Mode mode;
|
|
||||||
private readonly Layer cutLayer;
|
|
||||||
private readonly Layer rapidLayer;
|
|
||||||
private readonly Layer plateLayer;
|
|
||||||
|
|
||||||
public DxfExporter()
|
|
||||||
{
|
|
||||||
doc = new CadDocument();
|
|
||||||
|
|
||||||
cutLayer = new Layer("Cut");
|
|
||||||
cutLayer.Color = new Color(1);
|
|
||||||
|
|
||||||
rapidLayer = new Layer("Rapid");
|
|
||||||
rapidLayer.Color = new Color(5);
|
|
||||||
|
|
||||||
plateLayer = new Layer("Plate");
|
|
||||||
plateLayer.Color = new Color(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ExportProgram(Program program, Stream stream)
|
|
||||||
{
|
|
||||||
doc = new CadDocument();
|
|
||||||
EnsureLayers();
|
|
||||||
AddProgram(program);
|
|
||||||
using (var writer = new DxfWriter(stream, doc, false))
|
|
||||||
{
|
|
||||||
writer.Write();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ExportProgram(Program program, string path)
|
|
||||||
{
|
|
||||||
Stream stream = null;
|
|
||||||
var success = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
stream = File.Create(path);
|
|
||||||
ExportProgram(program, stream);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Debug.Fail("DxfExporter.ExportProgram failed to write program to file: " + path);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (stream != null)
|
|
||||||
stream.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ExportPlate(Plate plate, Stream stream)
|
|
||||||
{
|
|
||||||
doc = new CadDocument();
|
|
||||||
EnsureLayers();
|
|
||||||
AddPlateOutline(plate);
|
|
||||||
|
|
||||||
foreach (var part in plate.Parts)
|
|
||||||
{
|
|
||||||
var endpt = part.Location.ToAcadXYZ();
|
|
||||||
AddLine(curpos, endpt, rapidLayer);
|
|
||||||
curpos = part.Location.ToAcadXYZ();
|
|
||||||
AddProgram(part.Program);
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var writer = new DxfWriter(stream, doc, false))
|
|
||||||
{
|
|
||||||
writer.Write();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ExportPlate(Plate plate, string path)
|
|
||||||
{
|
|
||||||
Stream stream = null;
|
|
||||||
var success = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
stream = File.Create(path);
|
|
||||||
ExportPlate(plate, stream);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Debug.Fail("DxfExporter.ExportPlate failed to write plate to file: " + path);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (stream != null)
|
|
||||||
stream.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnsureLayers()
|
|
||||||
{
|
|
||||||
doc.Layers.Add(cutLayer);
|
|
||||||
doc.Layers.Add(rapidLayer);
|
|
||||||
doc.Layers.Add(plateLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddLine(XYZ start, XYZ end, Layer layer)
|
|
||||||
{
|
|
||||||
var ln = new AcadLine();
|
|
||||||
ln.StartPoint = start;
|
|
||||||
ln.EndPoint = end;
|
|
||||||
ln.Layer = layer;
|
|
||||||
doc.Entities.Add(ln);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddPlateOutline(Plate plate)
|
|
||||||
{
|
|
||||||
XYZ pt1;
|
|
||||||
XYZ pt2;
|
|
||||||
XYZ pt3;
|
|
||||||
XYZ pt4;
|
|
||||||
|
|
||||||
switch (plate.Quadrant)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
pt1 = new XYZ(0, 0, 0);
|
|
||||||
pt2 = new XYZ(0, plate.Size.Width, 0);
|
|
||||||
pt3 = new XYZ(plate.Size.Length, plate.Size.Width, 0);
|
|
||||||
pt4 = new XYZ(plate.Size.Length, 0, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
pt1 = new XYZ(0, 0, 0);
|
|
||||||
pt2 = new XYZ(0, plate.Size.Width, 0);
|
|
||||||
pt3 = new XYZ(-plate.Size.Length, plate.Size.Width, 0);
|
|
||||||
pt4 = new XYZ(-plate.Size.Length, 0, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
pt1 = new XYZ(0, 0, 0);
|
|
||||||
pt2 = new XYZ(0, -plate.Size.Width, 0);
|
|
||||||
pt3 = new XYZ(-plate.Size.Length, -plate.Size.Width, 0);
|
|
||||||
pt4 = new XYZ(-plate.Size.Length, 0, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
pt1 = new XYZ(0, 0, 0);
|
|
||||||
pt2 = new XYZ(0, -plate.Size.Width, 0);
|
|
||||||
pt3 = new XYZ(plate.Size.Length, -plate.Size.Width, 0);
|
|
||||||
pt4 = new XYZ(plate.Size.Length, 0, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddLine(pt1, pt2, plateLayer);
|
|
||||||
AddLine(pt2, pt3, plateLayer);
|
|
||||||
AddLine(pt3, pt4, plateLayer);
|
|
||||||
AddLine(pt4, pt1, plateLayer);
|
|
||||||
|
|
||||||
var m1 = new XYZ(pt1.X + plate.EdgeSpacing.Left, pt1.Y + plate.EdgeSpacing.Bottom, 0);
|
|
||||||
var m2 = new XYZ(m1.X, pt2.Y - plate.EdgeSpacing.Top, 0);
|
|
||||||
var m3 = new XYZ(pt3.X - plate.EdgeSpacing.Right, m2.Y, 0);
|
|
||||||
var m4 = new XYZ(m3.X, m1.Y, 0);
|
|
||||||
|
|
||||||
AddLine(m1, m2, plateLayer);
|
|
||||||
AddLine(m2, m3, plateLayer);
|
|
||||||
AddLine(m3, m4, plateLayer);
|
|
||||||
AddLine(m4, m1, plateLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddProgram(Program program)
|
|
||||||
{
|
|
||||||
mode = program.Mode;
|
|
||||||
|
|
||||||
for (var i = 0; i < program.Length; ++i)
|
|
||||||
{
|
|
||||||
var code = program[i];
|
|
||||||
|
|
||||||
switch (code.Type)
|
|
||||||
{
|
|
||||||
case CodeType.ArcMove:
|
|
||||||
var arc = (ArcMove)code;
|
|
||||||
AddArcMove(arc);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CodeType.LinearMove:
|
|
||||||
var line = (LinearMove)code;
|
|
||||||
AddLinearMove(line);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CodeType.RapidMove:
|
|
||||||
var rapid = (RapidMove)code;
|
|
||||||
AddRapidMove(rapid);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CodeType.SubProgramCall:
|
|
||||||
var tmpmode = mode;
|
|
||||||
var subpgm = (CNC.SubProgramCall)code;
|
|
||||||
AddProgram(subpgm.Program);
|
|
||||||
mode = tmpmode;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddLinearMove(LinearMove line)
|
|
||||||
{
|
|
||||||
var pt = line.EndPoint.ToAcadXYZ();
|
|
||||||
|
|
||||||
if (mode == Mode.Incremental)
|
|
||||||
pt = new XYZ(pt.X + curpos.X, pt.Y + curpos.Y, 0);
|
|
||||||
|
|
||||||
AddLine(curpos, pt, cutLayer);
|
|
||||||
curpos = pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddRapidMove(RapidMove rapid)
|
|
||||||
{
|
|
||||||
var pt = rapid.EndPoint.ToAcadXYZ();
|
|
||||||
|
|
||||||
if (mode == Mode.Incremental)
|
|
||||||
pt = new XYZ(pt.X + curpos.X, pt.Y + curpos.Y, 0);
|
|
||||||
|
|
||||||
AddLine(curpos, pt, rapidLayer);
|
|
||||||
curpos = pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddArcMove(ArcMove arc)
|
|
||||||
{
|
|
||||||
var center = arc.CenterPoint.ToAcadXYZ();
|
|
||||||
var endpt = arc.EndPoint.ToAcadXYZ();
|
|
||||||
|
|
||||||
if (mode == Mode.Incremental)
|
|
||||||
{
|
|
||||||
endpt = new XYZ(endpt.X + curpos.X, endpt.Y + curpos.Y, 0);
|
|
||||||
center = new XYZ(center.X + curpos.X, center.Y + curpos.Y, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
var startAngle = System.Math.Atan2(
|
|
||||||
curpos.Y - center.Y,
|
|
||||||
curpos.X - center.X);
|
|
||||||
|
|
||||||
var endAngle = System.Math.Atan2(
|
|
||||||
endpt.Y - center.Y,
|
|
||||||
endpt.X - center.X);
|
|
||||||
|
|
||||||
if (arc.Rotation == OpenNest.RotationType.CW)
|
|
||||||
Generic.Swap(ref startAngle, ref endAngle);
|
|
||||||
|
|
||||||
var dx = endpt.X - center.X;
|
|
||||||
var dy = endpt.Y - center.Y;
|
|
||||||
|
|
||||||
var radius = System.Math.Sqrt(dx * dx + dy * dy);
|
|
||||||
|
|
||||||
if (startAngle.IsEqualTo(endAngle))
|
|
||||||
{
|
|
||||||
var circle = new AcadCircle();
|
|
||||||
circle.Center = center;
|
|
||||||
circle.Radius = radius;
|
|
||||||
circle.Layer = cutLayer;
|
|
||||||
doc.Entities.Add(circle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var arc2 = new AcadArc();
|
|
||||||
arc2.Center = center;
|
|
||||||
arc2.Radius = radius;
|
|
||||||
arc2.StartAngle = startAngle;
|
|
||||||
arc2.EndAngle = endAngle;
|
|
||||||
arc2.Layer = cutLayer;
|
|
||||||
doc.Entities.Add(arc2);
|
|
||||||
}
|
|
||||||
|
|
||||||
curpos = endpt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
using ACadSharp;
|
|
||||||
using ACadSharp.IO;
|
|
||||||
using OpenNest.Geometry;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace OpenNest.IO
|
|
||||||
{
|
|
||||||
public class DxfImporter
|
|
||||||
{
|
|
||||||
public DxfImporter()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Entity> GetGeometry(CadDocument doc)
|
|
||||||
{
|
|
||||||
var entities = new List<Entity>();
|
|
||||||
var lines = new List<Line>();
|
|
||||||
var arcs = new List<Arc>();
|
|
||||||
|
|
||||||
foreach (var entity in doc.Entities)
|
|
||||||
{
|
|
||||||
// Skip bend/etch entities — bends are converted to Bend objects
|
|
||||||
// separately via bend detection, and etch marks are generated from
|
|
||||||
// bends during DXF export. Neither should be treated as cut geometry.
|
|
||||||
if (IsNonCutLayer(entity.Layer?.Name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (entity)
|
|
||||||
{
|
|
||||||
case ACadSharp.Entities.Line line:
|
|
||||||
lines.Add(line.ToOpenNest());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACadSharp.Entities.Arc arc:
|
|
||||||
arcs.Add(arc.ToOpenNest());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACadSharp.Entities.Circle circle:
|
|
||||||
entities.Add(circle.ToOpenNest());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACadSharp.Entities.Spline spline:
|
|
||||||
foreach (var e in spline.ToOpenNest())
|
|
||||||
{
|
|
||||||
if (e is Line l) lines.Add(l);
|
|
||||||
else if (e is Arc a) arcs.Add(a);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACadSharp.Entities.LwPolyline lwPolyline:
|
|
||||||
lines.AddRange(lwPolyline.ToOpenNest());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACadSharp.Entities.Polyline polyline:
|
|
||||||
lines.AddRange(polyline.ToOpenNest());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACadSharp.Entities.Ellipse ellipse:
|
|
||||||
foreach (var e in ellipse.ToOpenNest())
|
|
||||||
{
|
|
||||||
if (e is Line l) lines.Add(l);
|
|
||||||
else if (e is Arc a) arcs.Add(a);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GeometryOptimizer.Optimize(lines);
|
|
||||||
GeometryOptimizer.Optimize(arcs);
|
|
||||||
|
|
||||||
entities.AddRange(lines);
|
|
||||||
entities.AddRange(arcs);
|
|
||||||
|
|
||||||
return entities;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Imports a DXF file, returning both converted entities and the raw CadDocument
|
|
||||||
/// for bend detection. The CadDocument is NOT disposed — caller can use it for
|
|
||||||
/// additional analysis (e.g., MText extraction for bend notes).
|
|
||||||
/// </summary>
|
|
||||||
public DxfImportResult Import(string path)
|
|
||||||
{
|
|
||||||
using var reader = new DxfReader(path);
|
|
||||||
var doc = reader.Read();
|
|
||||||
var entities = GetGeometry(doc);
|
|
||||||
|
|
||||||
return new DxfImportResult
|
|
||||||
{
|
|
||||||
Entities = entities,
|
|
||||||
Document = doc
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool GetGeometry(Stream stream, out List<Entity> geometry)
|
|
||||||
{
|
|
||||||
var success = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var reader = new DxfReader(stream))
|
|
||||||
{
|
|
||||||
var doc = reader.Read();
|
|
||||||
geometry = GetGeometry(doc);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.WriteLine(ex.Message);
|
|
||||||
geometry = new List<Entity>();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (stream != null)
|
|
||||||
stream.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool GetGeometry(string path, out List<Entity> geometry)
|
|
||||||
{
|
|
||||||
var success = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var reader = new DxfReader(path))
|
|
||||||
{
|
|
||||||
var doc = reader.Read();
|
|
||||||
geometry = GetGeometry(doc);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.WriteLine(ex.Message);
|
|
||||||
geometry = new List<Entity>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsNonCutLayer(string layerName)
|
|
||||||
{
|
|
||||||
return string.Equals(layerName, "BEND", System.StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| string.Equals(layerName, "ETCH", System.StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -96,13 +96,10 @@ namespace OpenNest.Mcp.Tools
|
|||||||
if (!File.Exists(path))
|
if (!File.Exists(path))
|
||||||
return $"Error: file not found: {path}";
|
return $"Error: file not found: {path}";
|
||||||
|
|
||||||
var importer = new DxfImporter();
|
var geometry = Dxf.GetGeometry(path);
|
||||||
|
|
||||||
if (!importer.GetGeometry(path, out var geometry))
|
|
||||||
return "Error: failed to read DXF file";
|
|
||||||
|
|
||||||
if (geometry.Count == 0)
|
if (geometry.Count == 0)
|
||||||
return "Error: no geometry found in DXF file";
|
return "Error: failed to read DXF file or no geometry found";
|
||||||
|
|
||||||
var normalized = ShapeProfile.NormalizeEntities(geometry);
|
var normalized = ShapeProfile.NormalizeEntities(geometry);
|
||||||
var pgm = ConvertGeometry.ToProgram(normalized);
|
var pgm = ConvertGeometry.ToProgram(normalized);
|
||||||
|
|||||||
@@ -70,8 +70,7 @@ public class NestRunnerTests
|
|||||||
var pgm = ConvertGeometry.ToProgram(shape);
|
var pgm = ConvertGeometry.ToProgram(shape);
|
||||||
var path = Path.Combine(Path.GetTempPath(), $"test-{Guid.NewGuid()}.dxf");
|
var path = Path.Combine(Path.GetTempPath(), $"test-{Guid.NewGuid()}.dxf");
|
||||||
|
|
||||||
var exporter = new DxfExporter();
|
Dxf.ExportProgram(pgm, path);
|
||||||
exporter.ExportProgram(pgm, path);
|
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,7 @@ public class SolidWorksBendDetectorTests
|
|||||||
var path = Path.Combine(AppContext.BaseDirectory, "Bending", "TestData", "4526 A14 PT11 Test.dxf");
|
var path = Path.Combine(AppContext.BaseDirectory, "Bending", "TestData", "4526 A14 PT11 Test.dxf");
|
||||||
Assert.True(File.Exists(path), $"Test DXF not found: {path}");
|
Assert.True(File.Exists(path), $"Test DXF not found: {path}");
|
||||||
|
|
||||||
var importer = new OpenNest.IO.DxfImporter();
|
var result = OpenNest.IO.Dxf.Import(path);
|
||||||
var result = importer.Import(path);
|
|
||||||
|
|
||||||
// EllipseConverter now produces arcs directly during import,
|
// EllipseConverter now produces arcs directly during import,
|
||||||
// so the imported entities should contain Arc instances from the ellipses
|
// so the imported entities should contain Arc instances from the ellipses
|
||||||
@@ -61,8 +60,7 @@ public class SolidWorksBendDetectorTests
|
|||||||
var path = Path.Combine(AppContext.BaseDirectory, "Bending", "TestData", "4526 A14 PT11.dxf");
|
var path = Path.Combine(AppContext.BaseDirectory, "Bending", "TestData", "4526 A14 PT11.dxf");
|
||||||
Assert.True(File.Exists(path), $"Test DXF not found: {path}");
|
Assert.True(File.Exists(path), $"Test DXF not found: {path}");
|
||||||
|
|
||||||
var importer = new OpenNest.IO.DxfImporter();
|
var result = OpenNest.IO.Dxf.Import(path);
|
||||||
var result = importer.Import(path);
|
|
||||||
|
|
||||||
// The DXF has 2 trimmed ellipses forming an oblong slot.
|
// The DXF has 2 trimmed ellipses forming an oblong slot.
|
||||||
// Trimmed ellipses must not generate a closing chord line.
|
// Trimmed ellipses must not generate a closing chord line.
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ public class BestFitOverlapTests
|
|||||||
if (!File.Exists(DxfPath))
|
if (!File.Exists(DxfPath))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var importer = new DxfImporter();
|
var geometry = Dxf.GetGeometry(DxfPath);
|
||||||
importer.GetGeometry(DxfPath, out var geometry);
|
|
||||||
var pgm = ConvertGeometry.ToProgram(geometry);
|
var pgm = ConvertGeometry.ToProgram(geometry);
|
||||||
return new Drawing("PT16", pgm);
|
return new Drawing("PT16", pgm);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ public class EngineOverlapTests
|
|||||||
if (!System.IO.File.Exists(DxfPath))
|
if (!System.IO.File.Exists(DxfPath))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var importer = new DxfImporter();
|
var geometry = Dxf.GetGeometry(DxfPath);
|
||||||
importer.GetGeometry(DxfPath, out var geometry);
|
|
||||||
var pgm = ConvertGeometry.ToProgram(geometry);
|
var pgm = ConvertGeometry.ToProgram(geometry);
|
||||||
return new Drawing("PT15", pgm);
|
return new Drawing("PT15", pgm);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,8 +228,7 @@ public class EllipseConverterTests
|
|||||||
using (var writer = new ACadSharp.IO.DxfWriter(stream, doc, false))
|
using (var writer = new ACadSharp.IO.DxfWriter(stream, doc, false))
|
||||||
writer.Write();
|
writer.Write();
|
||||||
|
|
||||||
var importer = new OpenNest.IO.DxfImporter();
|
var result = OpenNest.IO.Dxf.Import(tempPath);
|
||||||
var result = importer.Import(tempPath);
|
|
||||||
|
|
||||||
var arcCount = result.Entities.Count(e => e is Arc);
|
var arcCount = result.Entities.Count(e => e is Arc);
|
||||||
var lineCount = result.Entities.Count(e => e is Line);
|
var lineCount = result.Entities.Count(e => e is Line);
|
||||||
|
|||||||
@@ -138,8 +138,7 @@ public class GeometrySimplifierTests
|
|||||||
if (!File.Exists(path))
|
if (!File.Exists(path))
|
||||||
return; // skip if file not available
|
return; // skip if file not available
|
||||||
|
|
||||||
var importer = new DxfImporter();
|
var result = Dxf.Import(path);
|
||||||
var result = importer.Import(path);
|
|
||||||
var shapes = ShapeBuilder.GetShapes(result.Entities);
|
var shapes = ShapeBuilder.GetShapes(result.Entities);
|
||||||
|
|
||||||
var simplifier = new GeometrySimplifier { Tolerance = 0.004 };
|
var simplifier = new GeometrySimplifier { Tolerance = 0.004 };
|
||||||
|
|||||||
@@ -11,17 +11,14 @@ public class DxfRoundtripTests
|
|||||||
private static List<Entity> ExportAndReimport(List<Entity> geometry)
|
private static List<Entity> ExportAndReimport(List<Entity> geometry)
|
||||||
{
|
{
|
||||||
var program = ConvertGeometry.ToProgram(geometry);
|
var program = ConvertGeometry.ToProgram(geometry);
|
||||||
var exporter = new DxfExporter();
|
|
||||||
var importer = new DxfImporter();
|
|
||||||
|
|
||||||
using var exportStream = new MemoryStream();
|
using var exportStream = new MemoryStream();
|
||||||
exporter.ExportProgram(program, exportStream);
|
Dxf.ExportProgram(program, exportStream);
|
||||||
var bytes = exportStream.ToArray();
|
var bytes = exportStream.ToArray();
|
||||||
|
|
||||||
var importStream = new MemoryStream(bytes);
|
var importStream = new MemoryStream(bytes);
|
||||||
var success = importer.GetGeometry(importStream, out var reimported);
|
var reimported = Dxf.GetGeometry(importStream);
|
||||||
|
|
||||||
Assert.True(success, "Failed to re-import exported DXF");
|
Assert.NotEmpty(reimported);
|
||||||
return reimported;
|
return reimported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -369,8 +369,7 @@ public class DrawingSplitterTests
|
|||||||
var writer = new OpenNest.IO.SplitDxfWriter();
|
var writer = new OpenNest.IO.SplitDxfWriter();
|
||||||
writer.Write(tempPath, results[0]);
|
writer.Write(tempPath, results[0]);
|
||||||
|
|
||||||
var reimporter = new OpenNest.IO.DxfImporter();
|
var reimportResult = OpenNest.IO.Dxf.Import(tempPath);
|
||||||
var reimportResult = reimporter.Import(tempPath);
|
|
||||||
|
|
||||||
var afterArcs = reimportResult.Entities.OfType<Arc>().Count();
|
var afterArcs = reimportResult.Entities.OfType<Arc>().Count();
|
||||||
var afterCircles = reimportResult.Entities.OfType<Circle>().Count();
|
var afterCircles = reimportResult.Entities.OfType<Circle>().Count();
|
||||||
|
|||||||
@@ -185,8 +185,7 @@ public class SplitDxfWriterEtchLayerTests
|
|||||||
writer.Write(tempPath, splitDrawing);
|
writer.Write(tempPath, splitDrawing);
|
||||||
|
|
||||||
// Re-import via DxfImporter (same path as CadConverterForm)
|
// Re-import via DxfImporter (same path as CadConverterForm)
|
||||||
var importer = new DxfImporter();
|
var result = Dxf.Import(tempPath);
|
||||||
var result = importer.Import(tempPath);
|
|
||||||
|
|
||||||
// ETCH entities should be filtered during import (like BEND)
|
// ETCH entities should be filtered during import (like BEND)
|
||||||
var etchEntities = result.Entities
|
var etchEntities = result.Entities
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ public class StrategyOverlapTests
|
|||||||
if (!System.IO.File.Exists(DxfPath))
|
if (!System.IO.File.Exists(DxfPath))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var importer = new DxfImporter();
|
var geometry = Dxf.GetGeometry(DxfPath);
|
||||||
importer.GetGeometry(DxfPath, out var geometry);
|
|
||||||
var pgm = ConvertGeometry.ToProgram(geometry);
|
var pgm = ConvertGeometry.ToProgram(geometry);
|
||||||
return new Drawing("PT15", pgm);
|
return new Drawing("PT15", pgm);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ int RunDataCollection(string dir, string dbPath, string saveDir, double s, strin
|
|||||||
if (backfilled > 0)
|
if (backfilled > 0)
|
||||||
Console.WriteLine($"Backfilled PerimeterToAreaRatio for {backfilled} existing parts");
|
Console.WriteLine($"Backfilled PerimeterToAreaRatio for {backfilled} existing parts");
|
||||||
|
|
||||||
var importer = new DxfImporter();
|
|
||||||
var colorIndex = 0;
|
var colorIndex = 0;
|
||||||
var processed = 0;
|
var processed = 0;
|
||||||
var skippedGeometry = 0;
|
var skippedGeometry = 0;
|
||||||
@@ -129,7 +128,8 @@ int RunDataCollection(string dir, string dbPath, string saveDir, double s, strin
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!importer.GetGeometry(file, out var entities))
|
var entities = Dxf.GetGeometry(file);
|
||||||
|
if (entities.Count == 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine(" - SKIP (no geometry)");
|
Console.WriteLine(" - SKIP (no geometry)");
|
||||||
skippedGeometry++;
|
skippedGeometry++;
|
||||||
|
|||||||
@@ -382,7 +382,6 @@ namespace OpenNest.Forms
|
|||||||
}
|
}
|
||||||
|
|
||||||
var jobName = txtJobName.Text.Trim();
|
var jobName = txtJobName.Text.Trim();
|
||||||
var importer = new DxfImporter();
|
|
||||||
var nestsCreated = 0;
|
var nestsCreated = 0;
|
||||||
var importErrors = new List<string>();
|
var importErrors = new List<string>();
|
||||||
|
|
||||||
@@ -416,7 +415,7 @@ namespace OpenNest.Forms
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = importer.Import(part.DxfPath);
|
var result = Dxf.Import(part.DxfPath);
|
||||||
|
|
||||||
var drawingName = Path.GetFileNameWithoutExtension(part.DxfPath);
|
var drawingName = Path.GetFileNameWithoutExtension(part.DxfPath);
|
||||||
var drawing = new Drawing(drawingName);
|
var drawing = new Drawing(drawingName);
|
||||||
|
|||||||
@@ -74,8 +74,7 @@ namespace OpenNest.Forms
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var importer = new DxfImporter();
|
var result = Dxf.Import(file);
|
||||||
var result = importer.Import(file);
|
|
||||||
|
|
||||||
if (result.Entities.Count == 0)
|
if (result.Entities.Count == 0)
|
||||||
return;
|
return;
|
||||||
@@ -383,8 +382,7 @@ namespace OpenNest.Forms
|
|||||||
newItems.Add(splitPath);
|
newItems.Add(splitPath);
|
||||||
|
|
||||||
// Re-import geometry but keep bends from the split drawing
|
// Re-import geometry but keep bends from the split drawing
|
||||||
var importer = new DxfImporter();
|
var result = Dxf.Import(splitPath);
|
||||||
var result = importer.Import(splitPath);
|
|
||||||
|
|
||||||
var splitItem = new FileListItem
|
var splitItem = new FileListItem
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -362,9 +362,8 @@ namespace OpenNest.Forms
|
|||||||
{
|
{
|
||||||
if (dlg.FilterIndex == 1)
|
if (dlg.FilterIndex == 1)
|
||||||
{
|
{
|
||||||
var exporter = new DxfExporter();
|
Dxf.ExportPlate(PlateView.Plate, dlg.FileName);
|
||||||
var success = exporter.ExportPlate(PlateView.Plate, dlg.FileName);
|
return true;
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
else if (dlg.FilterIndex == 2)
|
else if (dlg.FilterIndex == 2)
|
||||||
{
|
{
|
||||||
@@ -540,8 +539,7 @@ namespace OpenNest.Forms
|
|||||||
var plate = PlateView.Plate;
|
var plate = PlateView.Plate;
|
||||||
var name = string.Format("{0}-P{1}.dxf", Nest.Name, PlateManager.CurrentIndex + 1);
|
var name = string.Format("{0}-P{1}.dxf", Nest.Name, PlateManager.CurrentIndex + 1);
|
||||||
var path = Path.Combine(Path.GetTempPath(), name);
|
var path = Path.Combine(Path.GetTempPath(), name);
|
||||||
var exporter = new DxfExporter();
|
Dxf.ExportPlate(plate, path);
|
||||||
exporter.ExportPlate(plate, path);
|
|
||||||
|
|
||||||
Process.Start(path);
|
Process.Start(path);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user