From 2930ea71da778870a89a3fe4616f86196bd76857 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Tue, 3 Feb 2026 22:40:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=80=9A=E8=BF=87PathId?= =?UTF-8?q?=E6=9F=A5=E6=89=BE=E5=8C=B9=E9=85=8D=E5=8E=9F=E5=A7=8B=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E7=9A=84=E6=96=B9=E6=B3=95=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?ClashDetective=E7=A2=B0=E6=92=9E=E7=BB=93=E6=9E=9C=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Collision/ClashDetectiveIntegration.cs | 90 +++++++++++++++++-- 1 file changed, 85 insertions(+), 5 deletions(-) diff --git a/src/Core/Collision/ClashDetectiveIntegration.cs b/src/Core/Collision/ClashDetectiveIntegration.cs index fed0b0b..a275f57 100644 --- a/src/Core/Collision/ClashDetectiveIntegration.cs +++ b/src/Core/Collision/ClashDetectiveIntegration.cs @@ -497,6 +497,80 @@ namespace NavisworksTransport return new Point3D(0, 0, 0); } } + + /// + /// 通过PathId向上查找匹配的原始对象 + /// 从ClashDetective返回的几何体组件开始,向上遍历父节点, + /// 直到找到与预计算记录中任一对象PathId匹配的父节点 + /// + private ModelItem FindMatchingObjectByPathId(ModelItem clashItem2, List precomputedCollisions) + { + try + { + if (precomputedCollisions == null || precomputedCollisions.Count == 0 || clashItem2 == null) + return null; + + var doc = Application.ActiveDocument; + if (doc?.Models == null) return null; + + // 1. 收集所有预计算记录中Item2的PathId(作为HashSet提高查找效率) + var precomputedPathIds = new HashSet<(int ModelIndex, string PathId)>(); + foreach (var precomputed in precomputedCollisions) + { + if (precomputed.Item2 != null) + { + try + { + var pathId = doc.Models.CreatePathId(precomputed.Item2); + precomputedPathIds.Add((pathId.ModelIndex, pathId.PathId)); + } + catch { /* 忽略获取PathId失败的记录 */ } + } + } + + if (precomputedPathIds.Count == 0) + { + LogManager.Debug($"[PathId匹配] 预计算记录中没有有效的PathId"); + return null; + } + + // 2. 从ClashDetective返回的Item2开始向上遍历父节点 + var current = clashItem2; + int levels = 0; + while (current != null && levels < 20) // 最多向上查找20层 + { + try + { + var currentPathId = doc.Models.CreatePathId(current); + + // 检查PathId是否在预计算记录中 + if (precomputedPathIds.Contains((currentPathId.ModelIndex, currentPathId.PathId))) + { + LogManager.Debug($"[PathId匹配] 成功找到匹配的父节点: {ModelItemAnalysisHelper.GetSafeDisplayName(current)} (向上{levels}层)"); + return current; + } + + // 继续向上查找 + current = current.Parent; + levels++; + } + catch + { + // 如果当前节点无法获取PathId,继续向上 + current = current.Parent; + levels++; + } + } + + LogManager.Debug($"[PathId匹配] 未找到匹配的父节点,向上查找了{levels}层"); + return null; + } + catch (Exception ex) + { + LogManager.Warning($"[PathId匹配] 查找失败: {ex.Message}"); + return null; + } + } /// /// 运行ClashDetective测试并保存到数据库(公共方法,供批处理和非批处理调用) @@ -758,22 +832,28 @@ namespace NavisworksTransport // 第三步:处理碰撞结果 // 🔥 重要:ClashDetective 返回的是几何体级别的碰撞结果 // Item1 是移动物体的组件名(如"车轮1"、"车轮2"),需要统一为移动物体本身 - // Item2 是被撞物体,需要向上查找有意义的父级容器 + // Item2 是被撞物体,通过PathId向上查找匹配预计算中的原始对象 var clashResults = new List(); foreach (var child in collisionGroup.Children) { if (child is ClashResult clashResult) { - var compositeItem1 = animatedObject; - var compositeItem2 = ModelItemAnalysisHelper.FindNamedParentContainer(clashResult.Item2); + // 🔥 通过PathId向上查找匹配的原始对象 + // 从ClashDetective返回的几何体组件开始,向上遍历父节点, + // 直到找到与预计算记录中任一对象PathId匹配的父节点 + ModelItem originalItem2 = FindMatchingObjectByPathId(clashResult.Item2, precomputedCollisions); + if (originalItem2 == null) + { + originalItem2 = clashResult.Item2; // 回退到原始对象 + } var collisionResult = new CollisionResult { ClashGuid = clashResult.Guid, DisplayName = clashResult.DisplayName, Status = clashResult.Status, - Item1 = compositeItem1, - Item2 = compositeItem2, + Item1 = animatedObject, + Item2 = originalItem2, Center = clashResult.Center, Distance = clashResult.Distance, CreatedTime = DateTime.Now