GraphicsRenderer.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. using netDxf.Entities;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Media;
  9. using WpfShapes = System.Windows.Shapes;
  10. using DxfLine = netDxf.Entities.Line;
  11. using WpfLine = System.Windows.Shapes.Line;
  12. using DxfEllipse = netDxf.Entities.Ellipse;
  13. using WpfEllipse = System.Windows.Shapes.Ellipse;
  14. using WpfPoint = System.Windows.Point;
  15. namespace TeamAAS_VP.DxfModule
  16. {
  17. public class GraphicsRenderer
  18. {
  19. private const double DefaultStrokeThickness = 1.0;
  20. public static List<UIElement> RenderEntity(EntityObject entity, double scale = 1.0)
  21. {
  22. var elements = new List<UIElement>();
  23. switch (entity)
  24. {
  25. case DxfLine line:
  26. elements.Add(RenderLine(line, scale));
  27. break;
  28. case Circle circle:
  29. elements.Add(RenderCircle(circle, scale));
  30. break;
  31. case Arc arc:
  32. elements.Add(RenderArc(arc, scale));
  33. break;
  34. case netDxf.Entities.Point point:
  35. elements.Add(RenderPoint(point, scale));
  36. break;
  37. case Text text:
  38. elements.Add(RenderText(text, scale));
  39. break;
  40. case MText mtext:
  41. elements.Add(RenderMText(mtext, scale));
  42. break;
  43. case Spline spline:
  44. elements.AddRange(RenderSpline(spline, scale));
  45. break;
  46. }
  47. return elements;
  48. }
  49. private static UIElement RenderLine(DxfLine line, double scale)
  50. {
  51. var wpfLine = new WpfLine
  52. {
  53. X1 = line.StartPoint.X * scale,
  54. Y1 = -line.StartPoint.Y * scale, // Flip Y axis
  55. X2 = line.EndPoint.X * scale,
  56. Y2 = -line.EndPoint.Y * scale,
  57. Stroke = new SolidColorBrush(GetColor(line.Color)),
  58. StrokeThickness = DefaultStrokeThickness,
  59. Tag = line // Store original entity
  60. };
  61. return wpfLine;
  62. }
  63. private static UIElement RenderCircle(Circle circle, double scale)
  64. {
  65. var wpfEllipse = new WpfEllipse
  66. {
  67. Width = circle.Radius * 2 * scale,
  68. Height = circle.Radius * 2 * scale,
  69. Stroke = new SolidColorBrush(GetColor(circle.Color)),
  70. StrokeThickness = DefaultStrokeThickness,
  71. Fill = Brushes.Transparent,
  72. Tag = circle
  73. };
  74. System.Windows.Controls.Canvas.SetLeft(wpfEllipse, (circle.Center.X - circle.Radius) * scale);
  75. System.Windows.Controls.Canvas.SetTop(wpfEllipse, (-circle.Center.Y - circle.Radius) * scale);
  76. return wpfEllipse;
  77. }
  78. private static UIElement RenderArc(Arc arc, double scale)
  79. {
  80. var path = new WpfShapes.Path
  81. {
  82. Stroke = new SolidColorBrush(GetColor(arc.Color)),
  83. StrokeThickness = DefaultStrokeThickness,
  84. Fill = Brushes.Transparent,
  85. Tag = arc
  86. };
  87. var geometry = new PathGeometry();
  88. var figure = new PathFigure();
  89. // Calculate start and end points
  90. double startAngleRad = arc.StartAngle * Math.PI / 180.0;
  91. double endAngleRad = arc.EndAngle * Math.PI / 180.0;
  92. double startX = (arc.Center.X + arc.Radius * Math.Cos(startAngleRad)) * scale;
  93. double startY = (-arc.Center.Y - arc.Radius * Math.Sin(startAngleRad)) * scale;
  94. double endX = (arc.Center.X + arc.Radius * Math.Cos(endAngleRad)) * scale;
  95. double endY = (-arc.Center.Y - arc.Radius * Math.Sin(endAngleRad)) * scale;
  96. figure.StartPoint = new WpfPoint(startX, startY);
  97. var arcSegment = new ArcSegment
  98. {
  99. Point = new WpfPoint(endX, endY),
  100. Size = new System.Windows.Size(arc.Radius * scale, arc.Radius * scale),
  101. SweepDirection = SweepDirection.Counterclockwise,
  102. IsLargeArc = Math.Abs(arc.EndAngle - arc.StartAngle) > 180
  103. };
  104. figure.Segments.Add(arcSegment);
  105. geometry.Figures.Add(figure);
  106. path.Data = geometry;
  107. return path;
  108. }
  109. private static List<UIElement> RenderSpline(Spline spline, double scale)
  110. {
  111. var elements = new List<UIElement>();
  112. // Approximate spline with lines using control points
  113. var controlPoints = new List<netDxf.Vector3>(spline.ControlPoints);
  114. if (controlPoints.Count < 2)
  115. return elements;
  116. for (int i = 0; i < controlPoints.Count - 1; i++)
  117. {
  118. var p1 = controlPoints[i];
  119. var p2 = controlPoints[i + 1];
  120. var line = new WpfLine
  121. {
  122. X1 = p1.X * scale,
  123. Y1 = -p1.Y * scale,
  124. X2 = p2.X * scale,
  125. Y2 = -p2.Y * scale,
  126. Stroke = new SolidColorBrush(GetColor(spline.Color)),
  127. StrokeThickness = DefaultStrokeThickness,
  128. Tag = spline
  129. };
  130. elements.Add(line);
  131. }
  132. return elements;
  133. }
  134. private static UIElement RenderPoint(netDxf.Entities.Point point, double scale)
  135. {
  136. var ellipse = new WpfEllipse
  137. {
  138. Width = 3,
  139. Height = 3,
  140. Fill = new SolidColorBrush(GetColor(point.Color)),
  141. Tag = point
  142. };
  143. System.Windows.Controls.Canvas.SetLeft(ellipse, point.Position.X * scale - 1.5);
  144. System.Windows.Controls.Canvas.SetTop(ellipse, -point.Position.Y * scale - 1.5);
  145. return ellipse;
  146. }
  147. private static UIElement RenderText(Text text, double scale)
  148. {
  149. var textBlock = new System.Windows.Controls.TextBlock
  150. {
  151. Text = text.Value,
  152. Foreground = new SolidColorBrush(GetColor(text.Color)),
  153. FontSize = text.Height * scale,
  154. Tag = text
  155. };
  156. System.Windows.Controls.Canvas.SetLeft(textBlock, text.Position.X * scale);
  157. System.Windows.Controls.Canvas.SetTop(textBlock, -text.Position.Y * scale);
  158. return textBlock;
  159. }
  160. private static UIElement RenderMText(MText mtext, double scale)
  161. {
  162. var textBlock = new System.Windows.Controls.TextBlock
  163. {
  164. Text = mtext.Value,
  165. Foreground = new SolidColorBrush(GetColor(mtext.Color)),
  166. FontSize = mtext.Height * scale,
  167. Tag = mtext
  168. };
  169. System.Windows.Controls.Canvas.SetLeft(textBlock, mtext.Position.X * scale);
  170. System.Windows.Controls.Canvas.SetTop(textBlock, -mtext.Position.Y * scale);
  171. return textBlock;
  172. }
  173. private static Color GetColor(netDxf.AciColor aciColor)
  174. {
  175. // Convert DXF AciColor to WPF Color
  176. if (aciColor.IsByLayer || aciColor.IsByBlock)
  177. return Colors.White;
  178. var rgb = aciColor.ToColor();
  179. return Color.FromRgb(rgb.R, rgb.G, rgb.B);
  180. }
  181. public static void HighlightElement(UIElement element, bool isSelected)
  182. {
  183. if (element is WpfShapes.Shape shape)
  184. {
  185. if (isSelected)
  186. {
  187. shape.Stroke = Brushes.Yellow;
  188. shape.StrokeThickness = 2.0;
  189. }
  190. else
  191. {
  192. // Restore original color from entity
  193. if (shape.Tag is EntityObject entity)
  194. {
  195. shape.Stroke = new SolidColorBrush(GetColor(entity.Color));
  196. shape.StrokeThickness = DefaultStrokeThickness;
  197. }
  198. }
  199. }
  200. else if (element is System.Windows.Controls.TextBlock textBlock)
  201. {
  202. if (isSelected)
  203. {
  204. textBlock.Foreground = Brushes.Yellow;
  205. }
  206. else
  207. {
  208. if (textBlock.Tag is Text text)
  209. {
  210. textBlock.Foreground = new SolidColorBrush(GetColor(text.Color));
  211. }
  212. else if (textBlock.Tag is MText mtext)
  213. {
  214. textBlock.Foreground = new SolidColorBrush(GetColor(mtext.Color));
  215. }
  216. }
  217. }
  218. }
  219. }
  220. }