refactor: rewrite DxfExporter for ACadSharp

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 13:30:23 -05:00
parent d185adecfa
commit 848023a2b9
2 changed files with 101 additions and 89 deletions
+100 -88
View File
@@ -1,23 +1,25 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using netDxf; using ACadSharp;
using netDxf.Entities; using ACadSharp.Entities;
using netDxf.Tables; using ACadSharp.IO;
using ACadSharp.Tables;
using CSMath;
using OpenNest.CNC; using OpenNest.CNC;
using OpenNest.Math; using OpenNest.Math;
namespace OpenNest.IO namespace OpenNest.IO
{ {
using Layer = netDxf.Tables.Layer; using AcadArc = ACadSharp.Entities.Arc;
using Line = netDxf.Entities.Line; using AcadCircle = ACadSharp.Entities.Circle;
using AcadLine = ACadSharp.Entities.Line;
using Layer = ACadSharp.Tables.Layer;
public class DxfExporter public class DxfExporter
{ {
private const double RadToDeg = 180.0 / System.Math.PI; private CadDocument doc;
private XYZ curpos;
private DxfDocument doc;
private Vector2 curpos;
private Mode mode; private Mode mode;
private readonly Layer cutLayer; private readonly Layer cutLayer;
private readonly Layer rapidLayer; private readonly Layer rapidLayer;
@@ -25,30 +27,33 @@ namespace OpenNest.IO
public DxfExporter() public DxfExporter()
{ {
doc = new DxfDocument(); doc = new CadDocument();
cutLayer = new Layer("Cut"); cutLayer = new Layer("Cut");
cutLayer.Color = AciColor.Red; cutLayer.Color = new Color(1);
rapidLayer = new Layer("Rapid"); rapidLayer = new Layer("Rapid");
rapidLayer.Color = AciColor.Blue; rapidLayer.Color = new Color(5);
rapidLayer.Linetype = Linetype.Dashed;
plateLayer = new Layer("Plate"); plateLayer = new Layer("Plate");
plateLayer.Color = AciColor.Cyan; plateLayer.Color = new Color(4);
} }
public void ExportProgram(Program program, Stream stream) public void ExportProgram(Program program, Stream stream)
{ {
doc = new DxfDocument(); doc = new CadDocument();
EnsureLayers();
AddProgram(program); AddProgram(program);
doc.Save(stream); using (var writer = new DxfWriter(stream, doc, false))
{
writer.Write();
}
} }
public bool ExportProgram(Program program, string path) public bool ExportProgram(Program program, string path)
{ {
Stream stream = null; Stream stream = null;
bool success = false; var success = false;
try try
{ {
@@ -71,26 +76,28 @@ namespace OpenNest.IO
public void ExportPlate(Plate plate, Stream stream) public void ExportPlate(Plate plate, Stream stream)
{ {
doc = new DxfDocument(); doc = new CadDocument();
EnsureLayers();
AddPlateOutline(plate); AddPlateOutline(plate);
foreach (var part in plate.Parts) foreach (var part in plate.Parts)
{ {
var endpt = part.Location.ToNetDxf(); var endpt = part.Location.ToAcadXYZ();
var line = new netDxf.Entities.Line(curpos, endpt); AddLine(curpos, endpt, rapidLayer);
line.Layer = rapidLayer; curpos = part.Location.ToAcadXYZ();
doc.Entities.Add(line);
curpos = part.Location.ToNetDxf();
AddProgram(part.Program); AddProgram(part.Program);
} }
doc.Save(stream); using (var writer = new DxfWriter(stream, doc, false))
{
writer.Write();
}
} }
public bool ExportPlate(Plate plate, string path) public bool ExportPlate(Plate plate, string path)
{ {
Stream stream = null; Stream stream = null;
bool success = false; var success = false;
try try
{ {
@@ -111,75 +118,84 @@ namespace OpenNest.IO
return success; 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) private void AddPlateOutline(Plate plate)
{ {
Vector2 pt1; XYZ pt1;
Vector2 pt2; XYZ pt2;
Vector2 pt3; XYZ pt3;
Vector2 pt4; XYZ pt4;
switch (plate.Quadrant) switch (plate.Quadrant)
{ {
case 1: case 1:
pt1 = new Vector2(0, 0); pt1 = new XYZ(0, 0, 0);
pt2 = new Vector2(0, plate.Size.Height); pt2 = new XYZ(0, plate.Size.Height, 0);
pt3 = new Vector2(plate.Size.Width, plate.Size.Height); pt3 = new XYZ(plate.Size.Width, plate.Size.Height, 0);
pt4 = new Vector2(plate.Size.Width, 0); pt4 = new XYZ(plate.Size.Width, 0, 0);
break; break;
case 2: case 2:
pt1 = new Vector2(0, 0); pt1 = new XYZ(0, 0, 0);
pt2 = new Vector2(0, plate.Size.Height); pt2 = new XYZ(0, plate.Size.Height, 0);
pt3 = new Vector2(-plate.Size.Width, plate.Size.Height); pt3 = new XYZ(-plate.Size.Width, plate.Size.Height, 0);
pt4 = new Vector2(-plate.Size.Width, 0); pt4 = new XYZ(-plate.Size.Width, 0, 0);
break; break;
case 3: case 3:
pt1 = new Vector2(0, 0); pt1 = new XYZ(0, 0, 0);
pt2 = new Vector2(0, -plate.Size.Height); pt2 = new XYZ(0, -plate.Size.Height, 0);
pt3 = new Vector2(-plate.Size.Width, -plate.Size.Height); pt3 = new XYZ(-plate.Size.Width, -plate.Size.Height, 0);
pt4 = new Vector2(-plate.Size.Width, 0); pt4 = new XYZ(-plate.Size.Width, 0, 0);
break; break;
case 4: case 4:
pt1 = new Vector2(0, 0); pt1 = new XYZ(0, 0, 0);
pt2 = new Vector2(0, -plate.Size.Height); pt2 = new XYZ(0, -plate.Size.Height, 0);
pt3 = new Vector2(plate.Size.Width, -plate.Size.Height); pt3 = new XYZ(plate.Size.Width, -plate.Size.Height, 0);
pt4 = new Vector2(plate.Size.Width, 0); pt4 = new XYZ(plate.Size.Width, 0, 0);
break; break;
default: default:
return; return;
} }
doc.Entities.Add(new Line(pt1, pt2) { Layer = plateLayer }); AddLine(pt1, pt2, plateLayer);
doc.Entities.Add(new Line(pt2, pt3) { Layer = plateLayer }); AddLine(pt2, pt3, plateLayer);
doc.Entities.Add(new Line(pt3, pt4) { Layer = plateLayer }); AddLine(pt3, pt4, plateLayer);
doc.Entities.Add(new Line(pt4, pt1) { Layer = plateLayer }); AddLine(pt4, pt1, plateLayer);
pt1.X += plate.EdgeSpacing.Left; var m1 = new XYZ(pt1.X + plate.EdgeSpacing.Left, pt1.Y + plate.EdgeSpacing.Bottom, 0);
pt1.Y += plate.EdgeSpacing.Bottom; 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);
pt2.X = pt1.X; AddLine(m1, m2, plateLayer);
pt2.Y -= plate.EdgeSpacing.Top; AddLine(m2, m3, plateLayer);
AddLine(m3, m4, plateLayer);
pt3.X -= plate.EdgeSpacing.Right; AddLine(m4, m1, plateLayer);
pt3.Y = pt2.Y;
pt4.X = pt3.X;
pt4.Y = pt1.Y;
doc.Entities.Add(new Line(pt1, pt2) { Layer = plateLayer, Linetype = Linetype.Dashed });
doc.Entities.Add(new Line(pt2, pt3) { Layer = plateLayer, Linetype = Linetype.Dashed });
doc.Entities.Add(new Line(pt3, pt4) { Layer = plateLayer, Linetype = Linetype.Dashed });
doc.Entities.Add(new Line(pt4, pt1) { Layer = plateLayer, Linetype = Linetype.Dashed });
} }
private void AddProgram(Program program) private void AddProgram(Program program)
{ {
mode = program.Mode; mode = program.Mode;
for (int i = 0; i < program.Length; ++i) for (var i = 0; i < program.Length; ++i)
{ {
var code = program[i]; var code = program[i];
@@ -212,55 +228,45 @@ namespace OpenNest.IO
private void AddLinearMove(LinearMove line) private void AddLinearMove(LinearMove line)
{ {
var pt = line.EndPoint.ToNetDxf(); var pt = line.EndPoint.ToAcadXYZ();
if (mode == Mode.Incremental) if (mode == Mode.Incremental)
pt += curpos; pt = new XYZ(pt.X + curpos.X, pt.Y + curpos.Y, 0);
var ln = new Line(curpos, pt); AddLine(curpos, pt, cutLayer);
ln.Layer = cutLayer;
doc.Entities.Add(ln);
curpos = pt; curpos = pt;
} }
private void AddRapidMove(RapidMove rapid) private void AddRapidMove(RapidMove rapid)
{ {
var pt = rapid.EndPoint.ToNetDxf(); var pt = rapid.EndPoint.ToAcadXYZ();
if (mode == Mode.Incremental) if (mode == Mode.Incremental)
pt += curpos; pt = new XYZ(pt.X + curpos.X, pt.Y + curpos.Y, 0);
var ln = new Line(curpos, pt); AddLine(curpos, pt, rapidLayer);
ln.Layer = rapidLayer;
doc.Entities.Add(ln);
curpos = pt; curpos = pt;
} }
private void AddArcMove(ArcMove arc) private void AddArcMove(ArcMove arc)
{ {
var center = arc.CenterPoint.ToNetDxf(); var center = arc.CenterPoint.ToAcadXYZ();
var endpt = arc.EndPoint.ToNetDxf(); var endpt = arc.EndPoint.ToAcadXYZ();
if (mode == Mode.Incremental) if (mode == Mode.Incremental)
{ {
endpt += curpos; endpt = new XYZ(endpt.X + curpos.X, endpt.Y + curpos.Y, 0);
center += curpos; center = new XYZ(center.X + curpos.X, center.Y + curpos.Y, 0);
} }
// start angle in radians
var startAngle = System.Math.Atan2( var startAngle = System.Math.Atan2(
curpos.Y - center.Y, curpos.Y - center.Y,
curpos.X - center.X); curpos.X - center.X);
// end angle in radians
var endAngle = System.Math.Atan2( var endAngle = System.Math.Atan2(
endpt.Y - center.Y, endpt.Y - center.Y,
endpt.X - center.X); endpt.X - center.X);
// convert the angles to degrees
startAngle = Angle.ToDegrees(startAngle);
endAngle = Angle.ToDegrees(endAngle);
if (arc.Rotation == OpenNest.RotationType.CW) if (arc.Rotation == OpenNest.RotationType.CW)
Generic.Swap(ref startAngle, ref endAngle); Generic.Swap(ref startAngle, ref endAngle);
@@ -271,13 +277,19 @@ namespace OpenNest.IO
if (startAngle.IsEqualTo(endAngle)) if (startAngle.IsEqualTo(endAngle))
{ {
var circle = new Circle(center, radius); var circle = new AcadCircle();
circle.Center = center;
circle.Radius = radius;
circle.Layer = cutLayer; circle.Layer = cutLayer;
doc.Entities.Add(circle); doc.Entities.Add(circle);
} }
else else
{ {
var arc2 = new Arc(center, radius, startAngle, endAngle); var arc2 = new AcadArc();
arc2.Center = center;
arc2.Radius = radius;
arc2.StartAngle = startAngle;
arc2.EndAngle = endAngle;
arc2.Layer = cutLayer; arc2.Layer = cutLayer;
doc.Entities.Add(arc2); doc.Entities.Add(arc2);
} }
+1 -1
View File
@@ -139,7 +139,7 @@ namespace OpenNest.IO
var lines = new List<Geometry.Line>(); var lines = new List<Geometry.Line>();
var center = new Vector(ellipse.Center.X, ellipse.Center.Y); var center = new Vector(ellipse.Center.X, ellipse.Center.Y);
var majorAxis = new Vector(ellipse.EndPoint.X, ellipse.EndPoint.Y); var majorAxis = new Vector(ellipse.MajorAxisEndPoint.X, ellipse.MajorAxisEndPoint.Y);
var majorLength = System.Math.Sqrt(majorAxis.X * majorAxis.X + majorAxis.Y * majorAxis.Y); var majorLength = System.Math.Sqrt(majorAxis.X * majorAxis.X + majorAxis.Y * majorAxis.Y);
var minorLength = majorLength * ellipse.RadiusRatio; var minorLength = majorLength * ellipse.RadiusRatio;
var rotation = System.Math.Atan2(majorAxis.Y, majorAxis.X); var rotation = System.Math.Atan2(majorAxis.Y, majorAxis.X);