向上查找复合节点,处理clashdetective碰撞结果,优化碰撞报告生成逻辑

This commit is contained in:
tian 2026-01-08 11:42:56 +08:00
parent c044be57c0
commit d473065025
5 changed files with 177 additions and 262 deletions

View File

@ -6,7 +6,7 @@
1. [ ] BUG虚拟车辆模型每次点击都重建
2. [x] BUG碰撞结果高亮应该显示clashdetective检测的结果
3. [ ] 优化对clashdetective的检测结果进行向上合并找到集合对象。
3. [x] 优化对clashdetective的检测结果进行向上合并找到集合对象。
### [2025/12/25]

View File

@ -58,6 +58,7 @@ namespace NavisworksTransport.Commands
public List<CollisionResult> AllCollisions { get; set; } = new List<CollisionResult>();
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
/// <summary>
/// 获取当前最新的物流碰撞检测测试名称作为缓存键
/// </summary>
/// <returns>测试名称,如果未找到则返回 null</returns>
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<ClashTest>()
.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; // 让错误暴露出来
}
}
/// <summary>
/// 清理过期缓存(可选功能)
/// </summary>
@ -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<string, int>();
var uniqueCollidedObjectsList = new List<string>();
// 新增:统计去重后的被撞物体
// 使用DictionaryModelItem作为键会自动调用Equals进行比较
var uniqueCollidedObjectsDict = new Dictionary<ModelItem, string>();
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<string, int>();
var uniqueCollidedObjectsList = new List<string>();
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<string>(uniqueCollidedObjectsList);
result.AllCollisions = uniqueCollisions;
result.UniqueCollidedObjects = uniqueCollidedObjectsSet;
result.AllCollisions = allCollisions;
result.UniqueCollidedObjects = new HashSet<string>(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;
}

View File

@ -50,6 +50,16 @@ namespace NavisworksTransport
get { return _clashDetectiveCollisionCount; }
}
/// <summary>
/// 当前ClashDetective测试名称
/// </summary>
public string CurrentTestName
{
get { return _currentTestName; }
}
private string _currentTestName;
/// <summary>
/// 单例实例
/// </summary>
@ -129,8 +139,9 @@ namespace NavisworksTransport
private List<CollisionResult> _cachedResults = new List<CollisionResult>();
private readonly object _resultsLock = new object();
// ClashDetective测试结果缓存pathName -> List<ClashResult>
private Dictionary<string, List<ClashResult>> _clashDetectiveResultsCache = new Dictionary<string, List<ClashResult>>();
// ClashDetective测试结果缓存pathName -> List<CollisionResult>
// 使用自定义的CollisionResult类型支持修改Item1和Item2
private Dictionary<string, List<CollisionResult>> _clashDetectiveResultsCache = new Dictionary<string, List<CollisionResult>>();
private readonly object _clashResultsCacheLock = new object();
/// <summary>
@ -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<string, CollisionResult>();
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<ClashResult>();
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<ClashTest>()
.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
/// <summary>
/// 高亮ClashDetective测试结果
/// </summary>
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
/// </summary>
/// <param name="pathName">路径名称</param>
/// <returns>当前路径的碰撞结果列表</returns>
public List<ClashResult> GetCurrentPathClashResults(string pathName)
public List<CollisionResult> 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;
/// <summary>
/// 获取当前测试的碰撞结果(便捷方法)
/// </summary>
/// <returns>当前测试的碰撞结果列表</returns>
public List<CollisionResult> GetCurrentTestResults()
{
return GetCurrentPathClashResults(_currentTestName);
}
/// <summary>

View File

@ -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检测结果");
}

View File

@ -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 "获取失败";
}
}
/// <summary>
/// 向上查找IsComposite为true的复合对象祖先节点
/// </summary>
/// <param name="item">要查找的ModelItem</param>
/// <param name="maxDepth">最大向上查找深度,防止无限递归</param>
/// <returns>找到的复合对象祖先节点,如果未找到则返回当前节点</returns>
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;
}
}
}
}