diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj index aa9703b..63de6d3 100644 --- a/NavisworksTransportPlugin.csproj +++ b/NavisworksTransportPlugin.csproj @@ -283,6 +283,7 @@ + diff --git a/doc/requirement/todo_features.md b/doc/requirement/todo_features.md index 9b7750a..f6fc845 100644 --- a/doc/requirement/todo_features.md +++ b/doc/requirement/todo_features.md @@ -2,6 +2,14 @@ ## 功能点 +### [2026/1/18] + +1. [x] (功能)实现吊装路径,支持3步吊运过程 +2. [x] (功能)给移动到起点的虚拟车辆或物体增加调整角度能力 +3. [x] (优化)在自动路径规划的几何体获取过程中,过滤隐藏项,提高性能 +4. [x] (功能)在碰撞检测报告中,增加碰撞结果截图 +5. [x] (功能)实现多条路径碰撞检测的批处理 + ### [2026/1/13] 1. [x] (优化)检查API调用的线程安全问题,提高插件的稳定性 diff --git a/src/Commands/GenerateCollisionReportCommand.cs b/src/Commands/GenerateCollisionReportCommand.cs index 226c7d8..8b42bf1 100644 --- a/src/Commands/GenerateCollisionReportCommand.cs +++ b/src/Commands/GenerateCollisionReportCommand.cs @@ -86,6 +86,12 @@ namespace NavisworksTransport.Commands public int FrameRate { get; set; } public double Duration { get; set; } public double DetectionGap { get; set; } + + // 新增:截图信息 + public string ScreenshotPath { get; set; } + public string ScreenshotFormat { get; set; } + public int ScreenshotWidth { get; set; } + public int ScreenshotHeight { get; set; } } /// @@ -228,6 +234,34 @@ namespace NavisworksTransport.Commands } } + UpdateProgress(95, "生成碰撞场景截图..."); + + // 自动生成默认截图(1920x1080, JPG格式) + try + { + string screenshotPath = PathHelper.GenerateSceneScreenshot( + result.PathName ?? "collision", + 1920, + 1080, + System.Drawing.Imaging.ImageFormat.Jpeg, + "collision" + ); + + if (screenshotPath != null) + { + result.ScreenshotPath = screenshotPath; + result.ScreenshotFormat = "JPG"; + result.ScreenshotWidth = 1920; + result.ScreenshotHeight = 1080; + LogManager.Info($"碰撞场景截图已自动生成: {screenshotPath}"); + } + } + catch (Exception ex) + { + LogManager.Error($"自动生成碰撞场景截图失败: {ex.Message}"); + // 截图失败不影响报告生成 + } + UpdateProgress(100, "报告生成完成"); // 显示报告(UI线程) diff --git a/src/UI/WPF/ViewModels/CollisionReportViewModel.cs b/src/UI/WPF/ViewModels/CollisionReportViewModel.cs index b848749..6fce5f7 100644 --- a/src/UI/WPF/ViewModels/CollisionReportViewModel.cs +++ b/src/UI/WPF/ViewModels/CollisionReportViewModel.cs @@ -9,6 +9,8 @@ using System.IO; using System.Text; using Microsoft.Win32; using System.Threading.Tasks; +using System.Windows.Media.Imaging; +using NavisworksTransport.UI.WPF.Views; namespace NavisworksTransport.UI.WPF.ViewModels { @@ -80,6 +82,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels private int _frameRate; private double _duration; private double _detectionGap; + private CollisionReportResult _currentReport; #endregion @@ -239,6 +242,46 @@ namespace NavisworksTransport.UI.WPF.ViewModels set => SetProperty(ref _detectionGap, value); } + /// + /// 当前报告结果 + /// + public CollisionReportResult CurrentReport + { + get => _currentReport; + set => SetProperty(ref _currentReport, value); + } + + /// + /// 截图预览图像源 + /// + public BitmapImage ScreenshotPreviewSource + { + get + { + if (string.IsNullOrEmpty(CurrentReport?.ScreenshotPath) || + !File.Exists(CurrentReport.ScreenshotPath)) + { + return null; + } + + try + { + var bitmap = new BitmapImage(); + bitmap.BeginInit(); + bitmap.CacheOption = BitmapCacheOption.OnLoad; + bitmap.UriSource = new Uri(CurrentReport.ScreenshotPath); + bitmap.EndInit(); + bitmap.Freeze(); // 防止跨线程访问问题 + return bitmap; + } + catch (Exception ex) + { + LogManager.Error($"加载截图预览失败: {ex.Message}"); + return null; + } + } + } + #endregion #region 命令属性 @@ -253,6 +296,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// public ICommand CloseCommand { get; } + /// + /// 重新截图命令 + /// + public ICommand RetakeScreenshotCommand { get; } /// /// 高亮碰撞对象命令 @@ -275,6 +322,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels ExportReportCommand = new RelayCommand(async () => await ExportReportAsync(), () => !IsGenerating && HasCollisions); CloseCommand = new RelayCommand(CloseWindow); HighlightCollisionCommand = new RelayCommand(HighlightCollision, item => item?.CollisionData != null); + RetakeScreenshotCommand = new RelayCommand(ExecuteRetakeScreenshot, CanExecuteRetakeScreenshot); // 初始化状态 ReportStatus = CollisionReportStatus.Generating; @@ -299,6 +347,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels return; } + // 保存当前报告结果 + CurrentReport = reportResult; + try { IsGenerating = true; @@ -572,7 +623,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { await Task.Run(() => { - var content = GenerateExportContent(Path.GetExtension(saveFileDialog.FileName).ToLower()); + var content = GenerateExportContent(Path.GetExtension(saveFileDialog.FileName).ToLower(), saveFileDialog.FileName); File.WriteAllText(saveFileDialog.FileName, content, Encoding.UTF8); }); @@ -590,11 +641,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// /// 生成导出内容 /// - private string GenerateExportContent(string fileExtension) + private string GenerateExportContent(string fileExtension, string filePath = null) { if (fileExtension == ".html") { - return GenerateHtmlReport(); + return GenerateHtmlReport(filePath); } else { @@ -703,7 +754,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// /// 生成HTML报告 /// - private string GenerateHtmlReport() + private string GenerateHtmlReport(string htmlFilePath = null) { var html = new StringBuilder(); var now = DateTime.Now; @@ -731,6 +782,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels html.AppendLine(".collision-status { display: inline-block; padding: 3px 8px; border-radius: 12px; font-size: 11px; color: white; margin-bottom: 8px; }"); html.AppendLine(".status-new { background-color: #ff6b6b; } .status-active { background-color: #ffa500; }"); html.AppendLine(".status-reviewed { background-color: #87ceeb; } .status-approved { background-color: #98fb98; } .status-resolved { background-color: #90ee90; }"); + html.AppendLine(".screenshot-section { margin: 20px 0; padding: 15px; background-color: #f5f5f5; border-radius: 5px; }"); + html.AppendLine(".screenshot-container { text-align: center; }"); + html.AppendLine(".screenshot-image { max-width: 100%; height: auto; border: 1px solid #ddd; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }"); + html.AppendLine(".screenshot-info { margin-top: 10px; font-size: 12px; color: #666; }"); html.AppendLine(""); html.AppendLine(""); @@ -776,6 +831,25 @@ namespace NavisworksTransport.UI.WPF.ViewModels html.AppendLine(""); html.AppendLine(""); + // 碰撞场景截图 + if (!string.IsNullOrEmpty(CurrentReport?.ScreenshotPath) && File.Exists(CurrentReport.ScreenshotPath)) + { + html.AppendLine("

