| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 | 
							- using System.Drawing;
 
- using System.Drawing.Drawing2D;
 
- using InABox.Core;
 
- using netDxf;
 
- using netDxf.Entities;
 
- using netDxf.Objects;
 
- using netDxf.Tables;
 
- using Svg;
 
- using Syncfusion.Pdf;
 
- namespace InABox.Dxf;
 
- public class DxfImportSettings
 
- {
 
-     public Size ImageSize;
 
-     public string[]? SupportFolders;
 
-     public string? LayoutName { get; set; }
 
-     public bool AutoFit { get; set; }
 
-     public DxfImportSettings(Size? imageSize = null, string[]? supportFolders = null, string? layoutName = null, bool autoFit = true)
 
-     {
 
-         AutoFit = autoFit;
 
-         ImageSize = imageSize ?? new(2048, 2048);
 
-         SupportFolders = supportFolders;
 
-         LayoutName = layoutName ?? "Model";
 
-     }
 
- }
 
- public class DxfData
 
- {
 
-     public DxfDocument Document { get; set; }
 
-     public DxfImportSettings Settings { get; set; }
 
-     public SizeF Size { get; set; }
 
-     public PointF Origin { get; set; }
 
-     public Layout Layout { get; set; }
 
-     public IEnumerable<string> LayoutNames => Document.Layouts.Select(x => x.Name);
 
-     public HashSet<string>? Layers { get; set; }
 
-     public bool HasLayer(Layer layer)
 
-     {
 
-         return Layers is null || Layers.Contains(layer.Name);
 
-     }
 
-     public void SetLayers(params string[] layers)
 
-     {
 
-         Layers = layers.ToHashSet();
 
-     }
 
-     public void SetLayers(IEnumerable<string> layers)
 
-     {
 
-         Layers = layers.ToHashSet();
 
-     }
 
-     public bool ShouldDraw(EntityObject obj)
 
-     {
 
-         return obj.IsVisible && HasLayer(obj.Layer);
 
-     }
 
-     public string LayoutName
 
-     {
 
-         get => Layout.Name;
 
-         set
 
-         {
 
-             Layout = Document.Layouts.First(x => x.Name == value);
 
-             UpdateSizeAndOrigin();
 
-         }
 
-     }
 
-     public DxfData(DxfDocument document, DxfImportSettings settings)
 
-     {
 
-         Document = document;
 
-         Settings = settings;
 
-         Layout = settings.LayoutName is not null ? document.Layouts.First(x => x.Name == settings.LayoutName) : document.Layouts.First();
 
-         UpdateSizeAndOrigin();
 
-     }
 
-     private void UpdateSizeAndOrigin()
 
-     {
 
-         if (Settings.AutoFit)
 
-         {
 
-             var bounds = DxfUtils.CalculateDxfSize(this) ?? new();
 
-             var margin = 0.1f * Math.Min(bounds.Width, bounds.Height);
 
-             if (bounds.IsEmpty)
 
-             {
 
-                 bounds.Size = new(100, 100);
 
-                 bounds.Location = new(0, 0);
 
-             }
 
-             else
 
-             {
 
-                 bounds.Size = new(bounds.Width + margin * 2, bounds.Height + margin * 2);
 
-                 bounds.Location = new(bounds.X - margin, bounds.Y - margin);
 
-             }
 
-             Size = bounds.Size;
 
-             Origin = bounds.Location;
 
-         }
 
-         else
 
-         {
 
-             Size = new((float)(Layout.MaxLimit.X - Layout.MinLimit.X), (float)(Layout.MaxLimit.Y - Layout.MinLimit.Y));
 
-             Origin = new((float)Layout.MinLimit.X, (float)Layout.MinLimit.Y);
 
-         }
 
-     }
 
- }
 
- public static class DxfUtils
 
