DrawData.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. using netDxf;
  2. using netDxf.Tables;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using System.Linq;
  8. using System.Numerics;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using FontStyle = System.Drawing.FontStyle;
  12. using Vector2 = System.Numerics.Vector2;
  13. using Vector3 = System.Numerics.Vector3;
  14. using Vector4 = System.Numerics.Vector4;
  15. namespace InABox.Dxf;
  16. internal class TransformData
  17. {
  18. public DxfData Data { get; set; }
  19. private Stack<Matrix4x4> MatrixStack = new();
  20. public Matrix4x4 Transform { get; private set; } = Matrix4x4.Identity;
  21. public void PushTransform()
  22. {
  23. MatrixStack.Push(Transform);
  24. }
  25. protected virtual void UpdateTransform()
  26. {
  27. }
  28. protected Matrix ProjectMatrix(Matrix4x4 matrix)
  29. {
  30. var elMatrix = new Matrix3x2();
  31. elMatrix.M11 = (float)matrix.M11;
  32. elMatrix.M12 = (float)matrix.M12;
  33. elMatrix.M21 = (float)matrix.M21;
  34. elMatrix.M22 = (float)matrix.M22;
  35. elMatrix.M31 = (float)matrix.M41;
  36. elMatrix.M32 = (float)matrix.M42;
  37. var newMatrix = new Matrix();
  38. newMatrix.MatrixElements = elMatrix;
  39. return newMatrix;
  40. }
  41. public void PopTransform()
  42. {
  43. Transform = MatrixStack.Pop();
  44. UpdateTransform();
  45. }
  46. public static Matrix4x4 ArbitraryAxisMatrix(Vector3 zAxis)
  47. {
  48. if (zAxis.Equals(Vector3.UnitZ))
  49. {
  50. return Matrix4x4.Identity;
  51. }
  52. var unitY = Vector3.UnitY;
  53. var unitZ = Vector3.UnitZ;
  54. 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));
  55. v = Vector3.Normalize(v);
  56. var vector = Vector3.Cross(zAxis, v);
  57. vector = Vector3.Normalize(vector);
  58. 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);
  59. }
  60. public void ArbitraryAxis(netDxf.Vector3 zAxis)
  61. {
  62. Transform = ArbitraryAxisMatrix(new((float)zAxis.X, (float)zAxis.Y, (float)zAxis.Z)) * Transform;
  63. UpdateTransform();
  64. }
  65. public void ArbitraryAxis(Vector3 zAxis)
  66. {
  67. Transform = ArbitraryAxisMatrix(zAxis) * Transform;
  68. UpdateTransform();
  69. }
  70. public void Translate(float x, float y)
  71. {
  72. Transform = Transform.Translate(x, y, 0);
  73. UpdateTransform();
  74. }
  75. public void Translate(PointF point)
  76. {
  77. Transform = Transform.Translate(point.X, point.Y, 0);
  78. UpdateTransform();
  79. }
  80. public void Rotate(float angle)
  81. {
  82. Transform = Transform.Rotate(0, 0, 1, angle);
  83. UpdateTransform();
  84. }
  85. public void Scale(float scale)
  86. {
  87. Scale(scale, scale);
  88. }
  89. public void Scale(float scaleX, float scaleY)
  90. {
  91. Transform = Transform.Scale(scaleX, scaleY, 1);
  92. UpdateTransform();
  93. }
  94. public float ConvertThickness(float thickness)
  95. {
  96. return thickness == 0 ? 1f / ScaleFactor() : thickness;
  97. }
  98. public PointF TransformPoint(float x, float y)
  99. {
  100. var nVec = Vector4.Transform(new Vector4(x, y, 0, 1), Transform);
  101. return new(nVec.X, nVec.Y);
  102. }
  103. public PointF TransformPoint(PointF vec)
  104. {
  105. var nVec = Vector4.Transform(new Vector4(vec.X, vec.Y, 0, 1), Transform);
  106. return new(nVec.X, nVec.Y);
  107. }
  108. public PointF TransformPoint(netDxf.Vector2 vec)
  109. {
  110. var nVec = Vector4.Transform(new Vector4((float)vec.X, (float)vec.Y, 0, 1), Transform);
  111. return new(nVec.X, nVec.Y);
  112. }
  113. public PointF TransformPoint(netDxf.Vector3 vec)
  114. {
  115. var nVec = Vector4.Transform(new Vector4((float)vec.X, (float)vec.Y, (float)vec.Z, 1), Transform);
  116. return new(nVec.X, nVec.Y);
  117. }
  118. public PointF TransformVec(PointF vec)
  119. {
  120. var nVec = Vector4.Transform(new Vector4(vec.X, vec.Y, 0, 0), Transform);
  121. return new(nVec.X, nVec.Y);
  122. }
  123. public Vector2 TransformVec(Vector2 vec)
  124. {
  125. var nVec = Vector4.Transform(new Vector4(vec.X, vec.Y, 0, 0), Transform);
  126. return new(nVec.X, nVec.Y);
  127. }
  128. public float ScaleFactor()
  129. {
  130. return (TransformVec(new Vector2(1, 0))).Length();
  131. }
  132. public static PointF ConvertPoint(netDxf.Vector2 vec)
  133. {
  134. return new PointF((float)vec.X, (float)vec.Y);
  135. }
  136. public static PointF ConvertPoint(netDxf.Vector3 vec)
  137. {
  138. return new PointF((float)vec.X, (float)vec.Y);
  139. }
  140. }
  141. internal class DrawData : TransformData
  142. {
  143. public IGraphics Graphics { get; set; }
  144. protected override void UpdateTransform()
  145. {
  146. base.UpdateTransform();
  147. Graphics.SetTransform(ProjectMatrix(Transform));
  148. }
  149. }
  150. public interface IGraphics
  151. {
  152. void SetTransform(Matrix transform);
  153. void DrawLine(Color color, float thickness, params PointF[] points);
  154. void FillPolygon(Color color, params PointF[] points);
  155. /// <summary>
  156. /// Set the current font to be the default font at the given <paramref name="fontSize"/>.
  157. /// </summary>
  158. /// <param name="fontSize">Size of the new font.</param>
  159. void SetFont(float fontSize, FontStyle fontStyle = FontStyle.Regular);
  160. void SetFont(string fontName, float fontSize, FontStyle fontStyle = FontStyle.Regular);
  161. void DrawText(string text, Color color, PointF position);
  162. }
  163. public class GdiGraphics : IGraphics
  164. {
  165. public Graphics Graphics { get; set; }
  166. private Font Font { get; set; }
  167. public GdiGraphics(Graphics graphics)
  168. {
  169. Graphics = graphics;
  170. }
  171. public void DrawLine(Color color, float thickness, params PointF[] points)
  172. {
  173. if(points.Length == 2)
  174. {
  175. Graphics.DrawLine(new Pen(color, thickness), points[0], points[1]);
  176. }
  177. else
  178. {
  179. Graphics.DrawLines(new Pen(color, thickness), points);
  180. }
  181. }
  182. public void DrawText(string text, Color color, PointF position)
  183. {
  184. Graphics.DrawString(text, Font, new SolidBrush(color), position, StringFormat.GenericTypographic);
  185. }
  186. public void FillPolygon(Color color, params PointF[] points)
  187. {
  188. Graphics.FillPolygon(new SolidBrush(color), points);
  189. }
  190. public void SetFont(string fontName, float fontSize, FontStyle fontStyle)
  191. {
  192. var fontFamily = new FontFamily(fontName);
  193. var font = new Font(fontFamily, fontSize, fontStyle);
  194. Font = font;
  195. }
  196. public void SetFont(float fontSize, FontStyle fontStyle)
  197. {
  198. var fontFamily = SystemFonts.DefaultFont.FontFamily;
  199. var font = new Font(fontFamily, fontSize, fontStyle);
  200. Font = font;
  201. }
  202. public void SetTransform(Matrix transform)
  203. {
  204. Graphics.Transform = transform;
  205. }
  206. }