From 85eb10a1b18227c00a9f42b902e6e3c3b11ed8db Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Fri, 7 Aug 2026 09:17:19 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=A2=84=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E7=A2=B0=E6=92=9E=E5=88=86=E6=9E=90=E6=94=B9=E4=B8=BA=E6=89=8B?= =?UTF-8?q?=E5=8A=A8=E5=85=A5=E5=8F=A3=EF=BC=88=E6=8E=92=E9=99=A4=E5=88=97?= =?UTF-8?q?=E8=A1=A8'=E7=A2=B0=E6=92=9E=E7=83=AD=E7=82=B9=E5=88=86?= =?UTF-8?q?=E6=9E=90'=E6=8C=89=E9=92=AE=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景:预计算分析起因是非手工指定模式耗时过长;剖面盒导出 (F1 副实例)解决后,动画后自动弹分析窗口已无必要且与 '非手工指定 = 检测所有物体'语义冲突(自动预选排除可能被误确认 导致遗漏)。 改动: - 动画生成后不再自动调用预计算分析——直接保存检测记录 (所有模式统一;批处理/测试不再弹窗闪烁) - 新增'碰撞热点分析'按钮(排除列表区域,AnalyzeCollisionHotspotsCommand): 手动触发分析当前动画的高频碰撞物体 → 弹窗供用户判断排除 (保留原高亮/热点/排除并重新生成行为,不自动保存记录) - 删除 AnalyzeAndHighlightPrecomputedCollisionsAsync(被手动版替代) 验证:集成测试 25/25;F1 批处理 46 秒(副实例无分析弹窗,0 次日志) --- .../ViewModels/AnimationControlViewModel.cs | 71 ++++++++++--------- src/UI/WPF/Views/AnimationControlView.xaml | 4 ++ 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs index 318f27e..5163420 100644 --- a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs +++ b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs @@ -1036,6 +1036,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels public ICommand RemoveExcludedObjectCommand { get; private set; } public ICommand HighlightAllExcludedObjectsCommand { get; private set; } public ICommand ClearExcludedHighlightCommand { get; private set; } + public ICommand AnalyzeCollisionHotspotsCommand { get; private set; } public ICommand HighlightPrecomputedCollisionResultsCommand { get; private set; } public ICommand ClearPrecomputedCollisionHighlightsCommand { get; private set; } public ICommand ToggleWireframeModeCommand { get; private set; } @@ -1313,6 +1314,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels RemoveExcludedObjectCommand = new RelayCommand(ExecuteRemoveExcludedObject, obj => obj != null); HighlightAllExcludedObjectsCommand = new RelayCommand(ExecuteHighlightAllExcludedObjects, () => HasExcludedObjects); ClearExcludedHighlightCommand = new RelayCommand(ExecuteClearExcludedHighlight, () => HasExcludedObjects); + AnalyzeCollisionHotspotsCommand = new RelayCommand( + async () => await ExecuteCollisionHotspotAnalysisAsync(), + () => _pathAnimationManager?.AllCollisionResults?.Count > 0); HighlightPrecomputedCollisionResultsCommand = new RelayCommand(ExecuteHighlightPrecomputedCollisionResults, () => HasClashDetectiveResults); ClearPrecomputedCollisionHighlightsCommand = new RelayCommand(ExecuteClearPrecomputedCollisionHighlights, () => HasClashDetectiveResults); ToggleWireframeModeCommand = new RelayCommand(ExecuteToggleWireframeMode); @@ -3619,31 +3623,27 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// /// 🔥 分析预计算碰撞结果,自动高亮并显示分析对话框 /// - private async Task AnalyzeAndHighlightPrecomputedCollisionsAsync() + /// + /// 【手动入口】碰撞热点分析(排除列表区域按钮触发): + /// 分析当前动画的预计算碰撞结果,显示高频碰撞物体窗口——用户判断哪些物体需要排除。 + /// 不自动保存检测记录(分析是决策辅助,不是动画流程的一部分)。 + /// 说明:动画后不再自动弹出(非手工指定模式 = 检测所有物体,避免人工遗漏; + /// 批处理用户不在场无决策机会;排除建议由用户主动触发)。 + /// + private async Task ExecuteCollisionHotspotAnalysisAsync() { try { - // 仅测试环境变量(副实例/测试进程)跳过预计算分析(历史行为); - // 批处理/测试请求自动模式下窗口会自动选择默认动作并关闭,业务流程完整执行 - if (DialogHelper.IsTestAutomationModeEnabled) - { - LogManager.Info("[碰撞分析] 自动测试模式下跳过预计算碰撞分析"); - SaveCollisionDetectionRecord(); - return; - } - // 1. 获取预计算碰撞结果(从PathAnimationManager,现在缓存帧中已包含碰撞结果) var allResults = _pathAnimationManager?.AllCollisionResults; if (allResults == null || allResults.Count == 0) { - LogManager.Info("[碰撞分析] 没有预计算碰撞结果,跳过分析"); - // 🔥 没有预计算碰撞,配置已确定,直接保存检测记录 - var recordId = SaveCollisionDetectionRecord(); - if (recordId.HasValue && IsReusedHistoryRecord(recordId.Value)) - { - LogManager.Info("[碰撞分析] 用户选择使用历史记录,跳过动画生成"); - return; - } + LogManager.Info("[碰撞热点分析] 无预计算碰撞结果(请先生成动画)"); + System.Windows.MessageBox.Show( + "没有预计算碰撞结果。请先运行\"生成动画\",再进行碰撞热点分析。", + "碰撞热点分析", + System.Windows.MessageBoxButton.OK, + System.Windows.MessageBoxImage.Information); return; } @@ -3653,21 +3653,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels .Select(g => g.First()) .ToList(); - LogManager.Info($"[碰撞分析] 开始分析 {allResults.Count} 个碰撞结果(去重后 {deduplicatedResults.Count} 个)"); + LogManager.Info($"[碰撞热点分析] 开始分析 {allResults.Count} 个碰撞结果(去重后 {deduplicatedResults.Count} 个)"); - // 2. 自动高亮所有预计算碰撞结果 + // 2. 高亮所有预计算碰撞结果 ModelHighlightHelper.ManageCollisionHighlightsByCategory( ModelHighlightHelper.PrecomputeCollisionResultsCategory, deduplicatedResults, clearOtherCategories: false); - LogManager.Info($"[碰撞分析] 已高亮 {deduplicatedResults.Count} 个碰撞对象"); + LogManager.Info($"[碰撞热点分析] 已高亮 {deduplicatedResults.Count} 个碰撞对象"); // 3. 分析碰撞热点(使用原始结果 - 按频率统计) var hotspots = AnalyzeCollisionHotspots(allResults); if (hotspots.Count > 0) { - LogManager.Info($"[碰撞分析] 发现 {hotspots.Count} 个高频碰撞物体"); + LogManager.Info($"[碰撞热点分析] 发现 {hotspots.Count} 个高频碰撞物体"); foreach (var hotspot in hotspots.Take(5)) { LogManager.Info($" - {hotspot.ObjectName}: {hotspot.CollisionCount} 次 ({hotspot.Percentage:F1}%) - {hotspot.Reason}"); @@ -3681,20 +3681,17 @@ namespace NavisworksTransport.UI.WPF.ViewModels } else { - LogManager.Info("[碰撞分析] 没有发现明显的高频碰撞物体"); - // 🔥 有碰撞但无高频热点,配置已确定,保存检测记录 - var recordId = SaveCollisionDetectionRecord(); - if (recordId.HasValue && IsReusedHistoryRecord(recordId.Value)) - { - // 用户选择使用历史记录,跳过后续流程 - LogManager.Info("[碰撞分析] 用户选择使用历史记录,跳过动画生成"); - return; - } + LogManager.Info("[碰撞热点分析] 没有发现明显的高频碰撞物体"); + System.Windows.MessageBox.Show( + "没有发现明显的高频碰撞物体(碰撞次数 > 100 或占比 > 50%)。", + "碰撞热点分析", + System.Windows.MessageBoxButton.OK, + System.Windows.MessageBoxImage.Information); } } catch (Exception ex) { - LogManager.Error($"[碰撞分析] 分析预计算碰撞结果失败: {ex.Message}", ex); + LogManager.Error($"[碰撞热点分析] 分析失败: {ex.Message}", ex); } } @@ -5024,8 +5021,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels Mouse.OverrideCursor = oldCursor; oldCursor = null; // 标记已恢复,避免 finally 再次恢复 - // 🔥 自动生成动画后,自动高亮预计算碰撞结果并显示分析对话框 - await AnalyzeAndHighlightPrecomputedCollisionsAsync(); + // 🔥 动画生成后直接保存检测记录——不再自动弹出预计算碰撞分析窗口: + // 非手工指定模式 = 检测所有物体(避免人工遗漏);排除建议由 + // 排除列表区域的"碰撞热点分析"手动触发(用户主动决策) + var autoRecordId = SaveCollisionDetectionRecord(); + if (autoRecordId.HasValue && IsReusedHistoryRecord(autoRecordId.Value)) + { + LogManager.Info("[动画生成] 用户选择使用历史记录,跳过动画生成"); + } // 更新状态 UpdateAnimationButtonStates(); diff --git a/src/UI/WPF/Views/AnimationControlView.xaml b/src/UI/WPF/Views/AnimationControlView.xaml index e295298..9a91dfa 100644 --- a/src/UI/WPF/Views/AnimationControlView.xaml +++ b/src/UI/WPF/Views/AnimationControlView.xaml @@ -239,6 +239,10 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管