diff --git a/src/Commands/GenerateCollisionReportCommand.cs b/src/Commands/GenerateCollisionReportCommand.cs index bd62368..0c579cf 100644 --- a/src/Commands/GenerateCollisionReportCommand.cs +++ b/src/Commands/GenerateCollisionReportCommand.cs @@ -108,6 +108,7 @@ namespace NavisworksTransport.Commands #endregion private readonly CollisionReportParameters _parameters; + private string _specificTestName = null; // 指定的测试名称(用于历史报告) public GenerateCollisionReportCommand(CollisionReportParameters parameters = null) : base("GenerateCollisionReport", "生成碰撞报告", "生成并显示详细的碰撞检测报告") @@ -115,6 +116,14 @@ namespace NavisworksTransport.Commands _parameters = parameters ?? new CollisionReportParameters(); } + /// + /// 设置要生成报告的测试名称 + /// + public void SetTestName(string testName) + { + _specificTestName = testName; + } + protected override PathPlanningResult ValidateParameters() { return _parameters.ValidateParameters(); @@ -126,39 +135,40 @@ namespace NavisworksTransport.Commands UpdateProgress(10, "开始生成碰撞报告..."); - // 检查缓存 + // 获取ClashDetectiveIntegration实例 var clashIntegration = ClashDetectiveIntegration.Instance; - var currentTestName = clashIntegration?.CurrentTestName; - if (!string.IsNullOrEmpty(currentTestName)) + // 使用指定的测试名称(如果有),否则使用当前测试名称 + var targetTestName = _specificTestName ?? clashIntegration?.CurrentTestName; + + if (string.IsNullOrEmpty(targetTestName)) { - lock (_cacheLock) - { - if (_reportCache.ContainsKey(currentTestName)) - { - var cachedResult = _reportCache[currentTestName]; - LogManager.Info($"使用缓存的碰撞报告: {currentTestName}"); - - UpdateProgress(100, "使用缓存报告"); - - // 显示缓存的报告 - ShowReport(cachedResult); - - var cachedMessage = cachedResult.TotalCollisions > 0 ? - $"碰撞报告显示完成(缓存):发现 {cachedResult.TotalCollisions} 个碰撞" : - "碰撞报告显示完成(缓存):未发现碰撞"; - - return PathPlanningResult.Success(cachedResult, cachedMessage); - } - else - { - LogManager.Debug($"缓存中未找到测试: {currentTestName}"); - } - } + return PathPlanningResult.Failure("无法确定测试名称,请先运行碰撞检测或选择历史记录"); } - else + + // 检查缓存 + lock (_cacheLock) { - LogManager.Warning("无法获取测试名称,跳过缓存检查"); + if (_reportCache.ContainsKey(targetTestName)) + { + var cachedResult = _reportCache[targetTestName]; + LogManager.Info($"使用缓存的碰撞报告: {targetTestName}"); + + UpdateProgress(100, "使用缓存报告"); + + // 显示缓存的报告 + ShowReport(cachedResult); + + var cachedMessage = cachedResult.TotalCollisions > 0 ? + $"碰撞报告显示完成(缓存):发现 {cachedResult.TotalCollisions} 个碰撞" : + "碰撞报告显示完成(缓存):未发现碰撞"; + + return PathPlanningResult.Success(cachedResult, cachedMessage); + } + else + { + LogManager.Debug($"缓存中未找到测试: {targetTestName}"); + } } var result = new CollisionReportResult(); @@ -225,13 +235,10 @@ namespace NavisworksTransport.Commands ShowReport(result); // 将报告结果缓存起来 - if (!string.IsNullOrEmpty(currentTestName)) + lock (_cacheLock) { - lock (_cacheLock) - { - _reportCache[currentTestName] = result; - LogManager.Info($"碰撞报告已缓存: {currentTestName}, 缓存总数: {_reportCache.Count}"); - } + _reportCache[targetTestName] = result; + LogManager.Info($"碰撞报告已缓存: {targetTestName}, 缓存总数: {_reportCache.Count}"); } } catch (OperationCanceledException) @@ -255,6 +262,40 @@ namespace NavisworksTransport.Commands #region 缓存相关方法 + /// + /// 从缓存获取报告 + /// + public static CollisionReportResult GetReportFromCache(string testName) + { + if (string.IsNullOrEmpty(testName)) + return null; + + lock (_cacheLock) + { + if (_reportCache.ContainsKey(testName)) + { + LogManager.Info($"从缓存获取报告: {testName}"); + return _reportCache[testName]; + } + } + return null; + } + + /// + /// 缓存报告 + /// + public static void CacheReport(string testName, CollisionReportResult reportResult) + { + if (string.IsNullOrEmpty(testName) || reportResult == null) + return; + + lock (_cacheLock) + { + _reportCache[testName] = reportResult; + LogManager.Info($"报告已缓存: {testName}, 缓存总数: {_reportCache.Count}"); + } + } + /// /// 清理过期缓存(可选功能) /// @@ -291,29 +332,31 @@ namespace NavisworksTransport.Commands // 从动画管理器获取当前路径名称 var animationManager = Core.Animation.PathAnimationManager.GetInstance(); var currentPathName = animationManager?.PathName; - var currentTestName = clashIntegration?.CurrentTestName; + + // 使用指定的测试名称(如果有),否则使用当前测试名称 + var targetTestName = _specificTestName ?? clashIntegration?.CurrentTestName; - if (string.IsNullOrEmpty(currentTestName)) + if (string.IsNullOrEmpty(targetTestName)) { - throw new InvalidOperationException("无法获取当前测试名称,请先运行碰撞检测"); + throw new InvalidOperationException("无法确定测试名称,请先运行碰撞检测或选择历史记录"); } - // 直接从缓存获取ClashDetective结果 - var testCollisionsRaw = clashIntegration.GetCurrentPathClashResults(currentTestName); + // 获取碰撞结果(先检查缓存,没有则从数据库加载) + var testCollisionsRaw = clashIntegration.GetCurrentPathClashResults(targetTestName); if (testCollisionsRaw == null || testCollisionsRaw.Count == 0) { - throw new InvalidOperationException($"未找到测试 '{currentTestName}' 的ClashDetective碰撞结果"); + throw new InvalidOperationException($"未找到测试 '{targetTestName}' 的ClashDetective碰撞结果"); } - LogManager.Info($"从缓存获取ClashDetective结果: {testCollisionsRaw.Count}个碰撞,测试名称:{currentTestName}"); + LogManager.Info($"从缓存获取ClashDetective结果: {testCollisionsRaw.Count}个碰撞,测试名称:{targetTestName}"); // 直接使用缓存中的CollisionResult对象(已经过复合对象处理和去重) allCollisions.AddRange(testCollisionsRaw); // 统计碰撞总数 result.ClashDetectiveCollisionCount = testCollisionsRaw.Count; - LogManager.Debug($"测试 '{currentTestName}' 包含 {testCollisionsRaw.Count} 个碰撞"); + LogManager.Debug($"测试 '{targetTestName}' 包含 {testCollisionsRaw.Count} 个碰撞"); // 统计被撞物体(缓存中已经是复合对象,不需要再去重) var nameCountDict = new Dictionary(); diff --git a/src/Core/Collision/ClashDetectiveIntegration.cs b/src/Core/Collision/ClashDetectiveIntegration.cs index 12f22b7..597d6fe 100644 --- a/src/Core/Collision/ClashDetectiveIntegration.cs +++ b/src/Core/Collision/ClashDetectiveIntegration.cs @@ -98,7 +98,6 @@ namespace NavisworksTransport private ClashDetectiveIntegration() { _currentCollisions = new List(); - _cachedResults = new List(); // 自动初始化 Clash Detective 集成 try @@ -124,26 +123,7 @@ namespace NavisworksTransport } } - /// - /// 创建碰撞快照(动画结束后一次性更新结果) - /// - public void CreateCollisionSnapshot(List results) - { - try - { - if (_documentClash == null) - return; - - // 缓存结果,等动画结束后统一处理 - CacheCollisionResults(results); - } - catch (Exception ex) - { - LogManager.Error($"创建实时碰撞快照失败: {ex.Message}"); - } - } - - private List _cachedResults = new List(); + private List _deduplicatedCollisionResults = new List(); // 去重后的预计算碰撞结果 private readonly object _resultsLock = new object(); // ClashDetective测试结果缓存:pathName -> List @@ -152,13 +132,14 @@ namespace NavisworksTransport private readonly object _clashResultsCacheLock = new object(); /// - /// 缓存碰撞结果 + /// 获取去重后的预计算碰撞结果(第一次去重,按碰撞对象对去重) /// - private void CacheCollisionResults(List results) + public List GetDeduplicatedCollisionResults() { - if (results != null && results.Count > 0) + lock (_resultsLock) { - _cachedResults.AddRange(results); + LogManager.Debug($"[GetDeduplicatedCollisionResults] 当前去重缓存数量: {_deduplicatedCollisionResults.Count}"); + return new List(_deduplicatedCollisionResults); } } @@ -263,7 +244,7 @@ namespace NavisworksTransport /// /// 测试名称 /// 碰撞结果列表,如果加载失败返回null - private List LoadClashDetectiveResultsFromDatabase(string testName) + public List GetClashDetectiveResultsFromDatabase(string testName) { try { @@ -516,75 +497,7 @@ namespace NavisworksTransport return clashResults; } - /// - /// 缓存碰撞结果(动画过程中使用)- 现在包含位置信息用于恢复测试 - /// 使用精确的碰撞检测算法替代简化检测 - /// - public void CacheCollisionDuringAnimation(ModelItem animatedObject, Point3D animatedObjectPosition, ModelItem collisionObject, Point3D collisionObjectPosition = null) - { - try - { - if (!IsModelItemValid(animatedObject) || !IsModelItemValid(collisionObject)) - { - LogManager.Warning($"[诊断-无效对象] 对象验证失败,退出缓存过程"); - return; - } - // 🔧 智能容器映射:将几何体子对象映射到有名称的容器对象 - var mappedAnimatedObject = GetCollisionObjectWithValidIdentity(animatedObject); - var mappedCollisionObject = GetCollisionObjectWithValidIdentity(collisionObject); - - // 检查是否进行了容器映射 - bool hasMapping1 = !mappedAnimatedObject.Equals(animatedObject); - bool hasMapping2 = !mappedCollisionObject.Equals(collisionObject); - - // 使用包围盒碰撞检测算法 - var animatedBoundingBox = animatedObject.BoundingBox(); - var collisionBoundingBox = collisionObject.BoundingBox(); - - if (BoundingBoxGeometryUtils.BoundingBoxesIntersect(animatedBoundingBox, collisionBoundingBox)) - { - // 🔍 计算并验证位置信息 - var finalCollisionPosition = collisionObjectPosition ?? GetObjectPosition(collisionObject); - - // 创建碰撞结果 - var collisionDistance = BoundingBoxGeometryUtils.CalculateDistance(animatedBoundingBox, collisionBoundingBox); - var collisionCenter = BoundingBoxGeometryUtils.CalculateCenter(animatedBoundingBox, collisionBoundingBox); - - var collision = new CollisionResult - { - ClashGuid = Guid.NewGuid(), - DisplayName = $"精确碰撞: {mappedAnimatedObject.DisplayName} <-> {mappedCollisionObject.DisplayName}", - Status = ClashResultStatus.New, - Item1 = mappedAnimatedObject, // 记录容器对象 - Item2 = mappedCollisionObject, // 记录容器对象 - OriginalItem1 = animatedObject, // 保存原始几何体对象 - OriginalItem2 = collisionObject, // 保存原始几何体对象 - HasContainerMapping = hasMapping1 || hasMapping2, // 标记是否进行了映射 - CreatedTime = DateTime.Now, - Distance = collisionDistance, - Center = collisionCenter, - Item1Position = animatedObjectPosition, - Item2Position = finalCollisionPosition, - HasPositionInfo = true - }; - - // 去重处理:避免重复缓存相同的碰撞对(基于容器对象) - var existing = _cachedResults.FirstOrDefault(r => - r.Item1.Equals(mappedAnimatedObject) && r.Item2.Equals(mappedCollisionObject)); - - if (existing == null) - { - _cachedResults.Add(collision); - } - } - } - catch (Exception ex) - { - LogManager.Error($"缓存碰撞失败: {ex.Message}"); - LogManager.Error($"[诊断-异常堆栈] {ex.StackTrace}"); - } - } /// /// 获取对象当前位置 @@ -701,7 +614,7 @@ namespace NavisworksTransport LogManager.Info($"[分组测试] 有效碰撞数量: {validCollisions.Count}"); // 创建主测试名称 - var mainTestName = $"物流碰撞检测_{pathName}_{DateTime.Now:yyyyMMdd_HHmmss}"; + var mainTestName = $"碰撞检测_{pathName}_{DateTime.Now:yyyyMMdd_HHmmss}"; _currentTestName = mainTestName; LogManager.Info($"[分组测试] 创建主测试: {mainTestName}"); @@ -748,9 +661,20 @@ namespace NavisworksTransport LogManager.Info($"[分组测试] 智能去重: {validCollisions.Count} 个检测点 -> {groupedCollisions.Count} 个唯一碰撞对"); + // 缓存去重后的碰撞结果(每组取第一个) + lock (_resultsLock) + { + _deduplicatedCollisionResults.Clear(); + foreach (var group in groupedCollisions) + { + _deduplicatedCollisionResults.Add(group.First()); + } + LogManager.Debug($"[去重缓存] 已缓存 {_deduplicatedCollisionResults.Count} 个去重后的碰撞结果"); + } + var collisionGroup = new ClashResultGroup { - DisplayName = $"物流碰撞检测组 ({groupedCollisions.Count} 个唯一碰撞对)" + DisplayName = $"碰撞检测组 ({groupedCollisions.Count} 个唯一碰撞对)" }; LogManager.Info($"[分组测试] 创建碰撞分组: {collisionGroup.DisplayName}"); @@ -983,7 +907,7 @@ namespace NavisworksTransport } // 检查是否成功创建了主测试 - var finalMainTest = _documentClash.TestsData.Tests.FirstOrDefault(t => t.DisplayName.Contains("物流碰撞检测")) as ClashTest; + var finalMainTest = _documentClash.TestsData.Tests.FirstOrDefault(t => t.DisplayName.Contains("碰撞检测")) as ClashTest; if (finalMainTest != null) { // 刷新Clash Detective窗口 @@ -1226,10 +1150,10 @@ namespace NavisworksTransport } /// - /// 获取所有物流碰撞检测测试 + /// 获取所有碰撞检测测试 /// - /// 物流碰撞检测测试列表 - public List GetLogisticsClashTests() + /// 碰撞检测测试列表 + public List GetClashTests() { if (_documentClash == null) { @@ -1237,8 +1161,7 @@ namespace NavisworksTransport } return _documentClash.TestsData.Tests.Cast() - .Where(t => t.DisplayName.Contains("物流碰撞检测") || - t.DisplayName.Contains("物流碰撞")) + .Where(t => t.DisplayName.Contains("碰撞检测")) .ToList(); } @@ -1259,17 +1182,17 @@ namespace NavisworksTransport throw new ArgumentException("路径名称不能为空", nameof(pathName)); } - // 获取所有物流碰撞检测测试 - var logisticsTests = GetLogisticsClashTests(); + // 获取所有碰撞检测测试 + var logisticsTests = GetClashTests(); if (logisticsTests.Count == 0) { - throw new InvalidOperationException("未找到任何物流碰撞检测测试"); + throw new InvalidOperationException("未找到任何碰撞检测测试"); } // 精确匹配当前路径的测试 var matchedTest = logisticsTests - .Where(t => t.DisplayName.StartsWith("物流碰撞检测_") && + .Where(t => t.DisplayName.StartsWith("碰撞检测_") && t.DisplayName.Contains(pathName)) .OrderByDescending(t => t.DisplayName) .FirstOrDefault(); @@ -1304,7 +1227,7 @@ namespace NavisworksTransport // 缓存中没有,尝试从数据库加载 LogManager.Info($"[ClashDetective结果] 缓存中没有 '{testName}',尝试从数据库加载"); - var loadedResults = LoadClashDetectiveResultsFromDatabase(testName); + var loadedResults = GetClashDetectiveResultsFromDatabase(testName); if (loadedResults != null && loadedResults.Count > 0) { @@ -1380,12 +1303,12 @@ namespace NavisworksTransport } /// - /// 获取所有物流碰撞检测的碰撞结果 + /// 获取所有碰撞检测的碰撞结果 /// /// 碰撞结果列表 - public List GetAllLogisticsClashResults() + public List GetAllClashResults() { - var tests = GetLogisticsClashTests(); + var tests = GetClashTests(); var allResults = new List(); foreach (var test in tests) @@ -1705,7 +1628,7 @@ namespace NavisworksTransport // 清空缓存的结果 lock (_resultsLock) { - _cachedResults?.Clear(); + _deduplicatedCollisionResults?.Clear(); } // 清除对象缓存 @@ -1912,7 +1835,7 @@ namespace NavisworksTransport _currentCollisions?.Clear(); lock (_resultsLock) { - _cachedResults?.Clear(); + _deduplicatedCollisionResults?.Clear(); } // 清理.NET API引用 diff --git a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs index 6b87139..309e259 100644 --- a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs +++ b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs @@ -94,7 +94,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels } public ClashDetectiveResultRecord Record { get; } - public string TestTimeDisplay => Record.TestTime.ToString("HH:mm:ss"); + public string TestTimeDisplay => Record.TestTime.ToString("MM-dd HH:mm:ss"); public string CollisionCountDisplay => $"{Record.CollisionCount}个"; public ICommand ViewCommand { get; } public ICommand ReportCommand { get; } @@ -110,8 +110,22 @@ namespace NavisworksTransport.UI.WPF.ViewModels private void ExecuteReport() { // 打开该次检测的详细报告 - var command = GenerateCollisionReportCommand.CreateComprehensive(autoHighlight: false); - command.ExecuteAsync(); + try + { + var testName = Record.TestName; + LogManager.Info($"[历史报告] 开始生成历史碰撞报告: {testName}"); + + // 直接使用现有的报告生成命令,但指定测试名称 + var command = GenerateCollisionReportCommand.CreateComprehensive(autoHighlight: false); + command.SetTestName(testName); + command.ExecuteAsync(); + } + catch (Exception ex) + { + LogManager.Error($"[历史报告] 生成历史报告失败: {ex.Message}", ex); + System.Windows.MessageBox.Show($"生成历史报告失败: {ex.Message}", "错误", + System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); + } } private void ExecuteDelete() @@ -135,7 +149,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { #region 私有字段 - private readonly NavisworksTransport.Core.Animation.PathAnimationManager _pathAnimationManager; + private readonly Core.Animation.PathAnimationManager _pathAnimationManager; private readonly ClashDetectiveIntegration _clashIntegration; private readonly UIStateManager _uiStateManager; @@ -148,7 +162,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels private bool _canStopAnimation = false; // 碰撞检测相关字段 - private bool _hasCollisionResults = false; private CollisionReportResult _lastGeneratedReport; // 缓存最后生成的报告 // 碰撞检测参数字段(从配置初始化) @@ -177,7 +190,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels private ObservableCollection _manualCollisionTargets; private string _manualCollisionTargetSummary = "未指定碰撞检测对象"; private DateTime? _manualTargetsLastSyncTime; - private List _latestCollisionResults = new List(); private const int ManualCollisionTargetLimit = 60; private const string ManualTargetsHighlightCategory = ModelHighlightHelper.ManualTargetsCategory; private const string CollisionResultsHighlightCategory = ModelHighlightHelper.CollisionResultsCategory; @@ -266,18 +278,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// /// 是否有碰撞检测结果 /// - public bool HasCollisionResults - { - get => _hasCollisionResults; - set - { - if (SetProperty(ref _hasCollisionResults, value)) - { - System.Windows.Input.CommandManager.InvalidateRequerySuggested(); - } - } - } - private bool _hasClashDetectiveResults; public bool HasClashDetectiveResults { @@ -711,8 +711,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels public ICommand RemoveManualTargetCommand { get; private set; } public ICommand HighlightManualTargetsCommand { get; private set; } public ICommand ClearManualHighlightsCommand { get; private set; } - public ICommand HighlightCollisionResultsCommand { get; private set; } - public ICommand ClearCollisionHighlightsCommand { get; private set; } + public ICommand HighlightPrecomputedCollisionResultsCommand { get; private set; } + public ICommand ClearPrecomputedCollisionHighlightsCommand { get; private set; } public ICommand HighlightClashDetectiveResultsCommand { get; private set; } public ICommand ClearClashDetectiveHighlightsCommand { get; private set; } @@ -816,7 +816,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels CanStopAnimation = false; // 初始化碰撞检测状态 - HasCollisionResults = false; + HasClashDetectiveResults = false; UpdateMainStatus("碰撞检测就绪"); // 从配置读取碰撞检测参数 @@ -837,7 +837,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels StartAnimationCommand = new RelayCommand(async () => await ExecuteStartAnimationAsync(), () => CanStartAnimation); PauseAnimationCommand = new RelayCommand(async () => await ExecutePauseAnimationAsync(), () => CanPauseAnimation); StopAnimationCommand = new RelayCommand(async () => await ExecuteStopAnimationAsync(), () => CanStopAnimation); - ViewCollisionReportCommand = new RelayCommand(async () => await ExecuteViewCollisionReport(), () => HasCollisionResults); + ViewCollisionReportCommand = new RelayCommand(async () => await ExecuteViewCollisionReport(), () => HasClashDetectiveResults); SelectAnimatedObjectCommand = new RelayCommand(ExecuteSelectAnimatedObject); ClearAnimatedObjectCommand = new RelayCommand(ExecuteClearAnimatedObject, () => HasSelectedAnimatedObject); GenerateAnimationCommand = new RelayCommand(ExecuteGenerateAnimation, () => CanGenerateAnimation); @@ -846,8 +846,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels RemoveManualTargetCommand = new RelayCommand(ExecuteRemoveManualTarget, target => target != null); HighlightManualTargetsCommand = new RelayCommand(ExecuteHighlightManualTargets, () => HasManualCollisionTargets); ClearManualHighlightsCommand = new RelayCommand(ExecuteClearManualHighlights, () => HasManualCollisionTargets); - HighlightCollisionResultsCommand = new RelayCommand(ExecuteHighlightCollisionResults, () => HasCollisionResults); - ClearCollisionHighlightsCommand = new RelayCommand(ExecuteClearCollisionHighlights, () => HasCollisionResults); + HighlightPrecomputedCollisionResultsCommand = new RelayCommand(ExecuteHighlightPrecomputedCollisionResults, () => HasClashDetectiveResults); + ClearPrecomputedCollisionHighlightsCommand = new RelayCommand(ExecuteClearPrecomputedCollisionHighlights, () => HasClashDetectiveResults); HighlightClashDetectiveResultsCommand = new RelayCommand(ExecuteHighlightClashDetectiveResults, () => HasClashDetectiveResults); ClearClashDetectiveHighlightsCommand = new RelayCommand(ExecuteClearClashDetectiveHighlights, () => HasClashDetectiveResults); RefreshClashDetectiveResultsCommand = new RelayCommand(ExecuteRefreshClashDetectiveResults); @@ -993,7 +993,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// private async Task ExecuteViewCollisionReport() { - if (!HasCollisionResults) + if (!HasClashDetectiveResults) { UpdateMainStatus("尚无碰撞检测结果可查看"); return; @@ -1421,19 +1421,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels /// private async void OnCollisionDetected(object sender, CollisionDetectedEventArgs e) { - _latestCollisionResults = e?.Results?.Where(r => r != null).ToList() ?? new List(); - HasCollisionResults = _latestCollisionResults.Count > 0; - - if (!HasCollisionResults) + try { - ModelHighlightHelper.ClearCollisionHighlights(); - } + // 获取ClashDetective结果 + var clashResults = _clashIntegration?.GetCurrentTestResults(); + var collisionCount = clashResults?.Count ?? 0; - var collisionCount = _latestCollisionResults.Count; - - if (collisionCount > 0) - { - try + if (collisionCount > 0) { UpdateMainStatus($"发现 {collisionCount} 个碰撞点,正在生成报告...", -1, true); LogManager.Info($"碰撞检测完成,发现 {collisionCount} 个碰撞,开始自动生成报告"); @@ -1464,16 +1458,16 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Error($"自动生成碰撞报告失败: {result.ErrorMessage}"); } } - catch (Exception ex) + else { - LogManager.Error($"处理碰撞检测事件失败: {ex.Message}", ex); - UpdateMainStatus($"发现 {collisionCount} 个碰撞点(报告生成异常)"); + UpdateMainStatus("未发现碰撞"); + _lastGeneratedReport = null; } } - else + catch (Exception ex) { - UpdateMainStatus("未发现碰撞"); - _lastGeneratedReport = null; + LogManager.Error($"处理碰撞检测事件失败: {ex.Message}", ex); + UpdateMainStatus("处理碰撞检测事件失败"); } } @@ -1703,23 +1697,42 @@ namespace NavisworksTransport.UI.WPF.ViewModels #region 碰撞结果高亮命令 - private void ExecuteHighlightCollisionResults() + private void ExecuteHighlightPrecomputedCollisionResults() { - if (_latestCollisionResults == null || _latestCollisionResults.Count == 0) + try { - UpdateMainStatus("没有可高亮的碰撞结果对象"); - return; - } + var deduplicatedResults = _clashIntegration?.GetDeduplicatedCollisionResults(); + LogManager.Debug($"[预计算碰撞结果高亮] 获取到去重后的预计算结果数量: {deduplicatedResults?.Count ?? 0}"); - _clashIntegration?.HighlightCollisions(_latestCollisionResults, CollisionResultHighlightColor, false); - UpdateMainStatus($"已高亮 {_latestCollisionResults.Count} 个碰撞结果"); - LogManager.Info($"[碰撞结果高亮] 已高亮 {_latestCollisionResults.Count} 个结果"); + if (deduplicatedResults == null || deduplicatedResults.Count == 0) + { + UpdateMainStatus("没有可高亮的去重预计算碰撞结果对象"); + LogManager.Warning("[预计算碰撞结果高亮] 去重预计算缓存为空"); + return; + } + + // 输出前3个碰撞结果的信息 + for (int i = 0; i < Math.Min(3, deduplicatedResults.Count); i++) + { + var collision = deduplicatedResults[i]; + LogManager.Debug($"[预计算碰撞结果高亮] 碰撞{i+1}: {collision.DisplayName}, Item1={collision.Item1?.DisplayName}, Item2={collision.Item2?.DisplayName}"); + } + + _clashIntegration?.HighlightCollisions(deduplicatedResults, CollisionResultHighlightColor, false); + UpdateMainStatus($"已高亮 {deduplicatedResults.Count} 个去重预计算碰撞结果"); + LogManager.Info($"[预计算碰撞结果高亮] 已高亮 {deduplicatedResults.Count} 个结果"); + } + catch (Exception ex) + { + LogManager.Error($"高亮预计算碰撞结果失败: {ex.Message}", ex); + UpdateMainStatus("高亮预计算碰撞结果失败"); + } } - private void ExecuteClearCollisionHighlights() + private void ExecuteClearPrecomputedCollisionHighlights() { ModelHighlightHelper.ClearCategory(CollisionResultsHighlightCategory); - UpdateMainStatus("已清除碰撞结果高亮"); + UpdateMainStatus("已清除预计算碰撞结果高亮"); } private void ExecuteHighlightClashDetectiveResults() @@ -2456,11 +2469,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 获取所有动画相关的碰撞测试(包括新的分组测试) var animationTests = documentClash.TestsData.Tests.Cast() - .Where(t => t.DisplayName.Contains("物流碰撞检测") || - t.DisplayName.Contains("物流碰撞")) + .Where(t => t.DisplayName.Contains("碰撞检测") ) .ToList(); - LogManager.Info($"找到 {animationTests.Count} 个物流碰撞测试"); + LogManager.Info($"找到 {animationTests.Count} 个碰撞检测"); foreach (var test in animationTests) { @@ -2668,9 +2680,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels HasSelectedAnimatedObject = false; // 清空碰撞结果 - HasCollisionResults = false; HasClashDetectiveResults = false; - _latestCollisionResults.Clear(); ModelHighlightHelper.ClearCollisionHighlights(); UpdateMainStatus("已重置"); diff --git a/src/UI/WPF/Views/AnimationControlView.xaml b/src/UI/WPF/Views/AnimationControlView.xaml index 4f860e5..9688a31 100644 --- a/src/UI/WPF/Views/AnimationControlView.xaml +++ b/src/UI/WPF/Views/AnimationControlView.xaml @@ -376,19 +376,9 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管