diff --git a/doc/requirement/todo_features.md b/doc/requirement/todo_features.md index 2312bf3..809535f 100644 --- a/doc/requirement/todo_features.md +++ b/doc/requirement/todo_features.md @@ -6,7 +6,7 @@ 1. [ ] (BUG)虚拟车辆模型每次点击都重建 2. [x] (BUG)碰撞结果高亮,应该显示clashdetective检测的结果 -3. [ ] (优化)对clashdetective的检测结果,进行向上合并,找到集合对象。 +3. [x] (优化)对clashdetective的检测结果,进行向上合并,找到集合对象。 ### [2025/12/25] diff --git a/src/Commands/GenerateCollisionReportCommand.cs b/src/Commands/GenerateCollisionReportCommand.cs index 6a850e6..7560d24 100644 --- a/src/Commands/GenerateCollisionReportCommand.cs +++ b/src/Commands/GenerateCollisionReportCommand.cs @@ -58,6 +58,7 @@ namespace NavisworksTransport.Commands public List AllCollisions { get; set; } = new List(); public int BoundingBoxTestCount { get; set; } // 包围盒测试数量 public int ClashDetectiveCollisionCount { get; set; } // Clash Detective结果数量 + public int AnimationCollisions { get; set; } // 动画过程碰撞数量 public string MovingObjectInfo { get; set; } = string.Empty; // 新增:被撞物体去重统计 @@ -126,15 +127,17 @@ namespace NavisworksTransport.Commands UpdateProgress(10, "开始生成碰撞报告..."); // 检查缓存 - var testNameKey = GetLatestTestNameForCache(); - if (!string.IsNullOrEmpty(testNameKey)) + var clashIntegration = ClashDetectiveIntegration.Instance; + var currentTestName = clashIntegration?.CurrentTestName; + + if (!string.IsNullOrEmpty(currentTestName)) { lock (_cacheLock) { - if (_reportCache.ContainsKey(testNameKey)) + if (_reportCache.ContainsKey(currentTestName)) { - var cachedResult = _reportCache[testNameKey]; - LogManager.Info($"使用缓存的碰撞报告: {testNameKey}"); + var cachedResult = _reportCache[currentTestName]; + LogManager.Info($"使用缓存的碰撞报告: {currentTestName}"); UpdateProgress(100, "使用缓存报告"); @@ -149,7 +152,7 @@ namespace NavisworksTransport.Commands } else { - LogManager.Info($"未找到缓存报告,开始生成新报告: {testNameKey}"); + LogManager.Debug($"缓存中未找到测试: {currentTestName}"); } } } @@ -169,8 +172,7 @@ namespace NavisworksTransport.Commands result.AllCollisions = collisionData.AllCollisions; // 修改统计数据 - var clashIntegration = ClashDetectiveIntegration.Instance; - result.AnimationCollisions = clashIntegration?.AnimationCollisionCount ?? 0; // 检测点数量 + result.AnimationCollisions = collisionData.AnimationCollisions; result.TotalCollisions = collisionData.ClashDetectiveCollisionCount; result.MovingObjectInfo = collisionData.MovingObjectInfo; @@ -223,12 +225,12 @@ namespace NavisworksTransport.Commands ShowReport(result); // 将报告结果缓存起来 - if (!string.IsNullOrEmpty(testNameKey)) + if (!string.IsNullOrEmpty(currentTestName)) { lock (_cacheLock) { - _reportCache[testNameKey] = result; - LogManager.Info($"碰撞报告已缓存: {testNameKey}, 缓存总数: {_reportCache.Count}"); + _reportCache[currentTestName] = result; + LogManager.Info($"碰撞报告已缓存: {currentTestName}, 缓存总数: {_reportCache.Count}"); } } } @@ -253,56 +255,6 @@ namespace NavisworksTransport.Commands #region 缓存相关方法 - /// - /// 获取当前最新的物流碰撞检测测试名称作为缓存键 - /// - /// 测试名称,如果未找到则返回 null - private string GetLatestTestNameForCache() - { - try - { - var doc = Autodesk.Navisworks.Api.Application.ActiveDocument; - var documentClash = doc.GetClash(); - - if (documentClash == null) - { - LogManager.Warning("无法获取 Clash Detective 文档,无法生成缓存键"); - return null; - } - - // 从动画管理器获取当前路径名称 - var animationManager = Core.Animation.PathAnimationManager.GetInstance(); - var currentPathName = animationManager?.PathName; - - if (string.IsNullOrEmpty(currentPathName)) - { - throw new InvalidOperationException("无法获取当前路径名称"); - } - - // 精确匹配当前路径的测试 - var matchedTest = documentClash.TestsData.Tests.Cast() - .Where(t => t.DisplayName.StartsWith("物流碰撞检测_") && - t.DisplayName.Contains(currentPathName)) - .OrderByDescending(t => t.DisplayName) // 同一路径可能有多个测试,取最新的 - .FirstOrDefault(); - - if (matchedTest != null) - { - LogManager.Info($"找到当前路径的测试: {matchedTest.DisplayName}"); - return matchedTest.DisplayName; - } - else - { - throw new InvalidOperationException($"未找到路径 '{currentPathName}' 的碰撞测试"); - } - } - catch (Exception ex) - { - LogManager.Error($"获取测试名称作为缓存键失败: {ex.Message}"); - throw; // 让错误暴露出来 - } - } - /// /// 清理过期缓存(可选功能) /// @@ -339,94 +291,65 @@ namespace NavisworksTransport.Commands // 从动画管理器获取当前路径名称 var animationManager = Core.Animation.PathAnimationManager.GetInstance(); var currentPathName = animationManager?.PathName; + var currentTestName = clashIntegration?.CurrentTestName; - if (string.IsNullOrEmpty(currentPathName)) + if (string.IsNullOrEmpty(currentTestName)) { - throw new InvalidOperationException("无法获取当前路径名称"); + throw new InvalidOperationException("无法获取当前测试名称,请先运行碰撞检测"); } // 直接从缓存获取ClashDetective结果 - var testCollisionsRaw = clashIntegration.GetCurrentPathClashResults(currentPathName); + var testCollisionsRaw = clashIntegration.GetCurrentPathClashResults(currentTestName); if (testCollisionsRaw == null || testCollisionsRaw.Count == 0) { - throw new InvalidOperationException($"未找到路径 '{currentPathName}' 的ClashDetective碰撞结果"); + throw new InvalidOperationException($"未找到测试 '{currentTestName}' 的ClashDetective碰撞结果"); } - LogManager.Info($"从缓存获取ClashDetective结果: {testCollisionsRaw.Count}个碰撞"); + LogManager.Info($"从缓存获取ClashDetective结果: {testCollisionsRaw.Count}个碰撞,测试名称:{currentTestName}"); - // 转换为CollisionResult对象 - foreach (var clash in testCollisionsRaw) - { - var collision = new CollisionResult - { - ClashGuid = clash.Guid, - DisplayName = $"[{currentPathName}] {clash.DisplayName}", - Status = clash.Status, - Item1 = clash.Item1, - Item2 = clash.Item2, - Center = clash.Center, - Distance = clash.Distance, - CreatedTime = DateTime.Now - }; - allCollisions.Add(collision); - } + // 直接使用缓存中的CollisionResult对象(已经过复合对象处理和去重) + allCollisions.AddRange(testCollisionsRaw); - // 统计匹配测试的碰撞总数 - var totalCollisionCount = testCollisionsRaw.Count; - result.ClashDetectiveCollisionCount = totalCollisionCount; - LogManager.Debug($"路径 '{currentPathName}' 包含 {totalCollisionCount} 个碰撞"); + // 统计碰撞总数 + result.ClashDetectiveCollisionCount = testCollisionsRaw.Count; + LogManager.Debug($"测试 '{currentTestName}' 包含 {testCollisionsRaw.Count} 个碰撞"); - // 去重处理 - var uniqueCollisions = allCollisions - .GroupBy(c => new { c.Item1, c.Item2, c.Center }) - .Select(g => g.First()) - .ToList(); + // 统计被撞物体(缓存中已经是复合对象,不需要再去重) + var nameCountDict = new Dictionary(); + var uniqueCollidedObjectsList = new List(); - // 新增:统计去重后的被撞物体 - // 使用Dictionary,ModelItem作为键会自动调用Equals进行比较 - var uniqueCollidedObjectsDict = new Dictionary(); - foreach (var collision in uniqueCollisions) + foreach (var collision in testCollisionsRaw) { if (collision.Item2 != null) { - // ModelItem作为字典的键,会使用其Equals方法进行比较 - if (!uniqueCollidedObjectsDict.ContainsKey(collision.Item2)) + var item2Name = NavisworksApiHelper.GetModelItemNameWithAncestorFallback(collision.Item2) ?? "未知对象"; + + // 为相同名称的对象添加编号区分 + if (nameCountDict.ContainsKey(item2Name)) { - var item2Name = NavisworksApiHelper.GetModelItemNameWithAncestorFallback(collision.Item2); - uniqueCollidedObjectsDict[collision.Item2] = item2Name ?? "未知对象"; + nameCountDict[item2Name]++; + uniqueCollidedObjectsList.Add($"{item2Name} #{nameCountDict[item2Name]}"); + } + else + { + nameCountDict[item2Name] = 1; + uniqueCollidedObjectsList.Add(item2Name); } } } - // 修复:保留所有碰撞对象,为相同名称的对象添加编号区分 - var nameCountDict = new Dictionary(); - var uniqueCollidedObjectsList = new List(); - - foreach (var name in uniqueCollidedObjectsDict.Values) - { - if (nameCountDict.ContainsKey(name)) - { - nameCountDict[name]++; - uniqueCollidedObjectsList.Add($"{name} #{nameCountDict[name]}"); - } - else - { - nameCountDict[name] = 1; - uniqueCollidedObjectsList.Add(name); - } - } - - var uniqueCollidedObjectsSet = new HashSet(uniqueCollidedObjectsList); - - result.AllCollisions = uniqueCollisions; - result.UniqueCollidedObjects = uniqueCollidedObjectsSet; + result.AllCollisions = allCollisions; + result.UniqueCollidedObjects = new HashSet(uniqueCollidedObjectsList); result.BoundingBoxTestCount = 0; + + // 设置动画碰撞数量 + result.AnimationCollisions = clashIntegration?.AnimationCollisionCount ?? 0; // 从碰撞结果的Item1中获取运动构件信息 - if (uniqueCollisions.Count > 0 && uniqueCollisions[0].Item1 != null) + if (allCollisions.Count > 0 && allCollisions[0].Item1 != null) { - var movingItem = uniqueCollisions[0].Item1; + var movingItem = allCollisions[0].Item1; var movingItemName = NavisworksApiHelper.GetModelItemNameWithAncestorFallback(movingItem) ?? "未知运动构件"; result.MovingObjectInfo = $"运动构件: {movingItemName}"; } @@ -435,7 +358,7 @@ namespace NavisworksTransport.Commands result.MovingObjectInfo = "运动构件: 未知"; } - LogManager.Info($"收集完成 - Clash Detective权威结果: {result.ClashDetectiveCollisionCount}个, 去重后碰撞对象: {uniqueCollisions.Count}个, 去重后被撞构件: {uniqueCollidedObjectsSet.Count}个"); + LogManager.Info($"收集完成 - Clash Detective权威结果: {result.ClashDetectiveCollisionCount}个, 碰撞对象: {allCollisions.Count}个, 被撞构件: {uniqueCollidedObjectsList.Count}个"); return result; } diff --git a/src/Core/Collision/ClashDetectiveIntegration.cs b/src/Core/Collision/ClashDetectiveIntegration.cs index 52fd00d..ff60712 100644 --- a/src/Core/Collision/ClashDetectiveIntegration.cs +++ b/src/Core/Collision/ClashDetectiveIntegration.cs @@ -50,6 +50,16 @@ namespace NavisworksTransport get { return _clashDetectiveCollisionCount; } } + /// + /// 当前ClashDetective测试名称 + /// + public string CurrentTestName + { + get { return _currentTestName; } + } + + private string _currentTestName; + /// /// 单例实例 /// @@ -129,8 +139,9 @@ namespace NavisworksTransport private List _cachedResults = new List(); private readonly object _resultsLock = new object(); - // ClashDetective测试结果缓存:pathName -> List - private Dictionary> _clashDetectiveResultsCache = new Dictionary>(); + // ClashDetective测试结果缓存:pathName -> List + // 使用自定义的CollisionResult类型,支持修改Item1和Item2 + private Dictionary> _clashDetectiveResultsCache = new Dictionary>(); private readonly object _clashResultsCacheLock = new object(); /// @@ -325,6 +336,7 @@ namespace NavisworksTransport // 创建主测试名称 var mainTestName = $"物流碰撞检测_{pathName}_{DateTime.Now:yyyyMMdd_HHmmss}"; + _currentTestName = mainTestName; LogManager.Info($"[分组测试] 创建主测试: {mainTestName}"); Progress progress = null; @@ -370,26 +382,6 @@ namespace NavisworksTransport LogManager.Info($"[分组测试] 智能去重: {validCollisions.Count} 个检测点 -> {groupedCollisions.Count} 个唯一碰撞对"); - // 调试:打印所有去重后的碰撞对信息 - LogManager.Debug($"[分组测试] 去重后的碰撞对列表:"); - int debugIndex = 0; - foreach (var group in groupedCollisions) - { - var firstCollision = group.First(); - var item1 = firstCollision.Item1; - var item2 = firstCollision.Item2; - - // 使用 GetModelItemWithAncestorFallback 获取名称(向上查找父节点) - var item1Name = item1 != null ? NavisworksApiHelper.GetModelItemNameWithAncestorFallback(item1) : "null"; - var item2Name = item2 != null ? NavisworksApiHelper.GetModelItemNameWithAncestorFallback(item2) : "null"; - var item1Hash = item1?.GetHashCode() ?? -1; - var item2Hash = item2?.GetHashCode() ?? -1; - var frameCount = group.Count(); - - LogManager.Debug($" [{debugIndex}] Item1={item1Name}(Hash:{item1Hash}), Item2={item2Name}(Hash:{item2Hash}), 帧数={frameCount}"); - debugIndex++; - } - var collisionGroup = new ClashResultGroup { DisplayName = $"物流碰撞检测组 ({groupedCollisions.Count} 个唯一碰撞对)" @@ -546,44 +538,58 @@ namespace NavisworksTransport LogManager.Info($"[分组测试] ClashDetective检测完成: 确认碰撞 {confirmedCount} 组, 跳过 {skippedCount} 个冗余检测点"); - // 调试:打印所有确认的碰撞对信息 - LogManager.Debug($"[分组测试] 确认的碰撞对列表:"); - int confirmedIndex = 0; - foreach (var result in collisionGroup.Children) - { - if (result is ClashResult clashResult) - { - var item1 = clashResult.Item1; - var item2 = clashResult.Item2; + // 第三步:处理碰撞结果并缓存 + var mergedResults = new Dictionary(); + int mergedCount = 0; - // 使用 GetModelItemWithAncestorFallback 获取名称(向上查找父节点) - var item1Name = item1 != null ? NavisworksApiHelper.GetModelItemNameWithAncestorFallback(item1) : "null"; - var item2Name = item2 != null ? NavisworksApiHelper.GetModelItemNameWithAncestorFallback(item2) : "null"; - var item1Hash = item1?.GetHashCode() ?? -1; - var item2Hash = item2?.GetHashCode() ?? -1; - - LogManager.Debug($" [{confirmedIndex}] Item1={item1Name}(Hash:{item1Hash}), Item2={item2Name}(Hash:{item2Hash})"); - confirmedIndex++; - } - } - - // 直接从collisionGroup.Children提取结果并缓存 - var clashResults = new List(); foreach (var child in collisionGroup.Children) { if (child is ClashResult clashResult) { - clashResults.Add(clashResult); + // 向上查找复合对象 + var compositeItem1 = NavisworksApiHelper.FindCompositeAncestor(clashResult.Item1); + var compositeItem2 = NavisworksApiHelper.FindCompositeAncestor(clashResult.Item2); + + // 创建自定义的CollisionResult对象 + var collisionResult = new CollisionResult + { + ClashGuid = clashResult.Guid, + DisplayName = clashResult.DisplayName, + Status = clashResult.Status, + Item1 = compositeItem1, + Item2 = compositeItem2, + Center = clashResult.Center, + Distance = clashResult.Distance, + CreatedTime = DateTime.Now, + OriginalItem1 = clashResult.Item1, + OriginalItem2 = clashResult.Item2, + HasContainerMapping = true + }; + + // 使用复合对象的HashCode作为key去重 + var key = $"{compositeItem1.GetHashCode()}_{compositeItem2.GetHashCode()}"; + + if (!mergedResults.ContainsKey(key)) + { + mergedResults[key] = collisionResult; + mergedCount++; + } } } + var clashResults = mergedResults.Values.ToList(); + LogManager.Info($"复合对象处理完成:原始{collisionGroup.Children.Count}个碰撞,合并后{clashResults.Count}个碰撞"); + lock (_clashResultsCacheLock) { - _clashDetectiveResultsCache[pathName] = clashResults; + _clashDetectiveResultsCache[_currentTestName] = clashResults; } - LogManager.Info($"已缓存ClashDetective结果:{clashResults.Count}个碰撞"); + LogManager.Info($"已缓存ClashDetective结果:{clashResults.Count}个碰撞,测试名称:{_currentTestName}"); - // 第三步:将分组添加到主测试 + // 更新碰撞计数器 + _clashDetectiveCollisionCount = clashResults.Count; + + // 第四步:将分组添加到主测试 if (collisionGroup.Children.Count > 0) { _documentClash.TestsData.TestsAddCopy(addedMainTest, collisionGroup); @@ -610,13 +616,11 @@ namespace NavisworksTransport } } - // 关键修复:碰撞测试完成后,将物体恢复到动画终点位置 + // 碰撞测试完成后,将物体恢复到动画终点位置 if (animatedObject != null && IsModelItemValid(animatedObject)) { try { - LogManager.Info("=== 开始恢复物体到动画终点位置 ==="); - var modelItems = new ModelItemCollection { animatedObject }; // 计算当前位置到动画终点的偏移 @@ -637,7 +641,6 @@ namespace NavisworksTransport doc.Models.OverridePermanentTransform(modelItems, restoreTransform, false); LogManager.Info($"已将 {animatedObject.DisplayName} 恢复到动画终点位置: ({animationEndPosition.X:F2},{animationEndPosition.Y:F2},{animationEndPosition.Z:F2})"); - LogManager.Info("=== 物体位置恢复完成 ==="); } catch (Exception restoreEx) { @@ -645,8 +648,6 @@ namespace NavisworksTransport } } - LogManager.Info($"=== 分组方案完成:成功创建分组碰撞测试(容差: {detectionGap}米) ==="); - // 检查是否成功创建了主测试 var finalMainTest = _documentClash.TestsData.Tests.FirstOrDefault(t => t.DisplayName.Contains("物流碰撞检测")) as ClashTest; if (finalMainTest != null) @@ -657,7 +658,7 @@ namespace NavisworksTransport // 自动高亮ClashDetective结果 try { - HighlightClashDetectiveResults(pathName); + HighlightClashDetectiveResults(_currentTestName); LogManager.Info("自动高亮ClashDetective检测结果完成"); } catch (Exception clashHighlightEx) @@ -665,47 +666,9 @@ namespace NavisworksTransport LogManager.Error($"自动高亮ClashDetective结果失败: {clashHighlightEx.Message}"); } - // 更新Clash Detective碰撞计数器 - 统计分组测试中的碰撞数量 - var finalClashDetectiveCount = 0; - if (_documentClash != null) - { - // 计算物流碰撞检测测试的碰撞总数 - var logisticsTests = _documentClash.TestsData.Tests.Cast() - .Where(t => t.DisplayName.Contains("物流碰撞检测") || - t.DisplayName.Contains("物流碰撞")) - .ToList(); - - finalClashDetectiveCount = logisticsTests.Sum(t => GetTotalClashResultCount(t)); - LogManager.Info($"统计Clash Detective最终碰撞数量: {logisticsTests.Count}个测试,总共{finalClashDetectiveCount}个碰撞"); - - // 详细分析主测试结构 - if (finalMainTest != null) - { - LogManager.Info($"[分组统计] 主测试: {finalMainTest.DisplayName}"); - LogManager.Info($"[分组统计] 主测试直接子项数量: {finalMainTest.Children.Count}"); - - foreach (var child in finalMainTest.Children) - { - if (child is ClashResultGroup group) - { - LogManager.Info($"[分组统计] 分组: {group.DisplayName}, 包含 {group.Children.Count} 个结果"); - } - else if (child is ClashResult result) - { - LogManager.Info($"[分组统计] 直接结果: {result.DisplayName}"); - } - } - } - } - - _clashDetectiveCollisionCount = finalClashDetectiveCount; LogManager.Info($"=== 碰撞统计最终结果 ==="); LogManager.Info($"动画过程包围盒检测: {_animationCollisionCount}个碰撞 (参考值)"); - LogManager.Info($"Clash Detective权威结果: {_clashDetectiveCollisionCount}个碰撞 (最终权威数据)"); - LogManager.Info($"统计说明: 动画过程使用简单包围盒检测,Clash Detective使用精确几何体检测"); - LogManager.Info($"=== 统计分离完成 ==="); - - LogManager.Info("=== 动画碰撞测试(分组方案)完成 ==="); + LogManager.Info($"Clash Detective权威结果: {_clashDetectiveCollisionCount}个碰撞 (权威数据)"); // 触发碰撞检测完成事件,通知生成报告 if (validCollisions.Count > 0) @@ -862,16 +825,16 @@ namespace NavisworksTransport /// /// 高亮ClashDetective测试结果 /// - public void HighlightClashDetectiveResults(string pathName) + public void HighlightClashDetectiveResults(string testName) { try { - // 使用公共方法获取指定路径的碰撞结果 - var clashResults = GetCurrentPathClashResults(pathName); + // 使用公共方法获取指定测试的碰撞结果 + var clashResults = GetCurrentPathClashResults(testName); if (clashResults.Count == 0) { - LogManager.Info("[ClashDetective高亮] 指定路径测试中未找到碰撞结果"); + LogManager.Info("[ClashDetective高亮] 指定测试中未找到碰撞结果"); return; } @@ -994,36 +957,27 @@ namespace NavisworksTransport /// /// 路径名称 /// 当前路径的碰撞结果列表 - public List GetCurrentPathClashResults(string pathName) + public List GetCurrentPathClashResults(string testName) { - // 优先从缓存获取 lock (_clashResultsCacheLock) { - if (_clashDetectiveResultsCache.TryGetValue(pathName, out var cachedResults)) + if (_clashDetectiveResultsCache.TryGetValue(testName, out var cachedResults)) { - LogManager.Debug($"[ClashDetective结果] 从缓存获取 '{pathName}' 的结果:{cachedResults.Count}个碰撞"); + LogManager.Debug($"[ClashDetective结果] 从缓存获取 '{testName}' 的结果:{cachedResults.Count}个碰撞"); return cachedResults; } } - // 缓存中没有,从API获取 - var matchedTest = GetCurrentPathClashTest(pathName); + throw new InvalidOperationException($"未找到测试 '{testName}' 的ClashDetective缓存结果,请先运行碰撞检测"); + } - if (matchedTest == null) - { - throw new InvalidOperationException($"未找到路径 '{pathName}' 的ClashDetective测试"); - } - - var results = ExtractClashResultsFromTest(matchedTest); - - // 缓存结果 - lock (_clashResultsCacheLock) - { - _clashDetectiveResultsCache[pathName] = results; - } - - LogManager.Debug($"[ClashDetective结果] 从API获取并缓存 '{pathName}' 的结果:{results.Count}个碰撞"); - return results; + /// + /// 获取当前测试的碰撞结果(便捷方法) + /// + /// 当前测试的碰撞结果列表 + public List GetCurrentTestResults() + { + return GetCurrentPathClashResults(_currentTestName); } /// diff --git a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs index 3d5fba5..f8576d1 100644 --- a/src/UI/WPF/ViewModels/AnimationControlViewModel.cs +++ b/src/UI/WPF/ViewModels/AnimationControlViewModel.cs @@ -1329,21 +1329,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels { try { - var animationManager = Core.Animation.PathAnimationManager.GetInstance(); - var pathName = animationManager?.PathName; - - if (string.IsNullOrEmpty(pathName)) - { - return; - } - - // 检查是否有该路径的ClashDetective结果 - var clashResults = _clashIntegration?.GetCurrentPathClashResults(pathName); + // 检查是否有当前测试的ClashDetective结果 + var clashResults = _clashIntegration?.GetCurrentTestResults(); if (clashResults != null && clashResults.Count > 0) { // 有ClashDetective结果,高亮显示 - _clashIntegration?.HighlightClashDetectiveResults(pathName); + _clashIntegration?.HighlightClashDetectiveResults(_clashIntegration.CurrentTestName); HasClashDetectiveResults = true; LogManager.Info($"动画结束,已高亮ClashDetective检测结果:{clashResults.Count}个碰撞"); } @@ -1393,9 +1385,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels LogManager.Info("碰撞报告已自动生成并保存到数据库"); // 高亮ClashDetective结果 - var animationManager = Core.Animation.PathAnimationManager.GetInstance(); - var pathName = animationManager?.PathName ?? "未知路径"; - _clashIntegration?.HighlightClashDetectiveResults(pathName); + _clashIntegration?.HighlightClashDetectiveResults(_clashIntegration.CurrentTestName); HasClashDetectiveResults = true; LogManager.Info("已自动高亮ClashDetective检测结果"); } @@ -1648,9 +1638,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels private void ExecuteHighlightClashDetectiveResults() { - var animationManager = Core.Animation.PathAnimationManager.GetInstance(); - var pathName = animationManager?.PathName ?? "未知路径"; - _clashIntegration?.HighlightClashDetectiveResults(pathName); + _clashIntegration?.HighlightClashDetectiveResults(_clashIntegration.CurrentTestName); UpdateMainStatus("已高亮ClashDetective检测结果"); } diff --git a/src/Utils/NavisworksApiHelper.cs b/src/Utils/NavisworksApiHelper.cs index 078fa8e..fce2745 100644 --- a/src/Utils/NavisworksApiHelper.cs +++ b/src/Utils/NavisworksApiHelper.cs @@ -128,7 +128,6 @@ namespace NavisworksTransport.Utils } // 如果所有父节点都没有DisplayName,返回默认名称 - LogManager.Debug($"[元素名称获取] 向上查找{depth}层后仍未找到DisplayName,返回默认名称"); return depth > 0 ? "未命名对象(已溯源)" : "未命名对象"; } catch (Exception ex) @@ -170,5 +169,56 @@ namespace NavisworksTransport.Utils return "获取失败"; } } + + /// + /// 向上查找IsComposite为true的复合对象祖先节点 + /// + /// 要查找的ModelItem + /// 最大向上查找深度,防止无限递归 + /// 找到的复合对象祖先节点,如果未找到则返回当前节点 + public static ModelItem FindCompositeAncestor(ModelItem item, int maxDepth = 10) + { + if (item == null) return null; + + try + { + var current = item; + int depth = 0; + + // 首先检查当前节点是否已经是复合对象 + if (current.IsComposite) + { + return current; + } + + // 向上查找复合对象 + while (current != null && depth < maxDepth) + { + // 向上一级父节点继续查找 + current = current.Parent; + + if (current == null) + { + break; + } + + depth++; + + // 检查是否是复合对象 + if (current.IsComposite) + { + return current; + } + } + + // 如果没有找到复合对象,返回原始节点 + return item; + } + catch (Exception ex) + { + LogManager.Error($"查找复合对象祖先失败: {ex.Message}"); + return item; + } + } } } \ No newline at end of file