- {
 
-     public static event ProcessError OnProcessError;
 
-     public delegate void ProcessError(string message);
 
-     internal static IDxfObject? ConvertEl(EntityObject el)
 
-     {
 
-         if(el is Line line)
 
-         {
 
-             return new DxfLine { Line = line };
 
-         }
 
-         else if(el is Insert insert)
 
-         {
 
-             return new DxfInsert(insert);
 
-         }
 
-         else if(el is Ellipse ellipse)
 
-         {
 
-             return new DxfEllipse(ellipse);
 
-         }
 
-         else if(el is MText text)
 
-         {
 
-             return new DxfMText(text);
 
-         }
 
-         else if(el is Polyline2D ln2D)
 
-         {
 
-             return new DxfPolyline2D(ln2D);
 
-         }
 
-         else if(el is Dimension dim)
 
-         {
 
-             return new DxfDimension(dim);
 
-         }
 
-         else if(el is Solid solid)
 
-         {
 
-             return new DxfSolid(solid);
 
-         }
 
-         else if (el is netDxf.Entities.Point point)
 
-         {
 
-             return null;
 
-         }
 
-         else if (el is netDxf.Entities.Viewport viewport)
 
-         {
 
-             return null;
 
-         }
 
-         else if (el is Arc a)
 
-         {
 
-             return new DxfArc(a);
 
-         }
 
-         else if(el is Text t)
 
-         {
 
-             return new DxfText(t);
 
-         }
 
-         else
 
-         {
 
-             return null;
 
-         }
 
-     }
 
-     public static void DrawDxf(DxfData data, IGraphics graphics, float width, float height)
 
-     {
 
-         // Calculate the scaling factor to fit the image within the bounds
 
-         float ratioX = (float)data.Settings.ImageSize.Width / data.Size.Width;
 
-         float ratioY = (float)data.Settings.ImageSize.Height / data.Size.Height;
 
-         var scale = Math.Min(ratioX, ratioY);
 
-         var drawData = new DrawData() { Graphics = graphics, Data = data };
 
-         graphics.Clear(Color.White);
 
-         // drawData.Translate(graphics.VisibleClipBounds.Width / 2, graphics.VisibleClipBounds.Height / 2);
 
-         drawData.Scale(scale, scale);
 
-         drawData.Translate(-data.Origin.X, -data.Origin.Y);
 
-         // drawData.Translate(-data.Origin.X - data.Size.Width / 2, -data.Origin.Y - data.Size.Height / 2);
 
-         foreach(var el in data.Layout.AssociatedBlock.Entities)
 
-         {
 
-             var item = ConvertEl(el);
 
-             item?.Draw(drawData);
 
-         }
 
-         graphics.Finish();
 
-     }
 
-     public static DxfData LoadDxf(string filename, DxfImportSettings? settings = null)
 
-     {
 
-         using var stream = new FileStream(filename, FileMode.Open, FileAccess.Read);
 
-         settings ??= new();
 
-         var document = DxfDocument.Load(stream, settings.SupportFolders ?? Array.Empty<string>());
 
-         document.BuildDimensionBlocks = true;
 
-         return new(document, settings);
 
-     }
 
-     public static DxfData LoadDxf(Stream stream, DxfImportSettings? settings = null)
 
-     {
 
-         settings ??= new();
 
-         var document = DxfDocument.Load(stream, settings.SupportFolders ?? Array.Empty<string>());
 
-         return new(document, settings);
 
-     }
 
-     /// <summary>
 
-     /// Returns <see langword="null"/> if the bounds are completely empty.
 
-     /// </summary>
 
-     /// <param name="data"></param>
 
-     /// <returns></returns>
 
-     public static RectangleF? CalculateDxfSize(DxfData data)
 
-     {
 
-         var transformData = new TransformData { Data = data };
 
-         RectangleF? bounds = null;
 
-         foreach(var el in data.Document.Entities.All)
 
-         {
 
-             if(ConvertEl(el) is IDxfObject obj)
 
-             {
 
-                 bounds = Utils.CombineBounds(bounds, obj.GetBounds(transformData));
 
-             }
 
-         }
 
-         return bounds;
 
-     }
 
-     public static Bitmap ProcessImage(DxfData data)
 
-     {
 
-         var height = data.Size.Height;
 
-         var width = data.Size.Width;
 
-         
 
-         // Calculate the scaling factor to fit the image within the bounds
 
-         float ratioX = (float)data.Settings.ImageSize.Width / width;
 
-         float ratioY = (float)data.Settings.ImageSize.Height / height;
 
-         var scale = Math.Min(ratioX, ratioY);
 
-         var _result = new Bitmap((int)(width * scale), (int)(height * scale));
 
-         using (var _graphics = Graphics.FromImage(_result))
 
-         {
 
-             _graphics.SmoothingMode = SmoothingMode.AntiAlias;
 
-             DrawDxf(data, new GdiGraphics(_graphics), _result.Width, _result.Height);
 
-         }
 
-         _result.RotateFlip(RotateFlipType.RotateNoneFlipY);
 
-         return _result;
 
-     }
 
-     public static PdfDocument ProcessPdf(DxfData data)
 
-     {
 
-         var doc = new PdfDocument();
 
-         doc.PageSettings.Size = data.Size;
 
-         doc.PageSettings.SetMargins(0);
 
-         var page = doc.Pages.Add();
 
-         var graphics = page.Graphics;
 
-         var drawData = new DrawData() { Graphics = new PdfGraphics(page.Graphics), Data = data };
 
-         drawData.PushTransform();
 
-         drawData.Translate(data.Size.Width / 2, data.Size.Height / 2);
 
-         drawData.Scale(1, -1);
 
-         drawData.Translate(-data.Size.Width / 2, -data.Size.Height / 2);
 
-         drawData.Translate(-data.Origin.X, -data.Origin.Y);
 
-         if (data.Layout.IsPaperSpace)
 
-         {
 
-             var modelSpace = data.Document.Layouts.First(x => x.Name == "Model");
 
-             foreach(var el in modelSpace.AssociatedBlock.Entities)
 
-             {
 
-                 var item = ConvertEl(el);
 
-                 item?.Draw(drawData);
 
-             }
 
-         }
 
-         foreach(var el in data.Layout.AssociatedBlock.Entities)
 
-         {
 
-             var item = ConvertEl(el);
 
-             item?.Draw(drawData);
 
-         }
 
-         drawData.PopTransform();
 
-         drawData.Graphics.Finish();
 
-         return doc;
 
-     }
 
-     // public static PdfDocument ProcessPdf(DxfData data)
 
-     // {
 
-     //     var doc = new PdfDocument();
 
-     //     var size = data.Size;
 
-     //     var origin = data.Origin;
 
-     //     foreach(var layout in data.LayoutNames)
 
-     //     {
 
-     //         data.LayoutName = layout;
 
-     //         Matrix4x4 transform;
 
-     //         if (data.Layout.IsPaperSpace)
 
-     //         {
 
-     //             var viewport = data.Layout.Viewport;
 
-     //             var scale = (float)(viewport.ViewHeight == 0 ? 0 : viewport.Height / viewport.ViewHeight);
 
-     //             data.Origin = new((float)(viewport.ViewCenter.X - viewport.Width / 2), (float)(viewport.ViewCenter.Y - viewport.Height / 2));
 
-     //             data.Size = new((float)viewport.Width, (float)viewport.Height);
 
-     //             var normal = -System.Numerics.Vector3.Cross(viewport.UcsXAxis.ToVec3(), viewport.UcsYAxis.ToVec3());
 
-     //             transform = Matrix4x4.CreateLookAt(viewport.UcsOrigin.ToVec3(), viewport.UcsOrigin.ToVec3() + normal, viewport.UcsYAxis.ToVec3())
 
-     //                 * Matrix4x4.CreateScale(scale)
 
-     //                 * Matrix4x4.CreateRotationZ((float)viewport.TwistAngle);
 
-     //         }
 
-     //         else
 
-     //         {
 
-     //             data.Size = size;
 
-     //             data.Origin = origin;
 
-     //             transform = Matrix4x4.Identity;
 
-     //         }
 
-     //         var section = doc.Sections.Add();
 
-     //         section.PageSettings.Size = data.Size;
 
-     //         section.PageSettings.SetMargins(0);
 
-     //         var page = section.Pages.Add();
 
-     //         var graphics = page.Graphics;
 
-     //         var drawData = new DrawData() { Graphics = new PdfGraphics(page.Graphics), Data = data };
 
-     //         drawData.PushTransform();
 
-     //         drawData.Translate(data.Size.Width / 2, data.Size.Height / 2);
 
-     //         drawData.Scale(1, -1);
 
-     //         drawData.Translate(-data.Size.Width / 2, -data.Size.Height / 2);
 
-     //         drawData.Translate(-data.Origin.X, -data.Origin.Y);
 
-     //         drawData.TransformBy(transform);
 
-     //         if (data.Layout.IsPaperSpace)
 
-     //         {
 
-     //             var modelSpace = data.Document.Layouts.First(x => x.Name == "Model");
 
-     //             foreach(var el in modelSpace.AssociatedBlock.Entities)
 
-     //             {
 
-     //                 var item = ConvertEl(el);
 
-     //                 item?.Draw(drawData);
 
-     //             }
 
-     //         }
 
-     //         foreach(var el in data.Layout.AssociatedBlock.Entities)
 
-     //         {
 
-     //             var item = ConvertEl(el);
 
-     //             item?.Draw(drawData);
 
-     //         }
 
-     //         drawData.PopTransform();
 
-     //         drawData.Graphics.Finish();
 
-     //     }
 
-     //     return doc;
 
-     // }
 
-     public static SvgDocument ProcessSvg(DxfData data)
 
-     {
 
-         var doc = new SvgDocument
 
-         {
 
-             ViewBox = new(data.Origin.X, data.Origin.Y, data.Size.Width, data.Size.Height)
 
-         };
 
-         var drawData = new DrawData() { Graphics = new SvgGraphics(doc), Data = data };
 
-         foreach(var el in data.Layout.AssociatedBlock.Entities)
 
-         {
 
-             var item = ConvertEl(el);
 
-             item?.Draw(drawData);
 
-         }
 
-         drawData.Graphics.Finish();
 
-         return doc;
 
-     }
 
-     public static Bitmap ProcessImage(Stream stream, DxfImportSettings? settings = null)
 
-     {
 
-         return ProcessImage(LoadDxf(stream, settings));
 
-     }
 
-     public static Result<Bitmap, Exception> DXFToBitmap(string filename, DxfImportSettings? settings = null)
 
-     {
 
-         using var stream = new FileStream(filename, FileMode.Open, FileAccess.Read);
 
-         try
 
-         {
 
-             return Result.Ok(ProcessImage(stream, settings: settings));
 
-         }
 
-         catch (Exception e)
 
-         {
 
-             OnProcessError?.Invoke(e.Message);
 
-             return Result.Error(e);
 
-         }
 
-     }
 
- }
 
 
  |