Objects.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. using InABox.Core;
  2. using netDxf;
  3. using netDxf.Entities;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Data;
  7. using System.Drawing;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. namespace InABox.Dxf;
  12. internal interface IDxfObject
  13. {
  14. void Draw(DrawData data);
  15. }
  16. internal class DxfLine : IDxfObject
  17. {
  18. public Line Line { get; set; }
  19. public void Draw(DrawData data)
  20. {
  21. if (!Line.IsVisible || !data.Data.HasLayer(Line.Layer)) return;
  22. data.Graphics.DrawLine(new Pen(Color.Black, data.ConvertThickness((float)Line.Thickness)), DrawData.ConvertPoint(Line.StartPoint), DrawData.ConvertPoint(Line.EndPoint));
  23. }
  24. }
  25. internal class DxfInsert : IDxfObject
  26. {
  27. public Insert Insert { get; set; }
  28. public List<IDxfObject> Objects { get; set; }
  29. public DxfInsert(Insert insert)
  30. {
  31. Insert = insert;
  32. Objects = insert.Block.Entities.Select(DxfUtils.ConvertEl).NotNull().ToList();
  33. }
  34. public void Draw(DrawData data)
  35. {
  36. if (!Insert.IsVisible || !data.Data.HasLayer(Insert.Layer)) return;
  37. var transformation = Insert.GetTransformation();
  38. var translation = Insert.Position - transformation * Insert.Block.Origin;
  39. foreach(var entity in Insert.Block.Entities)
  40. {
  41. entity.TransformBy(transformation, translation);
  42. DxfUtils.ConvertEl(entity)?.Draw(data);
  43. }
  44. // foreach(var obj in Insert.Explode())
  45. // {
  46. // DxfUtils.ConvertEl(obj)?.Draw(data);
  47. // }
  48. }
  49. }
  50. internal class DxfEllipse : IDxfObject
  51. {
  52. public Ellipse Ellipse { get; set; }
  53. public DxfEllipse(Ellipse ellipse)
  54. {
  55. Ellipse = ellipse;
  56. }
  57. public void Draw(DrawData data)
  58. {
  59. if (!Ellipse.IsVisible || !data.Data.HasLayer(Ellipse.Layer)) return;
  60. foreach(var obj in Ellipse.ToPolyline2D(100).Explode())
  61. {
  62. DxfUtils.ConvertEl(obj)?.Draw(data);
  63. }
  64. // var center = DrawData.ConvertPoint(Ellipse.Center);
  65. // var size = new SizeF((float)Ellipse.MajorAxis, (float)Ellipse.MinorAxis);
  66. // var startAngle = (float)(Ellipse.StartAngle);
  67. // var endAngle = (float)(Ellipse.EndAngle);
  68. // 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));
  69. }
  70. }
  71. internal class DxfSolid : IDxfObject
  72. {
  73. public Solid Solid { get; set; }
  74. public DxfSolid(Solid solid)
  75. {
  76. Solid = solid;
  77. }
  78. public void Draw(DrawData data)
  79. {
  80. if (!Solid.IsVisible || !data.Data.HasLayer(Solid.Layer)) return;
  81. var vertices = new Vector2[]
  82. {
  83. Solid.FirstVertex,
  84. Solid.SecondVertex,
  85. Solid.FourthVertex, // Apparently the third and fourth are the wrong way round, so I've mirrored that here.
  86. Solid.ThirdVertex
  87. };
  88. data.Graphics.FillPolygon(new SolidBrush(Color.Black), vertices.ToArray(x => DrawData.ConvertPoint(x)));
  89. }
  90. }
  91. internal class DxfPolyline2D : IDxfObject
  92. {
  93. public Polyline2D Polyline { get; set; }
  94. public DxfPolyline2D(Polyline2D polyline)
  95. {
  96. Polyline = polyline;
  97. }
  98. public void Draw(DrawData data)
  99. {
  100. if (!Polyline.IsVisible || !data.Data.HasLayer(Polyline.Layer)) return;
  101. var entities = Polyline.Explode();
  102. foreach(var entity in entities)
  103. {
  104. DxfUtils.ConvertEl(entity)?.Draw(data);
  105. }
  106. // if(Polyline.SmoothType == PolylineSmoothType.NoSmooth)
  107. // {
  108. // var vertices = Polyline.Vertexes.ToArray(x => new PointF((float)x.Position.X, (float)x.Position.Y));
  109. // if (Polyline.IsClosed)
  110. // {
  111. // data.Graphics.DrawPolygon(
  112. // new Pen(Color.Black, data.ConvertThickness((float)Polyline.Thickness)),
  113. // vertices);
  114. // }
  115. // else
  116. // {
  117. // data.Graphics.DrawLines(
  118. // new Pen(Color.Black, data.ConvertThickness((float)Polyline.Thickness)),
  119. // vertices);
  120. // }
  121. // }
  122. // else
  123. // {
  124. // }
  125. }
  126. }
  127. internal class DxfMText : IDxfObject
  128. {
  129. public MText MText { get; set; }
  130. public DxfMText(MText text)
  131. {
  132. MText = text;
  133. }
  134. public void Draw(DrawData data)
  135. {
  136. if (!MText.IsVisible || !data.Data.HasLayer(MText.Layer)) return;
  137. Font font;
  138. if (MText.Style.FontFamilyName.IsNullOrWhiteSpace())
  139. {
  140. font = SystemFonts.DefaultFont;
  141. }
  142. else
  143. {
  144. var fontFamily = new FontFamily(MText.Style.FontFamilyName);
  145. font = new Font(fontFamily, (float)MText.Height, MText.Style.FontStyle switch
  146. {
  147. netDxf.Tables.FontStyle.Bold => FontStyle.Bold,
  148. netDxf.Tables.FontStyle.Italic => FontStyle.Italic,
  149. netDxf.Tables.FontStyle.Regular or _ => FontStyle.Regular,
  150. });
  151. }
  152. var text = MText.PlainText().Replace("^M", "");
  153. data.PushTransform();
  154. data.Translate(new PointF((float)MText.Position.X, (float)MText.Position.Y));
  155. data.Rotate((float)MText.Rotation);
  156. data.Scale(1, -1);
  157. var size = data.Graphics.MeasureString(text, font, new PointF(), StringFormat.GenericTypographic);
  158. switch (MText.AttachmentPoint)
  159. {
  160. case MTextAttachmentPoint.MiddleLeft:
  161. case MTextAttachmentPoint.MiddleCenter:
  162. case MTextAttachmentPoint.MiddleRight:
  163. data.Translate(new PointF(0, -size.Height / 2));
  164. break;
  165. case MTextAttachmentPoint.BottomLeft:
  166. case MTextAttachmentPoint.BottomCenter:
  167. case MTextAttachmentPoint.BottomRight:
  168. data.Translate(new PointF(0, -size.Height));
  169. break;
  170. default:
  171. var ascent = font.FontFamily.GetCellAscent(font.Style);
  172. var lineSpace = font.FontFamily.GetLineSpacing(font.Style);
  173. var baseline = ascent * font.Height / font.FontFamily.GetEmHeight(font.Style);
  174. var ratio = font.GetHeight(data.Graphics) / lineSpace;
  175. data.Translate(new PointF(0, -baseline + ascent * ratio));
  176. break;
  177. }
  178. switch (MText.AttachmentPoint)
  179. {
  180. case MTextAttachmentPoint.TopLeft:
  181. case MTextAttachmentPoint.MiddleLeft:
  182. case MTextAttachmentPoint.BottomLeft:
  183. break;
  184. case MTextAttachmentPoint.TopCenter:
  185. case MTextAttachmentPoint.MiddleCenter:
  186. case MTextAttachmentPoint.BottomCenter:
  187. data.Translate(new PointF(-(float)size.Width / 2, 0));
  188. break;
  189. case MTextAttachmentPoint.TopRight:
  190. case MTextAttachmentPoint.MiddleRight:
  191. case MTextAttachmentPoint.BottomRight:
  192. data.Translate(new PointF(-(float)size.Width, 0));
  193. break;
  194. }
  195. data.Graphics.DrawString(text, font, new SolidBrush(Color.Black), new PointF(0, 0), StringFormat.GenericTypographic);
  196. data.PopTransform();
  197. }
  198. }
  199. internal class DxfDimension : IDxfObject
  200. {
  201. public Dimension Dimension { get; set; }
  202. public DxfDimension(Dimension dimension)
  203. {
  204. Dimension = dimension;
  205. }
  206. public void Draw(DrawData data)
  207. {
  208. if (!Dimension.IsVisible || !data.Data.HasLayer(Dimension.Layer)) return;
  209. if(Dimension.Block is null)
  210. {
  211. return;
  212. }
  213. var entities = Dimension.Block.Entities;
  214. foreach(var entity in entities)
  215. {
  216. DxfUtils.ConvertEl(entity)?.Draw(data);
  217. }
  218. }
  219. }