refactor: 预计算碰撞分析改为手动入口(排除列表'碰撞热点分析'按钮)
背景:预计算分析起因是非手工指定模式耗时过长;剖面盒导出 (F1 副实例)解决后,动画后自动弹分析窗口已无必要且与 '非手工指定 = 检测所有物体'语义冲突(自动预选排除可能被误确认 导致遗漏)。 改动: - 动画生成后不再自动调用预计算分析——直接保存检测记录 (所有模式统一;批处理/测试不再弹窗闪烁) - 新增'碰撞热点分析'按钮(排除列表区域,AnalyzeCollisionHotspotsCommand): 手动触发分析当前动画的高频碰撞物体 → 弹窗供用户判断排除 (保留原高亮/热点/排除并重新生成行为,不自动保存记录) - 删除 AnalyzeAndHighlightPrecomputedCollisionsAsync(被手动版替代) 验证:集成测试 25/25;F1 批处理 46 秒(副实例无分析弹窗,0 次日志)
This commit is contained in:
parent
75ade5ad08
commit
85eb10a1b1
@ -1036,6 +1036,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
public ICommand RemoveExcludedObjectCommand { get; private set; }
|
public ICommand RemoveExcludedObjectCommand { get; private set; }
|
||||||
public ICommand HighlightAllExcludedObjectsCommand { get; private set; }
|
public ICommand HighlightAllExcludedObjectsCommand { get; private set; }
|
||||||
public ICommand ClearExcludedHighlightCommand { get; private set; }
|
public ICommand ClearExcludedHighlightCommand { get; private set; }
|
||||||
|
public ICommand AnalyzeCollisionHotspotsCommand { get; private set; }
|
||||||
public ICommand HighlightPrecomputedCollisionResultsCommand { get; private set; }
|
public ICommand HighlightPrecomputedCollisionResultsCommand { get; private set; }
|
||||||
public ICommand ClearPrecomputedCollisionHighlightsCommand { get; private set; }
|
public ICommand ClearPrecomputedCollisionHighlightsCommand { get; private set; }
|
||||||
public ICommand ToggleWireframeModeCommand { get; private set; }
|
public ICommand ToggleWireframeModeCommand { get; private set; }
|
||||||
@ -1313,6 +1314,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
RemoveExcludedObjectCommand = new RelayCommand<ExcludedObjectViewModel>(ExecuteRemoveExcludedObject, obj => obj != null);
|
RemoveExcludedObjectCommand = new RelayCommand<ExcludedObjectViewModel>(ExecuteRemoveExcludedObject, obj => obj != null);
|
||||||
HighlightAllExcludedObjectsCommand = new RelayCommand(ExecuteHighlightAllExcludedObjects, () => HasExcludedObjects);
|
HighlightAllExcludedObjectsCommand = new RelayCommand(ExecuteHighlightAllExcludedObjects, () => HasExcludedObjects);
|
||||||
ClearExcludedHighlightCommand = new RelayCommand(ExecuteClearExcludedHighlight, () => HasExcludedObjects);
|
ClearExcludedHighlightCommand = new RelayCommand(ExecuteClearExcludedHighlight, () => HasExcludedObjects);
|
||||||
|
AnalyzeCollisionHotspotsCommand = new RelayCommand(
|
||||||
|
async () => await ExecuteCollisionHotspotAnalysisAsync(),
|
||||||
|
() => _pathAnimationManager?.AllCollisionResults?.Count > 0);
|
||||||
HighlightPrecomputedCollisionResultsCommand = new RelayCommand(ExecuteHighlightPrecomputedCollisionResults, () => HasClashDetectiveResults);
|
HighlightPrecomputedCollisionResultsCommand = new RelayCommand(ExecuteHighlightPrecomputedCollisionResults, () => HasClashDetectiveResults);
|
||||||
ClearPrecomputedCollisionHighlightsCommand = new RelayCommand(ExecuteClearPrecomputedCollisionHighlights, () => HasClashDetectiveResults);
|
ClearPrecomputedCollisionHighlightsCommand = new RelayCommand(ExecuteClearPrecomputedCollisionHighlights, () => HasClashDetectiveResults);
|
||||||
ToggleWireframeModeCommand = new RelayCommand(ExecuteToggleWireframeMode);
|
ToggleWireframeModeCommand = new RelayCommand(ExecuteToggleWireframeMode);
|
||||||
@ -3619,31 +3623,27 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 🔥 分析预计算碰撞结果,自动高亮并显示分析对话框
|
/// 🔥 分析预计算碰撞结果,自动高亮并显示分析对话框
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task AnalyzeAndHighlightPrecomputedCollisionsAsync()
|
/// <summary>
|
||||||
|
/// 【手动入口】碰撞热点分析(排除列表区域按钮触发):
|
||||||
|
/// 分析当前动画的预计算碰撞结果,显示高频碰撞物体窗口——用户判断哪些物体需要排除。
|
||||||
|
/// 不自动保存检测记录(分析是决策辅助,不是动画流程的一部分)。
|
||||||
|
/// 说明:动画后不再自动弹出(非手工指定模式 = 检测所有物体,避免人工遗漏;
|
||||||
|
/// 批处理用户不在场无决策机会;排除建议由用户主动触发)。
|
||||||
|
/// </summary>
|
||||||
|
private async Task ExecuteCollisionHotspotAnalysisAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 仅测试环境变量(副实例/测试进程)跳过预计算分析(历史行为);
|
|
||||||
// 批处理/测试请求自动模式下窗口会自动选择默认动作并关闭,业务流程完整执行
|
|
||||||
if (DialogHelper.IsTestAutomationModeEnabled)
|
|
||||||
{
|
|
||||||
LogManager.Info("[碰撞分析] 自动测试模式下跳过预计算碰撞分析");
|
|
||||||
SaveCollisionDetectionRecord();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 获取预计算碰撞结果(从PathAnimationManager,现在缓存帧中已包含碰撞结果)
|
// 1. 获取预计算碰撞结果(从PathAnimationManager,现在缓存帧中已包含碰撞结果)
|
||||||
var allResults = _pathAnimationManager?.AllCollisionResults;
|
var allResults = _pathAnimationManager?.AllCollisionResults;
|
||||||
if (allResults == null || allResults.Count == 0)
|
if (allResults == null || allResults.Count == 0)
|
||||||
{
|
{
|
||||||
LogManager.Info("[碰撞分析] 没有预计算碰撞结果,跳过分析");
|
LogManager.Info("[碰撞热点分析] 无预计算碰撞结果(请先生成动画)");
|
||||||
// 🔥 没有预计算碰撞,配置已确定,直接保存检测记录
|
System.Windows.MessageBox.Show(
|
||||||
var recordId = SaveCollisionDetectionRecord();
|
"没有预计算碰撞结果。请先运行\"生成动画\",再进行碰撞热点分析。",
|
||||||
if (recordId.HasValue && IsReusedHistoryRecord(recordId.Value))
|
"碰撞热点分析",
|
||||||
{
|
System.Windows.MessageBoxButton.OK,
|
||||||
LogManager.Info("[碰撞分析] 用户选择使用历史记录,跳过动画生成");
|
System.Windows.MessageBoxImage.Information);
|
||||||
return;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3653,21 +3653,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
.Select(g => g.First())
|
.Select(g => g.First())
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
LogManager.Info($"[碰撞分析] 开始分析 {allResults.Count} 个碰撞结果(去重后 {deduplicatedResults.Count} 个)");
|
LogManager.Info($"[碰撞热点分析] 开始分析 {allResults.Count} 个碰撞结果(去重后 {deduplicatedResults.Count} 个)");
|
||||||
|
|
||||||
// 2. 自动高亮所有预计算碰撞结果
|
// 2. 高亮所有预计算碰撞结果
|
||||||
ModelHighlightHelper.ManageCollisionHighlightsByCategory(
|
ModelHighlightHelper.ManageCollisionHighlightsByCategory(
|
||||||
ModelHighlightHelper.PrecomputeCollisionResultsCategory,
|
ModelHighlightHelper.PrecomputeCollisionResultsCategory,
|
||||||
deduplicatedResults,
|
deduplicatedResults,
|
||||||
clearOtherCategories: false);
|
clearOtherCategories: false);
|
||||||
LogManager.Info($"[碰撞分析] 已高亮 {deduplicatedResults.Count} 个碰撞对象");
|
LogManager.Info($"[碰撞热点分析] 已高亮 {deduplicatedResults.Count} 个碰撞对象");
|
||||||
|
|
||||||
// 3. 分析碰撞热点(使用原始结果 - 按频率统计)
|
// 3. 分析碰撞热点(使用原始结果 - 按频率统计)
|
||||||
var hotspots = AnalyzeCollisionHotspots(allResults);
|
var hotspots = AnalyzeCollisionHotspots(allResults);
|
||||||
|
|
||||||
if (hotspots.Count > 0)
|
if (hotspots.Count > 0)
|
||||||
{
|
{
|
||||||
LogManager.Info($"[碰撞分析] 发现 {hotspots.Count} 个高频碰撞物体");
|
LogManager.Info($"[碰撞热点分析] 发现 {hotspots.Count} 个高频碰撞物体");
|
||||||
foreach (var hotspot in hotspots.Take(5))
|
foreach (var hotspot in hotspots.Take(5))
|
||||||
{
|
{
|
||||||
LogManager.Info($" - {hotspot.ObjectName}: {hotspot.CollisionCount} 次 ({hotspot.Percentage:F1}%) - {hotspot.Reason}");
|
LogManager.Info($" - {hotspot.ObjectName}: {hotspot.CollisionCount} 次 ({hotspot.Percentage:F1}%) - {hotspot.Reason}");
|
||||||
@ -3681,20 +3681,17 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogManager.Info("[碰撞分析] 没有发现明显的高频碰撞物体");
|
LogManager.Info("[碰撞热点分析] 没有发现明显的高频碰撞物体");
|
||||||
// 🔥 有碰撞但无高频热点,配置已确定,保存检测记录
|
System.Windows.MessageBox.Show(
|
||||||
var recordId = SaveCollisionDetectionRecord();
|
"没有发现明显的高频碰撞物体(碰撞次数 > 100 或占比 > 50%)。",
|
||||||
if (recordId.HasValue && IsReusedHistoryRecord(recordId.Value))
|
"碰撞热点分析",
|
||||||
{
|
System.Windows.MessageBoxButton.OK,
|
||||||
// 用户选择使用历史记录,跳过后续流程
|
System.Windows.MessageBoxImage.Information);
|
||||||
LogManager.Info("[碰撞分析] 用户选择使用历史记录,跳过动画生成");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
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;
|
Mouse.OverrideCursor = oldCursor;
|
||||||
oldCursor = null; // 标记已恢复,避免 finally 再次恢复
|
oldCursor = null; // 标记已恢复,避免 finally 再次恢复
|
||||||
|
|
||||||
// 🔥 自动生成动画后,自动高亮预计算碰撞结果并显示分析对话框
|
// 🔥 动画生成后直接保存检测记录——不再自动弹出预计算碰撞分析窗口:
|
||||||
await AnalyzeAndHighlightPrecomputedCollisionsAsync();
|
// 非手工指定模式 = 检测所有物体(避免人工遗漏);排除建议由
|
||||||
|
// 排除列表区域的"碰撞热点分析"手动触发(用户主动决策)
|
||||||
|
var autoRecordId = SaveCollisionDetectionRecord();
|
||||||
|
if (autoRecordId.HasValue && IsReusedHistoryRecord(autoRecordId.Value))
|
||||||
|
{
|
||||||
|
LogManager.Info("[动画生成] 用户选择使用历史记录,跳过动画生成");
|
||||||
|
}
|
||||||
|
|
||||||
// 更新状态
|
// 更新状态
|
||||||
UpdateAnimationButtonStates();
|
UpdateAnimationButtonStates();
|
||||||
|
|||||||
@ -239,6 +239,10 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
|||||||
<Button Content="从选择添加"
|
<Button Content="从选择添加"
|
||||||
Command="{Binding AddExcludedObjectsFromSelectionCommand}"
|
Command="{Binding AddExcludedObjectsFromSelectionCommand}"
|
||||||
Style="{StaticResource SecondaryButtonStyle}"/>
|
Style="{StaticResource SecondaryButtonStyle}"/>
|
||||||
|
<Button Content="碰撞热点分析"
|
||||||
|
Command="{Binding AnalyzeCollisionHotspotsCommand}"
|
||||||
|
Style="{StaticResource SecondaryButtonStyle}"
|
||||||
|
ToolTip="分析当前动画的高频碰撞物体,供手动决定是否排除"/>
|
||||||
<Button Content="清除所有"
|
<Button Content="清除所有"
|
||||||
Command="{Binding ClearExcludedObjectsCommand}"
|
Command="{Binding ClearExcludedObjectsCommand}"
|
||||||
Style="{StaticResource SecondaryButtonStyle}"
|
Style="{StaticResource SecondaryButtonStyle}"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user