|
|
@@ -0,0 +1,282 @@
|
|
|
+using netDxf.Entities;
|
|
|
+using OxyPlot;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using System.Windows;
|
|
|
+using System.Windows.Controls;
|
|
|
+using System.Windows.Data;
|
|
|
+using System.Windows.Documents;
|
|
|
+using System.Windows.Input;
|
|
|
+using System.Windows.Media;
|
|
|
+using System.Windows.Media.Imaging;
|
|
|
+using System.Windows.Navigation;
|
|
|
+using System.Windows.Shapes;
|
|
|
+using WpfLine = System.Windows.Shapes.Line;
|
|
|
+using DxfLine = netDxf.Entities.Line;
|
|
|
+using DxfLwPolyline = netDxf.Entities.Polyline2D;
|
|
|
+using Microsoft.Win32;
|
|
|
+
|
|
|
+namespace TeamAAS_VP.DxfModule
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// DxfView.xaml 的交互逻辑
|
|
|
+ /// </summary>
|
|
|
+ public partial class DxfView : UserControl
|
|
|
+ {
|
|
|
+ private DxfParserService _dxfParser;
|
|
|
+ private InteractionController _interactionController;
|
|
|
+ private double _currentScale = 1.0;
|
|
|
+ private double _zoomFactor = 1.2;
|
|
|
+
|
|
|
+ public DxfView()
|
|
|
+ {
|
|
|
+ InitializeComponent();
|
|
|
+ _dxfParser = new DxfParserService();
|
|
|
+ InitializeInteractionController();
|
|
|
+ }
|
|
|
+ private void InitializeInteractionController()
|
|
|
+ {
|
|
|
+ _interactionController = new InteractionController(DrawingCanvas);
|
|
|
+ _interactionController.SelectionChanged += OnSelectionChanged;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void BtnLoadDxf_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ var openFileDialog = new OpenFileDialog
|
|
|
+ {
|
|
|
+ Filter = "DXF文件 (*.dxf)|*.dxf|所有文件 (*.*)|*.*",
|
|
|
+ Title = "选择DXF文件"
|
|
|
+ };
|
|
|
+
|
|
|
+ if (openFileDialog.ShowDialog() == true)
|
|
|
+ {
|
|
|
+ LoadDxfFile(openFileDialog.FileName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void LoadDxfFile(string filePath)
|
|
|
+ {
|
|
|
+ TxtStatus.Text = "正在加载DXF文件...";
|
|
|
+
|
|
|
+ DrawingCanvas.Children.Clear();
|
|
|
+ _interactionController?.ClearSelection();
|
|
|
+
|
|
|
+ if (_dxfParser.LoadDxfFile(filePath))
|
|
|
+ {
|
|
|
+ var entities = _dxfParser.GetAllEntities();
|
|
|
+ TxtStatus.Text = $"成功加载: {System.IO.Path.GetFileName(filePath)}";
|
|
|
+ TxtEntityCount.Text = $"实体数: {entities.Count}";
|
|
|
+
|
|
|
+ // Calculate bounds and scale
|
|
|
+ var bounds = _dxfParser.GetBounds();
|
|
|
+ double boundsWidth = bounds.maxX - bounds.minX;
|
|
|
+ double boundsHeight = bounds.maxY - bounds.minY;
|
|
|
+
|
|
|
+ if (boundsWidth > 0 && boundsHeight > 0)
|
|
|
+ {
|
|
|
+ double scaleX = (DrawingCanvas.Width * 0.8) / boundsWidth;
|
|
|
+ double scaleY = (DrawingCanvas.Height * 0.8) / boundsHeight;
|
|
|
+ _currentScale = Math.Min(scaleX, scaleY);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Render entities
|
|
|
+ foreach (var entity in entities)
|
|
|
+ {
|
|
|
+ var renderedElements = GraphicsRenderer.RenderEntity(entity, _currentScale);
|
|
|
+ foreach (var element in renderedElements)
|
|
|
+ {
|
|
|
+ DrawingCanvas.Children.Add(element);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Center the drawing
|
|
|
+ CenterDrawing(bounds);
|
|
|
+
|
|
|
+ // Update statistics
|
|
|
+ UpdateStatistics();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ TxtStatus.Text = "加载DXF文件失败";
|
|
|
+ MessageBox.Show("无法加载DXF文件,请检查文件是否有效。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void CenterDrawing((double minX, double minY, double maxX, double maxY) bounds)
|
|
|
+ {
|
|
|
+ double centerX = (bounds.minX + bounds.maxX) / 2 * _currentScale;
|
|
|
+ double centerY = -(bounds.minY + bounds.maxY) / 2 * _currentScale;
|
|
|
+
|
|
|
+ double offsetX = DrawingCanvas.Width / 2 - centerX;
|
|
|
+ double offsetY = DrawingCanvas.Height / 2 - centerY;
|
|
|
+
|
|
|
+ // Translate all elements
|
|
|
+ foreach (UIElement element in DrawingCanvas.Children)
|
|
|
+ {
|
|
|
+ if (element is WpfLine line)
|
|
|
+ {
|
|
|
+ line.X1 += offsetX;
|
|
|
+ line.X2 += offsetX;
|
|
|
+ line.Y1 += offsetY;
|
|
|
+ line.Y2 += offsetY;
|
|
|
+ }
|
|
|
+ else if (element is FrameworkElement fe)
|
|
|
+ {
|
|
|
+ double left = Canvas.GetLeft(fe);
|
|
|
+ double top = Canvas.GetTop(fe);
|
|
|
+ Canvas.SetLeft(fe, left + offsetX);
|
|
|
+ Canvas.SetTop(fe, top + offsetY);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateStatistics()
|
|
|
+ {
|
|
|
+ var stats = _dxfParser.GetEntityStatistics();
|
|
|
+ var sb = new StringBuilder();
|
|
|
+
|
|
|
+ foreach (var stat in stats.OrderByDescending(s => s.Value))
|
|
|
+ {
|
|
|
+ if (stat.Value > 0)
|
|
|
+ {
|
|
|
+ sb.AppendLine($"{stat.Key}: {stat.Value}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ TxtStatistics.Text = sb.ToString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
+ {
|
|
|
+ TxtSelectedCount.Text = $"选中: {e.SelectedEntities.Count}";
|
|
|
+
|
|
|
+ var sb = new StringBuilder();
|
|
|
+
|
|
|
+ if (e.SelectedEntities.Count > 0)
|
|
|
+ {
|
|
|
+ sb.AppendLine($"已选择 {e.SelectedEntities.Count} 个图形实体:\n");
|
|
|
+
|
|
|
+ var grouped = e.SelectedEntities.GroupBy(entity => entity.Type.ToString());
|
|
|
+
|
|
|
+ foreach (var group in grouped)
|
|
|
+ {
|
|
|
+ sb.AppendLine($"{group.Key}: {group.Count()}");
|
|
|
+ }
|
|
|
+
|
|
|
+ sb.AppendLine("\n详细信息:");
|
|
|
+
|
|
|
+ int index = 1;
|
|
|
+ foreach (var entity in e.SelectedEntities.Take(10))
|
|
|
+ {
|
|
|
+ sb.AppendLine($"\n[{index}] {GetEntityInfo(entity)}");
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (e.SelectedEntities.Count > 10)
|
|
|
+ {
|
|
|
+ sb.AppendLine($"\n... 还有 {e.SelectedEntities.Count - 10} 个实体");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ sb.AppendLine("未选择任何图形");
|
|
|
+ }
|
|
|
+
|
|
|
+ TxtSelectedInfo.Text = sb.ToString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private string GetEntityInfo(EntityObject entity)
|
|
|
+ {
|
|
|
+ switch (entity)
|
|
|
+ {
|
|
|
+ case DxfLine line:
|
|
|
+ return $"直线: ({line.StartPoint.X:F2}, {line.StartPoint.Y:F2}) → ({line.EndPoint.X:F2}, {line.EndPoint.Y:F2})";
|
|
|
+ case Circle circle:
|
|
|
+ return $"圆: 中心({circle.Center.X:F2}, {circle.Center.Y:F2}), 半径={circle.Radius:F2}";
|
|
|
+ case Arc arc:
|
|
|
+ return $"圆弧: 中心({arc.Center.X:F2}, {arc.Center.Y:F2}), 半径={arc.Radius:F2}, 角度={arc.StartAngle:F1}°~{arc.EndAngle:F1}°";
|
|
|
+ case Text text:
|
|
|
+ return $"文本: \"{text.Value}\" 位置({text.Position.X:F2}, {text.Position.Y:F2})";
|
|
|
+ case MText mtext:
|
|
|
+ return $"多行文本: \"{mtext.Value}\" 位置({mtext.Position.X:F2}, {mtext.Position.Y:F2})";
|
|
|
+ case DxfLwPolyline lwPoly:
|
|
|
+ return $"轻量多段线: {lwPoly.Vertexes.Count} 个顶点{(lwPoly.IsClosed ? " (闭合)" : "")}";
|
|
|
+ case Spline spline:
|
|
|
+ // return $"样条曲线: {spline.ControlPoints.Count} 个控制点";
|
|
|
+ default:
|
|
|
+ return $"{entity.Type}: {entity.CodeName}";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void BtnClearSelection_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ _interactionController?.ClearSelection();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void BtnExtractSelected_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ var selectedEntities = _interactionController?.GetSelectedEntities();
|
|
|
+
|
|
|
+ if (selectedEntities == null || selectedEntities.Count == 0)
|
|
|
+ {
|
|
|
+ MessageBox.Show("请先选择要提取的图形。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var sb = new StringBuilder();
|
|
|
+ sb.AppendLine($"提取的图形信息 (共 {selectedEntities.Count} 个):\n");
|
|
|
+
|
|
|
+ var grouped = selectedEntities.GroupBy(p => p.Type.ToString());
|
|
|
+ foreach (var group in grouped)
|
|
|
+ {
|
|
|
+ sb.AppendLine($"\n{group.Key} ({group.Count()} 个):");
|
|
|
+ sb.AppendLine(new string('-', 50));
|
|
|
+
|
|
|
+ foreach (var entity in group)
|
|
|
+ {
|
|
|
+ sb.AppendLine(GetEntityInfo(entity));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ MessageBox.Show(sb.ToString(), "提取的图形信息", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void BtnZoomIn_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ Zoom(_zoomFactor);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void BtnZoomOut_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ Zoom(1.0 / _zoomFactor);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void BtnFitToScreen_Click(object sender, RoutedEventArgs e)
|
|
|
+ {
|
|
|
+ CanvasScaleTransform.ScaleX = 1.0;
|
|
|
+ CanvasScaleTransform.ScaleY = 1.0;
|
|
|
+ UpdateZoomDisplay();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void DrawingCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
|
|
|
+ {
|
|
|
+ double zoom = e.Delta > 0 ? _zoomFactor : 1.0 / _zoomFactor;
|
|
|
+ Zoom(zoom);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Zoom(double factor)
|
|
|
+ {
|
|
|
+ CanvasScaleTransform.ScaleX *= factor;
|
|
|
+ CanvasScaleTransform.ScaleY *= factor;
|
|
|
+ UpdateZoomDisplay();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateZoomDisplay()
|
|
|
+ {
|
|
|
+ TxtZoom.Text = $"缩放: {CanvasScaleTransform.ScaleX * 100:F0}%";
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|