动画结束用clashdetective结果高亮,整理高亮架构
This commit is contained in:
parent
4f7935499d
commit
ffac0ae146
@ -5,7 +5,8 @@
|
||||
### [2026/1/6]
|
||||
|
||||
1. [ ] (BUG)虚拟车辆模型每次点击都重建
|
||||
2. [ ] (BUG)碰撞结果高亮,应该显示精确检测的结果
|
||||
2. [x] (BUG)碰撞结果高亮,应该显示clashdetective检测的结果
|
||||
3. [ ] (优化)对clashdetective的检测结果,进行向上合并,找到集合对象。
|
||||
|
||||
### [2025/12/25]
|
||||
|
||||
|
||||
@ -330,17 +330,12 @@ namespace NavisworksTransport.Commands
|
||||
{
|
||||
LogManager.Info("开始收集所有碰撞数据及统计信息...");
|
||||
|
||||
var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
|
||||
var documentClash = doc.GetClash();
|
||||
|
||||
if (documentClash == null)
|
||||
var clashIntegration = ClashDetectiveIntegration.Instance;
|
||||
if (clashIntegration == null)
|
||||
{
|
||||
LogManager.Warning("无法获取 Clash Detective 文档,无法收集碰撞数据");
|
||||
return result;
|
||||
throw new InvalidOperationException("无法获取ClashDetectiveIntegration实例");
|
||||
}
|
||||
|
||||
int totalCollisionCount = 0; // Clash Detective总碰撞数
|
||||
|
||||
// 从动画管理器获取当前路径名称
|
||||
var animationManager = Core.Animation.PathAnimationManager.GetInstance();
|
||||
var currentPathName = animationManager?.PathName;
|
||||
@ -350,30 +345,41 @@ namespace NavisworksTransport.Commands
|
||||
throw new InvalidOperationException("无法获取当前路径名称");
|
||||
}
|
||||
|
||||
// 精确匹配当前路径的测试
|
||||
var matchedTest = documentClash.TestsData.Tests.Cast<ClashTest>()
|
||||
.Where(t => t.DisplayName.StartsWith("物流碰撞检测_") &&
|
||||
t.DisplayName.Contains(currentPathName))
|
||||
.OrderByDescending(t => t.DisplayName)
|
||||
.FirstOrDefault();
|
||||
// 使用公共方法获取当前路径的测试
|
||||
var matchedTest = clashIntegration.GetCurrentPathClashTest(currentPathName);
|
||||
|
||||
if (matchedTest != null)
|
||||
{
|
||||
LogManager.Info($"找到当前路径的测试: {matchedTest.DisplayName}");
|
||||
|
||||
// 提取匹配测试的碰撞数据
|
||||
var testCollisions = ExtractCollisionsFromTest(matchedTest);
|
||||
allCollisions.AddRange(testCollisions);
|
||||
|
||||
// 统计匹配测试的碰撞总数
|
||||
totalCollisionCount = GetTotalClashResultCountFromTest(matchedTest);
|
||||
LogManager.Debug($"匹配测试 '{matchedTest.DisplayName}' 包含 {totalCollisionCount} 个碰撞");
|
||||
}
|
||||
else
|
||||
if (matchedTest == null)
|
||||
{
|
||||
throw new InvalidOperationException($"未找到路径 '{currentPathName}' 的碰撞测试");
|
||||
}
|
||||
|
||||
LogManager.Info($"找到当前路径的测试: {matchedTest.DisplayName}");
|
||||
|
||||
// 使用ClashDetectiveIntegration的方法提取碰撞数据
|
||||
var testCollisionsRaw = clashIntegration.ExtractClashResultsFromTest(matchedTest);
|
||||
|
||||
// 转换为CollisionResult对象
|
||||
foreach (var clash in testCollisionsRaw)
|
||||
{
|
||||
var collision = new CollisionResult
|
||||
{
|
||||
ClashGuid = clash.Guid,
|
||||
DisplayName = $"[{matchedTest.DisplayName}] {clash.DisplayName}",
|
||||
Status = clash.Status,
|
||||
Item1 = clash.Item1,
|
||||
Item2 = clash.Item2,
|
||||
Center = clash.Center,
|
||||
Distance = clash.Distance,
|
||||
CreatedTime = DateTime.Now
|
||||
};
|
||||
allCollisions.Add(collision);
|
||||
}
|
||||
|
||||
// 统计匹配测试的碰撞总数
|
||||
var totalCollisionCount = testCollisionsRaw.Count;
|
||||
result.ClashDetectiveCollisionCount = totalCollisionCount;
|
||||
LogManager.Debug($"匹配测试 '{matchedTest.DisplayName}' 包含 {totalCollisionCount} 个碰撞");
|
||||
|
||||
// 去重处理
|
||||
var uniqueCollisions = allCollisions
|
||||
.GroupBy(c => new { c.Item1, c.Item2, c.Center })
|
||||
@ -419,7 +425,6 @@ namespace NavisworksTransport.Commands
|
||||
result.AllCollisions = uniqueCollisions;
|
||||
result.UniqueCollidedObjects = uniqueCollidedObjectsSet;
|
||||
result.BoundingBoxTestCount = 0;
|
||||
result.ClashDetectiveCollisionCount = totalCollisionCount;
|
||||
|
||||
// 从碰撞结果的Item1中获取运动构件信息
|
||||
if (uniqueCollisions.Count > 0 && uniqueCollisions[0].Item1 != null)
|
||||
@ -445,118 +450,6 @@ namespace NavisworksTransport.Commands
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从测试中提取碰撞结果
|
||||
/// </summary>
|
||||
private List<CollisionResult> ExtractCollisionsFromTest(ClashTest clashTest)
|
||||
{
|
||||
var results = new List<CollisionResult>();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var child in clashTest.Children)
|
||||
{
|
||||
if (child is ClashResult clashResult)
|
||||
{
|
||||
var collision = new CollisionResult
|
||||
{
|
||||
ClashGuid = clashResult.Guid,
|
||||
DisplayName = $"[{clashTest.DisplayName}] {clashResult.DisplayName}",
|
||||
Status = clashResult.Status,
|
||||
Item1 = clashResult.Item1,
|
||||
Item2 = clashResult.Item2,
|
||||
Center = clashResult.Center,
|
||||
Distance = clashResult.Distance,
|
||||
CreatedTime = DateTime.Now
|
||||
};
|
||||
|
||||
results.Add(collision);
|
||||
}
|
||||
else if (child is ClashResultGroup resultGroup)
|
||||
{
|
||||
// 处理分组结果
|
||||
foreach (var groupChild in resultGroup.Children)
|
||||
{
|
||||
if (groupChild is ClashResult groupResult)
|
||||
{
|
||||
var collision = new CollisionResult
|
||||
{
|
||||
ClashGuid = groupResult.Guid,
|
||||
DisplayName = $"[{clashTest.DisplayName}] {groupResult.DisplayName}",
|
||||
Status = groupResult.Status,
|
||||
Item1 = groupResult.Item1,
|
||||
Item2 = groupResult.Item2,
|
||||
Center = groupResult.Center,
|
||||
Distance = groupResult.Distance,
|
||||
CreatedTime = DateTime.Now
|
||||
};
|
||||
|
||||
results.Add(collision);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"从测试 {clashTest.DisplayName} 提取结果失败: {ex.Message}");
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归统计测试中的碰撞结果总数(包括分组内的结果)
|
||||
/// </summary>
|
||||
/// <param name="test">要统计的测试</param>
|
||||
/// <returns>碰撞结果总数</returns>
|
||||
private int GetTotalClashResultCountFromTest(ClashTest test)
|
||||
{
|
||||
if (test == null) return 0;
|
||||
|
||||
int totalCount = 0;
|
||||
foreach (var child in test.Children)
|
||||
{
|
||||
if (child is ClashResult)
|
||||
{
|
||||
totalCount++;
|
||||
}
|
||||
else if (child is ClashResultGroup group)
|
||||
{
|
||||
// 递归统计分组内的结果
|
||||
totalCount += CountClashResultsInGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归统计分组内的碰撞结果数量
|
||||
/// </summary>
|
||||
/// <param name="group">分组</param>
|
||||
/// <returns>分组内的碰撞结果总数</returns>
|
||||
private int CountClashResultsInGroup(ClashResultGroup group)
|
||||
{
|
||||
if (group == null) return 0;
|
||||
|
||||
int count = 0;
|
||||
foreach (var child in group.Children)
|
||||
{
|
||||
if (child is ClashResult)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else if (child is ClashResultGroup nestedGroup)
|
||||
{
|
||||
// 递归处理嵌套分组
|
||||
count += CountClashResultsInGroup(nestedGroup);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成报告内容
|
||||
/// </summary>
|
||||
|
||||
@ -936,6 +936,10 @@ namespace NavisworksTransport.Core.Animation
|
||||
_lastHighlightState = false; // 重置高亮状态
|
||||
_lastCollisionObjects.Clear(); // 重置碰撞对象集合
|
||||
|
||||
// 清除所有碰撞高亮
|
||||
ModelHighlightHelper.ClearCollisionHighlights();
|
||||
LogManager.Debug("[动画开始] 已清除所有碰撞高亮");
|
||||
|
||||
// 启动动画播放
|
||||
StartAnimationPlayback();
|
||||
|
||||
@ -1050,18 +1054,6 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
}
|
||||
|
||||
// 高亮显示所有碰撞过的对象
|
||||
if (allCollisionResults.Count > 0)
|
||||
{
|
||||
ClashDetectiveIntegration.Instance.HighlightCollisions(allCollisionResults);
|
||||
LogManager.Info($"动画停止,高亮显示路径上的 {uniqueCollidedItems.Count} 个碰撞对象");
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelHighlightHelper.ClearCategory("collisionresults");
|
||||
LogManager.Info("动画停止,路径上无碰撞对象");
|
||||
}
|
||||
|
||||
SetState(AnimationState.Stopped);
|
||||
_pausedProgress = 0.0; // 重置暂停进度
|
||||
_currentFrameIndex = 0; // 重置帧索引
|
||||
@ -1148,18 +1140,6 @@ namespace NavisworksTransport.Core.Animation
|
||||
.Select(g => g.First())
|
||||
.ToList();
|
||||
|
||||
// 高亮显示所有碰撞过的对象
|
||||
if (allCollisionResults.Count > 0)
|
||||
{
|
||||
ClashDetectiveIntegration.Instance.HighlightCollisions(allCollisionResults);
|
||||
LogManager.Info($"动画完成,高亮显示路径上的 {allCollisionResults.Count} 个碰撞对象(基于预计算结果)");
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelHighlightHelper.ClearCategory("collisionresults");
|
||||
LogManager.Info("动画完成,路径上无碰撞对象");
|
||||
}
|
||||
|
||||
// 将物体移回起点位置并恢复初始朝向
|
||||
if (_pathPoints != null && _pathPoints.Count > 0 && _animatedObject != null)
|
||||
{
|
||||
@ -2316,7 +2296,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
else
|
||||
{
|
||||
// 无碰撞:清除高亮
|
||||
ModelHighlightHelper.ClearCategory("collisionresults");
|
||||
ModelHighlightHelper.ClearCollisionHighlights();
|
||||
LogManager.Debug($"[高亮状态] 帧{_currentFrameIndex}: 清除高亮");
|
||||
}
|
||||
|
||||
|
||||
@ -634,24 +634,15 @@ namespace NavisworksTransport
|
||||
// 刷新Clash Detective窗口
|
||||
RefreshClashDetectiveUI();
|
||||
|
||||
// 自动高亮所有碰撞结果(使用类别管理)
|
||||
// 自动高亮ClashDetective结果
|
||||
try
|
||||
{
|
||||
// 使用过滤后的预计算结果进行高亮
|
||||
var validResults = collisionResults.Where(r =>
|
||||
IsModelItemValid(r.Item1) && IsModelItemValid(r.Item2)).ToList();
|
||||
|
||||
if (validResults.Count > 0)
|
||||
{
|
||||
// 使用类别管理的高亮方式
|
||||
var darkRed = Color.Red; // 红色(暗红色在Navisworks API中不可用)
|
||||
ManageHighlightsByCategory(ModelHighlightHelper.CollisionResultsCategory, validResults, darkRed, true);
|
||||
LogManager.Info($"自动高亮显示 {validResults.Count} 个动画结束后的碰撞结果(暗红色)");
|
||||
}
|
||||
HighlightClashDetectiveResults(pathName);
|
||||
LogManager.Info("自动高亮ClashDetective检测结果完成");
|
||||
}
|
||||
catch (Exception highlightEx)
|
||||
catch (Exception clashHighlightEx)
|
||||
{
|
||||
LogManager.Error($"动画结束后自动高亮失败: {highlightEx.Message}");
|
||||
LogManager.Error($"自动高亮ClashDetective结果失败: {clashHighlightEx.Message}");
|
||||
}
|
||||
|
||||
// 更新Clash Detective碰撞计数器 - 统计分组测试中的碰撞数量
|
||||
@ -849,21 +840,228 @@ namespace NavisworksTransport
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有高亮
|
||||
/// 高亮ClashDetective测试结果
|
||||
/// </summary>
|
||||
public void ClearHighlights()
|
||||
public void HighlightClashDetectiveResults(string pathName)
|
||||
{
|
||||
try
|
||||
{
|
||||
ModelHighlightHelper.ClearAllHighlights();
|
||||
LogManager.Debug("已清除所有碰撞高亮");
|
||||
// 使用公共方法获取指定路径的碰撞结果
|
||||
var clashResults = GetCurrentPathClashResults(pathName);
|
||||
|
||||
if (clashResults.Count == 0)
|
||||
{
|
||||
LogManager.Info("[ClashDetective高亮] 指定路径测试中未找到碰撞结果");
|
||||
return;
|
||||
}
|
||||
|
||||
// 提取碰撞对象
|
||||
var highlightItems = new List<ModelItem>();
|
||||
foreach (var clash in clashResults)
|
||||
{
|
||||
if (clash.Item1 != null && !highlightItems.Contains(clash.Item1) &&
|
||||
ModelItemAnalysisHelper.IsModelItemValid(clash.Item1))
|
||||
{
|
||||
highlightItems.Add(clash.Item1);
|
||||
}
|
||||
|
||||
if (clash.Item2 != null && !highlightItems.Contains(clash.Item2) &&
|
||||
ModelItemAnalysisHelper.IsModelItemValid(clash.Item2))
|
||||
{
|
||||
highlightItems.Add(clash.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
if (highlightItems.Count > 0)
|
||||
{
|
||||
ModelHighlightHelper.HighlightItems(
|
||||
ModelHighlightHelper.ClashDetectiveResultsCategory,
|
||||
highlightItems,
|
||||
Color.Red
|
||||
);
|
||||
LogManager.Info($"[ClashDetective高亮] 已高亮 {highlightItems.Count} 个对象,来自 {clashResults.Count} 个碰撞结果");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Info("[ClashDetective高亮] 没有有效的碰撞对象可高亮");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"清除高亮失败: {ex.Message}");
|
||||
LogManager.Error($"[ClashDetective高亮] 高亮失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除ClashDetective高亮
|
||||
/// </summary>
|
||||
public void ClearClashDetectiveHighlights()
|
||||
{
|
||||
try
|
||||
{
|
||||
ModelHighlightHelper.ClearCategory(ModelHighlightHelper.ClashDetectiveResultsCategory);
|
||||
LogManager.Info("[ClashDetective高亮] 已清除高亮");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[ClashDetective高亮] 清除高亮失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有物流碰撞检测测试
|
||||
/// </summary>
|
||||
/// <returns>物流碰撞检测测试列表</returns>
|
||||
public List<ClashTest> GetLogisticsClashTests()
|
||||
{
|
||||
if (_documentClash == null)
|
||||
{
|
||||
return new List<ClashTest>();
|
||||
}
|
||||
|
||||
return _documentClash.TestsData.Tests.Cast<ClashTest>()
|
||||
.Where(t => t.DisplayName.Contains("物流碰撞检测") ||
|
||||
t.DisplayName.Contains("物流碰撞"))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前路径的Clash测试
|
||||
/// </summary>
|
||||
/// <param name="pathName">路径名称</param>
|
||||
/// <returns>当前路径的测试,如果未找到则返回null</returns>
|
||||
public ClashTest GetCurrentPathClashTest(string pathName)
|
||||
{
|
||||
if (_documentClash == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(pathName))
|
||||
{
|
||||
LogManager.Info("[获取当前路径测试] 路径名称为空");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取所有物流碰撞检测测试
|
||||
var logisticsTests = GetLogisticsClashTests();
|
||||
|
||||
if (logisticsTests.Count == 0)
|
||||
{
|
||||
LogManager.Info("[获取当前路径测试] 未找到物流碰撞检测测试");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 精确匹配当前路径的测试
|
||||
var matchedTest = logisticsTests
|
||||
.Where(t => t.DisplayName.StartsWith("物流碰撞检测_") &&
|
||||
t.DisplayName.Contains(pathName))
|
||||
.OrderByDescending(t => t.DisplayName)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (matchedTest != null)
|
||||
{
|
||||
LogManager.Info($"[获取当前路径测试] 找到路径 '{pathName}' 的测试: {matchedTest.DisplayName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Info($"[获取当前路径测试] 未找到路径 '{pathName}' 的碰撞测试");
|
||||
}
|
||||
|
||||
return matchedTest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前路径的Clash结果
|
||||
/// </summary>
|
||||
/// <param name="pathName">路径名称</param>
|
||||
/// <returns>当前路径的碰撞结果列表</returns>
|
||||
public List<ClashResult> GetCurrentPathClashResults(string pathName)
|
||||
{
|
||||
var matchedTest = GetCurrentPathClashTest(pathName);
|
||||
|
||||
if (matchedTest == null)
|
||||
{
|
||||
return new List<ClashResult>();
|
||||
}
|
||||
|
||||
return ExtractClashResultsFromTest(matchedTest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从测试中提取碰撞结果
|
||||
/// </summary>
|
||||
/// <param name="clashTest">测试</param>
|
||||
/// <returns>碰撞结果列表</returns>
|
||||
public List<ClashResult> ExtractClashResultsFromTest(ClashTest clashTest)
|
||||
{
|
||||
var results = new List<ClashResult>();
|
||||
ExtractClashResultsFromTestRecursive(clashTest, results);
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归提取测试中的碰撞结果
|
||||
/// </summary>
|
||||
/// <param name="clashTest">测试</param>
|
||||
/// <param name="results">结果列表</param>
|
||||
private void ExtractClashResultsFromTestRecursive(ClashTest clashTest, List<ClashResult> results)
|
||||
{
|
||||
if (clashTest == null || results == null) return;
|
||||
|
||||
foreach (var child in clashTest.Children)
|
||||
{
|
||||
if (child is ClashResult clashResult)
|
||||
{
|
||||
results.Add(clashResult);
|
||||
}
|
||||
else if (child is ClashResultGroup resultGroup)
|
||||
{
|
||||
ExtractClashResultsFromGroupRecursive(resultGroup, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归提取分组中的碰撞结果
|
||||
/// </summary>
|
||||
/// <param name="group">分组</param>
|
||||
/// <param name="results">结果列表</param>
|
||||
private void ExtractClashResultsFromGroupRecursive(ClashResultGroup group, List<ClashResult> results)
|
||||
{
|
||||
if (group == null || results == null) return;
|
||||
|
||||
foreach (var child in group.Children)
|
||||
{
|
||||
if (child is ClashResult result)
|
||||
{
|
||||
results.Add(result);
|
||||
}
|
||||
else if (child is ClashResultGroup subGroup)
|
||||
{
|
||||
ExtractClashResultsFromGroupRecursive(subGroup, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有物流碰撞检测的碰撞结果
|
||||
/// </summary>
|
||||
/// <returns>碰撞结果列表</returns>
|
||||
public List<ClashResult> GetAllLogisticsClashResults()
|
||||
{
|
||||
var tests = GetLogisticsClashTests();
|
||||
var allResults = new List<ClashResult>();
|
||||
|
||||
foreach (var test in tests)
|
||||
{
|
||||
var results = ExtractClashResultsFromTest(test);
|
||||
allResults.AddRange(results);
|
||||
}
|
||||
|
||||
return allResults;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按类别管理高亮显示
|
||||
/// </summary>
|
||||
|
||||
@ -132,7 +132,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
private const string ManualTargetsHighlightCategory = ModelHighlightHelper.ManualTargetsCategory;
|
||||
private const string CollisionResultsHighlightCategory = ModelHighlightHelper.CollisionResultsCategory;
|
||||
private static readonly Color ManualTargetHighlightColor = Color.FromByteRGB(255, 170, 0);
|
||||
private static readonly Color CollisionResultHighlightColor = Color.Red;
|
||||
private static readonly Color CollisionResultHighlightColor = Color.FromByteRGB(244, 67, 54); // Material Red(与路径终点颜色一致)
|
||||
|
||||
#endregion
|
||||
|
||||
@ -228,6 +228,19 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private bool _hasClashDetectiveResults;
|
||||
public bool HasClashDetectiveResults
|
||||
{
|
||||
get => _hasClashDetectiveResults;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _hasClashDetectiveResults, value))
|
||||
{
|
||||
System.Windows.Input.CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
@ -637,6 +650,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
public ICommand ClearManualHighlightsCommand { get; private set; }
|
||||
public ICommand HighlightCollisionResultsCommand { get; private set; }
|
||||
public ICommand ClearCollisionHighlightsCommand { get; private set; }
|
||||
public ICommand HighlightClashDetectiveResultsCommand { get; private set; }
|
||||
public ICommand ClearClashDetectiveHighlightsCommand { get; private set; }
|
||||
|
||||
// 媒体控制命令
|
||||
public ICommand PlayForwardCommand { get; private set; }
|
||||
@ -769,6 +784,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
ClearManualHighlightsCommand = new RelayCommand(ExecuteClearManualHighlights, () => HasManualCollisionTargets);
|
||||
HighlightCollisionResultsCommand = new RelayCommand(ExecuteHighlightCollisionResults, () => HasCollisionResults);
|
||||
ClearCollisionHighlightsCommand = new RelayCommand(ExecuteClearCollisionHighlights, () => HasCollisionResults);
|
||||
HighlightClashDetectiveResultsCommand = new RelayCommand(ExecuteHighlightClashDetectiveResults, () => HasClashDetectiveResults);
|
||||
ClearClashDetectiveHighlightsCommand = new RelayCommand(ExecuteClearClashDetectiveHighlights, () => HasClashDetectiveResults);
|
||||
PlayForwardCommand = new RelayCommand(ExecutePlayForward, CanExecuteMediaCommands);
|
||||
PlayReverseCommand = new RelayCommand(ExecutePlayReverse, CanExecuteMediaCommands);
|
||||
StepForwardCommand = new RelayCommand(ExecuteStepForward, CanExecuteMediaCommands);
|
||||
@ -828,6 +845,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
_pathAnimationManager?.ClearExclusionCache();
|
||||
LogManager.Info("已清理UI层碰撞检测缓存");
|
||||
|
||||
// 清理之前的碰撞高亮
|
||||
ModelHighlightHelper.ClearCollisionHighlights();
|
||||
LogManager.Info("已清理之前的碰撞高亮");
|
||||
|
||||
// 首先重置进度(开始全新动画时)
|
||||
|
||||
_pathAnimationManager.StartAnimation();
|
||||
@ -1281,6 +1302,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
CanStopAnimation = false;
|
||||
UpdateMainStatus("动画已完成");
|
||||
UpdateMediaControlProperties(); // 更新媒体控制属性
|
||||
// 检查并高亮ClashDetective结果
|
||||
CheckAndHighlightClashDetectiveResults();
|
||||
break;
|
||||
case NavisworksTransport.Core.Animation.AnimationState.Stopped:
|
||||
CanStartAnimation = true;
|
||||
@ -1288,6 +1311,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
CanStopAnimation = false;
|
||||
UpdateMainStatus("动画已停止");
|
||||
UpdateMediaControlProperties(); // 更新媒体控制属性
|
||||
// 检查并高亮ClashDetective结果
|
||||
CheckAndHighlightClashDetectiveResults();
|
||||
break;
|
||||
default:
|
||||
UpdateMainStatus($"动画状态: {state}");
|
||||
@ -1297,6 +1322,38 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查并高亮ClashDetective结果
|
||||
/// </summary>
|
||||
private void CheckAndHighlightClashDetectiveResults()
|
||||
{
|
||||
try
|
||||
{
|
||||
var animationManager = Core.Animation.PathAnimationManager.GetInstance();
|
||||
var pathName = animationManager?.PathName;
|
||||
|
||||
if (string.IsNullOrEmpty(pathName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否有该路径的ClashDetective结果
|
||||
var clashResults = _clashIntegration?.GetCurrentPathClashResults(pathName);
|
||||
|
||||
if (clashResults != null && clashResults.Count > 0)
|
||||
{
|
||||
// 有ClashDetective结果,高亮显示
|
||||
_clashIntegration?.HighlightClashDetectiveResults(pathName);
|
||||
HasClashDetectiveResults = true;
|
||||
LogManager.Info($"动画结束,已高亮ClashDetective检测结果:{clashResults.Count}个碰撞");
|
||||
}
|
||||
// 如果没有ClashDetective结果,不做处理(可能第一次运行会自动计算,或者没有碰撞)
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"检查并高亮ClashDetective结果失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理碰撞检测事件 - 自动生成报告并保存数据库
|
||||
@ -1308,7 +1365,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
if (!HasCollisionResults)
|
||||
{
|
||||
ModelHighlightHelper.ClearCategory(CollisionResultsHighlightCategory);
|
||||
ModelHighlightHelper.ClearCollisionHighlights();
|
||||
}
|
||||
|
||||
var collisionCount = _latestCollisionResults.Count;
|
||||
@ -1334,6 +1391,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
UpdateMainStatus($"✅ 碰撞报告已生成并保存:{collisionCount} 个碰撞");
|
||||
LogManager.Info("碰撞报告已自动生成并保存到数据库");
|
||||
|
||||
// 高亮ClashDetective结果
|
||||
var animationManager = Core.Animation.PathAnimationManager.GetInstance();
|
||||
var pathName = animationManager?.PathName ?? "未知路径";
|
||||
_clashIntegration?.HighlightClashDetectiveResults(pathName);
|
||||
HasClashDetectiveResults = true;
|
||||
LogManager.Info("已自动高亮ClashDetective检测结果");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1423,8 +1487,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
UpdateCanGenerateAnimation();
|
||||
|
||||
// 3. 清理高亮
|
||||
_clashIntegration?.ClearHighlights();
|
||||
ModelHighlightHelper.ClearCategory(CollisionResultsHighlightCategory);
|
||||
ModelHighlightHelper.ClearCollisionHighlights();
|
||||
|
||||
LogManager.Info("移动物体已完全清除并归位");
|
||||
UpdateMainStatus("已清除物体选择并恢复位置");
|
||||
@ -1583,6 +1646,20 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
UpdateMainStatus("已清除碰撞结果高亮");
|
||||
}
|
||||
|
||||
private void ExecuteHighlightClashDetectiveResults()
|
||||
{
|
||||
var animationManager = Core.Animation.PathAnimationManager.GetInstance();
|
||||
var pathName = animationManager?.PathName ?? "未知路径";
|
||||
_clashIntegration?.HighlightClashDetectiveResults(pathName);
|
||||
UpdateMainStatus("已高亮ClashDetective检测结果");
|
||||
}
|
||||
|
||||
private void ExecuteClearClashDetectiveHighlights()
|
||||
{
|
||||
_clashIntegration?.ClearClashDetectiveHighlights();
|
||||
UpdateMainStatus("已清除ClashDetective高亮");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@ -2460,8 +2537,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
// 清空碰撞结果
|
||||
HasCollisionResults = false;
|
||||
HasClashDetectiveResults = false;
|
||||
_latestCollisionResults.Clear();
|
||||
ModelHighlightHelper.ClearCategory(CollisionResultsHighlightCategory);
|
||||
ModelHighlightHelper.ClearCollisionHighlights();
|
||||
|
||||
UpdateMainStatus("已重置");
|
||||
}
|
||||
|
||||
@ -379,14 +379,24 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
IsEnabled="{Binding HasCollisionResults}"
|
||||
Style="{StaticResource ActionButtonStyle}"
|
||||
Margin="0,0,8,0"/>
|
||||
<Button Content="结果高亮"
|
||||
<Button Content="预计算高亮"
|
||||
Command="{Binding HighlightCollisionResultsCommand}"
|
||||
IsEnabled="{Binding HasCollisionResults}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Margin="0,0,8,0"/>
|
||||
<Button Content="清除高亮"
|
||||
<Button Content="清除预计算高亮"
|
||||
Command="{Binding ClearCollisionHighlightsCommand}"
|
||||
IsEnabled="{Binding HasCollisionResults}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Margin="0,0,8,0"/>
|
||||
<Button Content="结果高亮"
|
||||
Command="{Binding HighlightClashDetectiveResultsCommand}"
|
||||
IsEnabled="{Binding HasClashDetectiveResults}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Margin="0,0,8,0"/>
|
||||
<Button Content="清除高亮"
|
||||
Command="{Binding ClearClashDetectiveHighlightsCommand}"
|
||||
IsEnabled="{Binding HasClashDetectiveResults}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
@ -10,9 +10,10 @@ namespace NavisworksTransport.Utils
|
||||
/// </summary>
|
||||
public static class ModelHighlightHelper
|
||||
{
|
||||
public const string CollisionResultsCategory = "collisionresults";
|
||||
public const string CollisionResultsCategory = "collisionResults";
|
||||
public const string ManualTargetsCategory = "manualTargets";
|
||||
public const string ChannelPreviewCategory = "channel_preview";
|
||||
public const string ChannelPreviewCategory = "channelPreview";
|
||||
public const string ClashDetectiveResultsCategory = "clashDetectiveResults";
|
||||
|
||||
private class HighlightEntry
|
||||
{
|
||||
@ -41,8 +42,9 @@ namespace NavisworksTransport.Utils
|
||||
{ "report", Color.Green },
|
||||
{ "preview", Color.Blue },
|
||||
{ ManualTargetsCategory, Color.FromByteRGB(255, 170, 0) },
|
||||
{ CollisionResultsCategory, Color.Red },
|
||||
{ ChannelPreviewCategory, Color.Green }
|
||||
{ CollisionResultsCategory, Color.Green },
|
||||
{ ChannelPreviewCategory, Color.Green },
|
||||
{ ClashDetectiveResultsCategory, Color.Red }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@ -123,6 +125,18 @@ namespace NavisworksTransport.Utils
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有碰撞相关高亮(预计算碰撞和ClashDetective碰撞)
|
||||
/// </summary>
|
||||
public static void ClearCollisionHighlights()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
ClearCategory(CollisionResultsCategory);
|
||||
ClearCategory(ClashDetectiveResultsCategory);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除全部高亮。
|
||||
/// </summary>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user