| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 | using InABox.Core;using netDxf;using netDxf.Blocks;using netDxf.Entities;using System;using System.Collections.Generic;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InABox.Dxf;internal interface IDxfObject{    void Draw(DrawData data);    RectangleF? GetBounds(TransformData data);}internal class DxfLine : IDxfObject{    public Line Line { get; set; }    public void Draw(DrawData data)    {        if (!data.Data.ShouldDraw(Line)) return;        data.PushTransform();        //data.ArbitraryAxis(Line.Normal);        data.Graphics.DrawLine(            data.ResolveColour(Line.Color, Line), (float)Line.Thickness,            DrawData.ConvertPoint(Line.StartPoint), DrawData.ConvertPoint(Line.EndPoint));        data.PopTransform();    }    public RectangleF? GetBounds(TransformData data)    {        if (!data.Data.ShouldDraw(Line)) return null;        return Utils.RectangleFromPoints(            data.TransformPoint(Line.StartPoint),            data.TransformPoint(Line.EndPoint));    }}internal class DxfInsert : IDxfObject{    public Insert Insert { get; set; }    public List<IDxfObject> Objects { get; set; }    public DxfInsert(Insert insert)    {        Insert = insert;        Objects = insert.Block.Entities.Select(DxfUtils.ConvertEl).NotNull().ToList();    }    public void Draw(DrawData data)    {        if (!data.Data.ShouldDraw(Insert)) return;        // var transformation = Insert.GetTransformation();        // var translation = Insert.Position - transformation * Insert.Block.Origin;        data.PushTransform();        data.Translate(new PointF((float)Insert.Position.X, (float)Insert.Position.Y));        data.ArbitraryAxis(Insert.Normal);        data.Rotate((float)Insert.Rotation);        data.Scale((float)Insert.Scale.X, (float)Insert.Scale.Y);        data.PushBlockColour(Insert.Color, Insert);        foreach(var entity in Objects)        {            entity.Draw(data);        }        data.PopBlockColour();        data.PopTransform();        // foreach(var entity in Insert.Explode())        // {        //     // var ent = entity.Clone() as EntityObject;        //     // ent.TransformBy(transformation, translation);        //     DxfUtils.ConvertEl(entity)?.Draw(data);        // }        // foreach(var obj in Insert.Explode())        // {        //     DxfUtils.ConvertEl(obj)?.Draw(data);        // }    }    public RectangleF? GetBounds(TransformData data)    {        if (!data.Data.ShouldDraw(Insert)) return null;        data.PushTransform();        data.Translate(new PointF((float)Insert.Position.X, (float)Insert.Position.Y));        data.ArbitraryAxis(Insert.Normal);        data.Rotate((float)Insert.Rotation);        data.Scale((float)Insert.Scale.X, (float)Insert.Scale.Y);        var bounds = Utils.CombineBounds(Objects.Select(x => x.GetBounds(data)));        data.PopTransform();        return bounds;    }}internal class DxfArc : IDxfObject{    public Arc Arc { get; set; }    public DxfArc(Arc arc)    {        Arc = arc;    }    public void Draw(DrawData data)    {        if (!data.Data.ShouldDraw(Arc)) return;        foreach(var obj in Arc.ToPolyline2D(100).Explode())        {            DxfUtils.ConvertEl(obj)?.Draw(data);        }    }    public RectangleF? GetBounds(TransformData data)    {        if (!data.Data.ShouldDraw(Arc)) return null;        var halfSize = new netDxf.Vector3(Arc.Radius, Arc.Radius, 0);        return Utils.RectangleFromPoints(            data.TransformPoint(Arc.Center - halfSize),            data.TransformPoint(Arc.Center + halfSize));    }}internal class DxfEllipse : IDxfObject{    public Ellipse Ellipse { get; set; }    public DxfEllipse(Ellipse ellipse)    {        Ellipse = ellipse;    }    public void Draw(DrawData data)    {        if (!data.Data.ShouldDraw(Ellipse)) return;        foreach(var obj in Ellipse.ToPolyline2D(100).Explode())        {            DxfUtils.ConvertEl(obj)?.Draw(data);        }        // var center = DrawData.ConvertPoint(Ellipse.Center);        // var size = new SizeF((float)Ellipse.MajorAxis, (float)Ellipse.MinorAxis);        // var startAngle = (float)(Ellipse.StartAngle);        // var endAngle = (float)(Ellipse.EndAngle);        // data.Graphics.DrawArc(new Pen(Color.Black, data.ConvertThickness((float)Ellipse.Thickness)), center.X - size.Width / 2, center.Y - size.Height / 2, size.Width, size.Height, startAngle, Utils.Mod(endAngle - startAngle, 360));    }    public RectangleF? GetBounds(TransformData data)    {        if (!data.Data.ShouldDraw(Ellipse)) return null;        var halfSize = new netDxf.Vector3(Ellipse.MajorAxis / 2, Ellipse.MinorAxis / 2, 0);        return Utils.RectangleFromPoints(            data.TransformPoint(Ellipse.Center - halfSize),            data.TransformPoint(Ellipse.Center + halfSize));    }}internal class DxfSolid : IDxfObject{    public Solid Solid { get; set; }    public DxfSolid(Solid solid)    {        Solid = solid;    }    public void Draw(DrawData data)    {        if (!data.Data.ShouldDraw(Solid)) return;        var vertices = new Vector2[]        {            Solid.FirstVertex,            Solid.SecondVertex,            Solid.FourthVertex, // Apparently the third and fourth are the wrong way round, so I've mirrored that here.            Solid.ThirdVertex        };        data.Graphics.FillPolygon(data.ResolveColour(Solid.Color, Solid), vertices.ToArray(x => DrawData.ConvertPoint(x)));    }    public RectangleF? GetBounds(TransformData data)    {        if (!data.Data.ShouldDraw(Solid)) return null;        var vertices = new Vector2[]        {            Solid.FirstVertex,            Solid.SecondVertex,            Solid.FourthVertex, // Apparently the third and fourth are the wrong way round, so I've mirrored that here.            Solid.ThirdVertex        };        return Utils.RectangleFromPoints(            vertices.ToArray(data.TransformPoint));    }}internal class DxfPolyline2D : IDxfObject{    public Polyline2D Polyline { get; set; }    public DxfPolyline2D(Polyline2D polyline)    {        Polyline = polyline;    }    public void Draw(DrawData data)    {        if (!data.Data.ShouldDraw(Polyline)) return;        var entities = Polyline.Explode();        foreach(var entity in entities)        {            DxfUtils.ConvertEl(entity)?.Draw(data);        }        // if(Polyline.SmoothType == PolylineSmoothType.NoSmooth)        // {        //     var vertices = Polyline.Vertexes.ToArray(x => new PointF((float)x.Position.X, (float)x.Position.Y));        //     if (Polyline.IsClosed)        //     {        //         data.Graphics.DrawPolygon(        //             new Pen(Color.Black, data.ConvertThickness((float)Polyline.Thickness)),        //             vertices);        //     }        //     else        //     {        //         data.Graphics.DrawLines(        //             new Pen(Color.Black, data.ConvertThickness((float)Polyline.Thickness)),        //             vertices);        //     }        // }        // else        // {        // }    }    public RectangleF? GetBounds(TransformData data)    {        if (!data.Data.ShouldDraw(Polyline)) return null;        var entities = Polyline.Explode();        return Utils.CombineBounds(entities.Select(x => DxfUtils.ConvertEl(x)?.GetBounds(data)));    }}internal class DxfMText : IDxfObject{    public MText MText { get; set; }    public DxfMText(MText text)    {        MText = text;    }    private Font GetFont()    {        FontFamily fontFamily;        if (MText.Style.FontFamilyName.IsNullOrWhiteSpace())        {            fontFamily = SystemFonts.DefaultFont.FontFamily;        }        else        {            fontFamily = new FontFamily(MText.Style.FontFamilyName);        }        return new Font(fontFamily, (float)MText.Height, MText.Style.FontStyle switch        {            netDxf.Tables.FontStyle.Bold => FontStyle.Bold,            netDxf.Tables.FontStyle.Italic => FontStyle.Italic,            netDxf.Tables.FontStyle.Regular or _ => FontStyle.Regular,        });    }    private string GetText()    {        return MText.PlainText().Replace("^M", "");    }    private static Bitmap _placeholderBitmap = new Bitmap(1, 1);    private void Transform(TransformData data, Font font, string text, Graphics g)    {        data.Translate(new PointF((float)MText.Position.X, (float)MText.Position.Y));        data.Rotate((float)MText.Rotation);        data.Scale(1, -1);        var size = g.MeasureString(text, font, new PointF(), StringFormat.GenericTypographic);        switch (MText.AttachmentPoint)        {            case MTextAttachmentPoint.MiddleLeft:            case MTextAttachmentPoint.MiddleCenter:            case MTextAttachmentPoint.MiddleRight:                data.Translate(new PointF(0, -size.Height / 2));                break;            case MTextAttachmentPoint.BottomLeft:            case MTextAttachmentPoint.BottomCenter:            case MTextAttachmentPoint.BottomRight:                data.Translate(new PointF(0, -size.Height));                break;            default:                var ascent = font.FontFamily.GetCellAscent(font.Style);                var lineSpace = font.FontFamily.GetLineSpacing(font.Style);                var baseline = ascent * font.Height / font.FontFamily.GetEmHeight(font.Style);                var ratio = font.GetHeight(g) / lineSpace;                data.Translate(new PointF(0, -baseline + ascent * ratio));                break;        }        switch (MText.AttachmentPoint)        {            case MTextAttachmentPoint.TopLeft:            case MTextAttachmentPoint.MiddleLeft:            case MTextAttachmentPoint.BottomLeft:                break;            case MTextAttachmentPoint.TopCenter:            case MTextAttachmentPoint.MiddleCenter:            case MTextAttachmentPoint.BottomCenter:                data.Translate(new PointF(-(float)size.Width / 2, 0));                break;            case MTextAttachmentPoint.TopRight:            case MTextAttachmentPoint.MiddleRight:            case MTextAttachmentPoint.BottomRight:                data.Translate(new PointF(-(float)size.Width, 0));                break;        }    }    public void Draw(DrawData data)    {        if (!data.Data.ShouldDraw(MText)) return;        var text = GetText();        if (MText.Style.FontFamilyName.IsNullOrWhiteSpace())        {            data.Graphics.SetFont((float)MText.Height, MText.Style.FontStyle switch            {                netDxf.Tables.FontStyle.Bold => FontStyle.Bold,                netDxf.Tables.FontStyle.Italic => FontStyle.Italic,                netDxf.Tables.FontStyle.Regular or _ => FontStyle.Regular,            });        }        else        {            data.Graphics.SetFont(MText.Style.FontFamilyName, (float)MText.Height, MText.Style.FontStyle switch            {                netDxf.Tables.FontStyle.Bold => FontStyle.Bold,                netDxf.Tables.FontStyle.Italic => FontStyle.Italic,                netDxf.Tables.FontStyle.Regular or _ => FontStyle.Regular,            });        }        var format = new TextFormat        {            LineAlignment = MText.AttachmentPoint switch            {                MTextAttachmentPoint.MiddleLeft or MTextAttachmentPoint.MiddleCenter or MTextAttachmentPoint.MiddleRight => TextLineAlignment.Center,                MTextAttachmentPoint.BottomLeft or MTextAttachmentPoint.BottomCenter or MTextAttachmentPoint.BottomRight => TextLineAlignment.Bottom,                _ => TextLineAlignment.Top,            },            Alignment = MText.AttachmentPoint switch            {                MTextAttachmentPoint.TopCenter or MTextAttachmentPoint.MiddleCenter or MTextAttachmentPoint.BottomCenter => TextAlignment.Center,                MTextAttachmentPoint.TopRight or MTextAttachmentPoint.MiddleRight or MTextAttachmentPoint.BottomRight => TextAlignment.Right,                _ => TextAlignment.Left,            }        };        data.Graphics.DrawText(text, data.ResolveColour(MText.Color, MText), DrawData.ConvertPoint(MText.Position), (float)MText.Rotation, format);    }    public RectangleF? GetBounds(TransformData data)    {        if (!data.Data.ShouldDraw(MText)) return null;        var font = GetFont();        var text = GetText();        data.PushTransform();        using var g = Graphics.FromImage(_placeholderBitmap);        Transform(data, font, text, g);        var size = g.MeasureString(text, font, new PointF(), StringFormat.GenericTypographic);        var bounds = Utils.RectangleFromPoints(            data.TransformPoint(0, 0),            data.TransformPoint(size.Width, size.Height));        data.PopTransform();        return bounds;    }}internal class DxfDimension : IDxfObject{    public Dimension Dimension { get; set; }    public List<IDxfObject> Objects { get; set; }    public DxfDimension(Dimension dimension)    {        Dimension = dimension;        if(Dimension.Block is null)        {            Objects = new();        }        else        {            Objects = Dimension.Block.Entities.Select(DxfUtils.ConvertEl).NotNull().ToList();        }    }    public void Draw(DrawData data)    {        if (!data.Data.ShouldDraw(Dimension)) return;        data.PushBlockColour(Dimension.Color, Dimension);        foreach(var entity in Objects)        {            entity.Draw(data);        }        data.PopBlockColour();    }    public RectangleF? GetBounds(TransformData data)    {        if (!data.Data.ShouldDraw(Dimension)) return null;        return Utils.CombineBounds(Objects.Select(x => x.GetBounds(data)));    }}
 |