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