| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 | using netDxf;using netDxf.Tables;using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Drawing2D;using System.Linq;using System.Numerics;using System.Text;using System.Threading.Tasks;using FontStyle = System.Drawing.FontStyle;using Vector2 = System.Numerics.Vector2;using Vector3 = System.Numerics.Vector3;using Vector4 = System.Numerics.Vector4;namespace InABox.Dxf;internal class TransformData{    public DxfData Data { get; set; }    private Stack<Matrix4x4> MatrixStack = new();    public Matrix4x4 Transform { get; private set; } = Matrix4x4.Identity;    public void PushTransform()    {        MatrixStack.Push(Transform);    }    protected virtual void UpdateTransform()    {    }    protected Matrix ProjectMatrix(Matrix4x4 matrix)    {        var elMatrix = new Matrix3x2();        elMatrix.M11 = (float)matrix.M11;        elMatrix.M12 = (float)matrix.M12;        elMatrix.M21 = (float)matrix.M21;        elMatrix.M22 = (float)matrix.M22;        elMatrix.M31 = (float)matrix.M41;        elMatrix.M32 = (float)matrix.M42;        var newMatrix = new Matrix();        newMatrix.MatrixElements = elMatrix;        return newMatrix;    }    public void PopTransform()    {        Transform = MatrixStack.Pop();        UpdateTransform();    }    public static Matrix4x4 ArbitraryAxisMatrix(Vector3 zAxis)    {        if (zAxis.Equals(Vector3.UnitZ))        {            return Matrix4x4.Identity;        }        var unitY = Vector3.UnitY;        var unitZ = Vector3.UnitZ;        var v = ((!(Math.Abs(zAxis.X) < 1.0 / 64.0) || !(Math.Abs(zAxis.Y) < 1.0 / 64.0)) ? Vector3.Cross(unitZ, zAxis) : Vector3.Cross(unitY, zAxis));        v = Vector3.Normalize(v);        var vector = Vector3.Cross(zAxis, v);        vector = Vector3.Normalize(vector);        return new Matrix4x4(v.X, vector.X, zAxis.X, 0, v.Y, vector.Y, zAxis.Y, 0, v.Z, vector.Z, zAxis.Z, 0, 0, 0, 0, 1);    }    public void ArbitraryAxis(netDxf.Vector3 zAxis)    {        Transform = ArbitraryAxisMatrix(new((float)zAxis.X, (float)zAxis.Y, (float)zAxis.Z)) * Transform;        UpdateTransform();    }    public void ArbitraryAxis(Vector3 zAxis)    {        Transform = ArbitraryAxisMatrix(zAxis) * Transform;        UpdateTransform();    }    public void Translate(float x, float y)    {        Transform = Transform.Translate(x, y, 0);        UpdateTransform();    }    public void Translate(PointF point)    {        Transform = Transform.Translate(point.X, point.Y, 0);        UpdateTransform();    }    public void Rotate(float angle)    {        Transform = Transform.Rotate(0, 0, 1, angle);        UpdateTransform();    }    public void Scale(float scale)    {        Scale(scale, scale);    }    public void Scale(float scaleX, float scaleY)    {        Transform = Transform.Scale(scaleX, scaleY, 1);        UpdateTransform();    }    public float ConvertThickness(float thickness)    {        return thickness == 0 ? 1f / ScaleFactor() : thickness;    }    public PointF TransformPoint(float x, float y)    {        var nVec = Vector4.Transform(new Vector4(x, y, 0, 1), Transform);        return new(nVec.X, nVec.Y);    }    public PointF TransformPoint(PointF vec)    {        var nVec = Vector4.Transform(new Vector4(vec.X, vec.Y, 0, 1), Transform);        return new(nVec.X, nVec.Y);    }    public PointF TransformPoint(netDxf.Vector2 vec)    {        var nVec = Vector4.Transform(new Vector4((float)vec.X, (float)vec.Y, 0, 1), Transform);        return new(nVec.X, nVec.Y);    }    public PointF TransformPoint(netDxf.Vector3 vec)    {        var nVec = Vector4.Transform(new Vector4((float)vec.X, (float)vec.Y, (float)vec.Z, 1), Transform);        return new(nVec.X, nVec.Y);    }    public PointF TransformVec(PointF vec)    {        var nVec = Vector4.Transform(new Vector4(vec.X, vec.Y, 0, 0), Transform);        return new(nVec.X, nVec.Y);    }    public Vector2 TransformVec(Vector2 vec)    {        var nVec = Vector4.Transform(new Vector4(vec.X, vec.Y, 0, 0), Transform);        return new(nVec.X, nVec.Y);    }    public float ScaleFactor()    {        return (TransformVec(new Vector2(1, 0))).Length();    }    public static PointF ConvertPoint(netDxf.Vector2 vec)    {        return new PointF((float)vec.X, (float)vec.Y);    }    public static PointF ConvertPoint(netDxf.Vector3 vec)    {        return new PointF((float)vec.X, (float)vec.Y);    }}internal class DrawData : TransformData{    public IGraphics Graphics { get; set; }    protected override void UpdateTransform()    {        base.UpdateTransform();        Graphics.SetTransform(ProjectMatrix(Transform));    }}public interface IGraphics{    void SetTransform(Matrix transform);    void DrawLine(Color color, float thickness, params PointF[] points);    void FillPolygon(Color color, params PointF[] points);    /// <summary>    /// Set the current font to be the default font at the given <paramref name="fontSize"/>.    /// </summary>    /// <param name="fontSize">Size of the new font.</param>    void SetFont(float fontSize, FontStyle fontStyle = FontStyle.Regular);    void SetFont(string fontName, float fontSize, FontStyle fontStyle = FontStyle.Regular);    void DrawText(string text, Color color, PointF position);}public class GdiGraphics : IGraphics{    public Graphics Graphics { get; set; }    private Font Font { get; set; }    public GdiGraphics(Graphics graphics)    {        Graphics = graphics;    }    public void DrawLine(Color color, float thickness, params PointF[] points)    {        if(points.Length == 2)        {            Graphics.DrawLine(new Pen(color, thickness), points[0], points[1]);        }        else        {            Graphics.DrawLines(new Pen(color, thickness), points);        }    }    public void DrawText(string text, Color color, PointF position)    {        Graphics.DrawString(text, Font, new SolidBrush(color), position, StringFormat.GenericTypographic);    }    public void FillPolygon(Color color, params PointF[] points)    {        Graphics.FillPolygon(new SolidBrush(color), points);    }    public void SetFont(string fontName, float fontSize, FontStyle fontStyle)    {        var fontFamily = new FontFamily(fontName);        var font = new Font(fontFamily, fontSize, fontStyle);        Font = font;    }    public void SetFont(float fontSize, FontStyle fontStyle)    {        var fontFamily = SystemFonts.DefaultFont.FontFamily;        var font = new Font(fontFamily, fontSize, fontStyle);        Font = font;    }    public void SetTransform(Matrix transform)    {        Graphics.Transform = transform;    }}
 |