碰撞场景截图

"); + html.AppendLine("
"); + + // 使用 PathHelper 计算相对路径 + string relativePath = PathHelper.GetRelativePath(htmlFilePath, CurrentReport.ScreenshotPath); + + html.AppendLine("
"); + html.AppendLine($"\"碰撞场景截图\""); + html.AppendLine("
"); + html.AppendLine($"

分辨率: {CurrentReport.ScreenshotWidth} x {CurrentReport.ScreenshotHeight}

"); + html.AppendLine($"

格式: {CurrentReport.ScreenshotFormat}

"); + html.AppendLine("
"); + html.AppendLine("
"); + html.AppendLine("
"); + } + // 运动构件信息 if (!string.IsNullOrEmpty(MovingObjectInfo)) { @@ -903,6 +977,65 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Info("关闭碰撞报告窗口"); } + /// + /// 执行重新截图 + /// + private void ExecuteRetakeScreenshot() + { + try + { + // 复用现有的截图配置对话框 + var dialog = new GenerateNavigationMapDialog(); + dialog.Title = "碰撞场景截图配置"; + + // 尝试设置 Owner(如果主窗口已显示) + var mainWindow = System.Windows.Application.Current.MainWindow; + if (mainWindow != null && mainWindow.IsLoaded) + { + dialog.Owner = mainWindow; + } + + if (dialog.ShowDialog() == true) + { + // 调用 PathHelper 生成截图 + string screenshotPath = PathHelper.GenerateSceneScreenshot( + CurrentReport.PathName ?? "collision", + dialog.ImageWidth, + dialog.ImageHeight, + dialog.ImageFormat, + "collision" + ); + + if (screenshotPath != null) + { + // 更新报告数据 + CurrentReport.ScreenshotPath = screenshotPath; + CurrentReport.ScreenshotFormat = PathHelper.ImageFormatToExtension(dialog.ImageFormat).ToUpper(); + CurrentReport.ScreenshotWidth = dialog.ImageWidth; + CurrentReport.ScreenshotHeight = dialog.ImageHeight; + + // 通知UI更新 + OnPropertyChanged(nameof(CurrentReport)); + OnPropertyChanged(nameof(ScreenshotPreviewSource)); + + LogManager.Info("碰撞场景截图已更新"); + } + } + } + catch (Exception ex) + { + LogManager.Error($"重新截图失败: {ex.Message}"); + System.Windows.MessageBox.Show($"重新截图失败: {ex.Message}", "错误", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); + } } + + /// + /// 检查是否可以执行重新截图 + /// + private bool CanExecuteRetakeScreenshot() + { + return CurrentReport != null; + } + #endregion } } \ No newline at end of file diff --git a/src/UI/WPF/Views/CollisionReportDialog.xaml b/src/UI/WPF/Views/CollisionReportDialog.xaml index 30220d7..51cddc6 100644 --- a/src/UI/WPF/Views/CollisionReportDialog.xaml +++ b/src/UI/WPF/Views/CollisionReportDialog.xaml @@ -269,6 +269,32 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav + +