using ACadSharp; using ACadSharp.IO; using ACadSharp.Tables; using CSMath; using PepLib.Codes; using PepLib.Enums; using PepLib.Geometry; using PepLib.Models; using AcadArc = ACadSharp.Entities.Arc; using AcadCircle = ACadSharp.Entities.Circle; using AcadLine = ACadSharp.Entities.Line; namespace PepLib.IO; public static class DrawingDxfExporter { public static Stream Export(Drawing drawing) { var doc = new CadDocument(); foreach (var loop in drawing.Loops) { var layer = new Layer(loop.Name); doc.Layers.Add(layer); var pos = new Vector(); foreach (var code in loop) { switch (code.CodeType()) { case CodeType.RapidMove: pos = Advance(pos, ((RapidMove)code).EndPoint, loop.Mode); break; case CodeType.LinearMove: var lm = (LinearMove)code; var lineEnd = Advance(pos, lm.EndPoint, loop.Mode); doc.Entities.Add(new AcadLine { StartPoint = ToXYZ(pos), EndPoint = ToXYZ(lineEnd), Layer = layer }); pos = lineEnd; break; case CodeType.CircularMove: var cm = (CircularMove)code; var arcEnd = Advance(pos, cm.EndPoint, loop.Mode); var arcCenter = Advance(pos, cm.CenterPoint, loop.Mode); var dx = pos.X - arcCenter.X; var dy = pos.Y - arcCenter.Y; var radius = Math.Sqrt(dx * dx + dy * dy); var startAngle = Math.Atan2(pos.Y - arcCenter.Y, pos.X - arcCenter.X); var endAngle = Math.Atan2(arcEnd.Y - arcCenter.Y, arcEnd.X - arcCenter.X); if (cm.Rotation == RotationType.CW) { (startAngle, endAngle) = (endAngle, startAngle); } if (Math.Abs(startAngle - endAngle) < 1e-10) // full circle { doc.Entities.Add(new AcadCircle { Center = ToXYZ(arcCenter), Radius = radius, Layer = layer }); } else { doc.Entities.Add(new AcadArc { Center = ToXYZ(arcCenter), Radius = radius, StartAngle = startAngle * (180.0 / Math.PI), EndAngle = endAngle * (180.0 / Math.PI), Layer = layer }); } pos = arcEnd; break; } } } var buffer = new MemoryStream(); using (var writer = new DxfWriter(buffer, doc, false)) { writer.Write(); } var stream = new MemoryStream(buffer.ToArray()); return stream; } private static Vector Advance(Vector current, Vector offset, ProgrammingMode mode) => mode == ProgrammingMode.Incremental ? current + offset : offset; private static XYZ ToXYZ(Vector v) => new XYZ(v.X, v.Y, 0); }