重构碰撞报告生成逻辑,无碰撞也生成报告;修改通行空间为浅绿色;

This commit is contained in:
tian 2026-01-23 18:40:54 +08:00
parent 4c34340fdb
commit 3905db56bc
5 changed files with 145 additions and 152 deletions

View File

@ -99,20 +99,6 @@ namespace NavisworksTransport.Commands
/// </summary>
public class GenerateCollisionReportCommand : CommandBase
{
#region
/// <summary>
/// 碰撞报告结果缓存 - 使用测试名称作为键
/// </summary>
private static readonly Dictionary<string, CollisionReportResult> _reportCache = new Dictionary<string, CollisionReportResult>();
/// <summary>
/// 缓存操作锁对象
/// </summary>
private static readonly object _cacheLock = new object();
#endregion
private readonly CollisionReportParameters _parameters;
private string _specificTestName = null; // 指定的测试名称(用于历史报告)
@ -152,31 +138,6 @@ namespace NavisworksTransport.Commands
return PathPlanningResult.Failure("无法确定测试名称,请先运行碰撞检测或选择历史记录");
}
// 检查缓存
lock (_cacheLock)
{
if (_reportCache.ContainsKey(targetTestName))
{
var cachedResult = _reportCache[targetTestName];
LogManager.Info($"使用缓存的碰撞报告: {targetTestName}");
UpdateProgress(100, "使用缓存报告");
// 显示缓存的报告
ShowReport(cachedResult);
var cachedMessage = cachedResult.TotalCollisions > 0 ?
$"碰撞报告显示完成(缓存):发现 {cachedResult.TotalCollisions} 个碰撞" :
"碰撞报告显示完成(缓存):未发现碰撞";
return PathPlanningResult<CollisionReportResult>.Success(cachedResult, cachedMessage);
}
else
{
LogManager.Debug($"缓存中未找到测试: {targetTestName}");
}
}
var result = new CollisionReportResult();
try
@ -266,13 +227,6 @@ namespace NavisworksTransport.Commands
// 显示报告UI线程
ShowReport(result);
// 将报告结果缓存起来
lock (_cacheLock)
{
_reportCache[targetTestName] = result;
LogManager.Info($"碰撞报告已缓存: {targetTestName}, 缓存总数: {_reportCache.Count}");
}
}
catch (OperationCanceledException)
{
@ -293,56 +247,7 @@ namespace NavisworksTransport.Commands
return PathPlanningResult<CollisionReportResult>.Success(result, message);
}
#region
/// <summary>
/// 从缓存获取报告
/// </summary>
public static CollisionReportResult GetReportFromCache(string testName)
{
if (string.IsNullOrEmpty(testName))
return null;
lock (_cacheLock)
{
if (_reportCache.ContainsKey(testName))
{
LogManager.Info($"从缓存获取报告: {testName}");
return _reportCache[testName];
}
}
return null;
}
/// <summary>
/// 缓存报告
/// </summary>
public static void CacheReport(string testName, CollisionReportResult reportResult)
{
if (string.IsNullOrEmpty(testName) || reportResult == null)
return;
lock (_cacheLock)
{
_reportCache[testName] = reportResult;
LogManager.Info($"报告已缓存: {testName}, 缓存总数: {_reportCache.Count}");
}
}
/// <summary>
/// 清理过期缓存(可选功能)
/// </summary>
public static void ClearReportCache()
{
lock (_cacheLock)
{
var count = _reportCache.Count;
_reportCache.Clear();
LogManager.Info($"已清理碰撞报告缓存,共清理 {count} 个缓存项");
}
}
#endregion
/// <summary>
/// 收集所有碰撞数据及统计信息
@ -379,7 +284,14 @@ namespace NavisworksTransport.Commands
if (testCollisionsRaw == null || testCollisionsRaw.Count == 0)
{
throw new InvalidOperationException($"未找到测试 '{targetTestName}' 的ClashDetective碰撞结果");
LogManager.Info($"测试 '{targetTestName}' 没有碰撞结果,返回空数据");
result.AllCollisions = allCollisions;
result.ClashDetectiveCollisionCount = 0;
result.AnimationCollisions = 0;
result.UniqueCollidedObjects = new HashSet<string>();
result.BoundingBoxTestCount = 0;
result.MovingObjectInfo = "无碰撞";
return result;
}
LogManager.Info($"从缓存获取ClashDetective结果: {testCollisionsRaw.Count}个碰撞,测试名称:{targetTestName}");

View File

@ -2398,6 +2398,11 @@ namespace NavisworksTransport.Core.Animation
/// </summary>
public int AnimationFrameRate => _animationFrameRate;
/// <summary>
/// 获取所有碰撞结果(不去重)
/// </summary>
public List<CollisionResult> AllCollisionResults => _allCollisionResults;
/// <summary>
/// 获取当前碰撞检测精度
/// </summary>

View File

@ -905,15 +905,15 @@ namespace NavisworksTransport
LogManager.Info($"=== 碰撞统计最终结果 ===");
LogManager.Info($"动画过程包围盒检测: {_animationCollisionCount}个碰撞 (参考值)");
LogManager.Info($"Clash Detective权威结果: {_clashDetectiveCollisionCount}个碰撞 (权威数据)");
// 触发碰撞检测完成事件,通知生成报告
// 使用ClashDetective权威结果而不是预计算结果
// 如果权威结果为0个碰撞传入空列表以触发祝贺对话框
var finalCollisions = _clashDetectiveCollisionCount > 0 ? validCollisions : new List<CollisionResult>();
LogManager.Info($"触发CollisionDetected事件通知生成报告{_clashDetectiveCollisionCount}个碰撞,权威数据)");
var eventArgs = new CollisionDetectedEventArgs(finalCollisions);
OnCollisionDetected(eventArgs);
}
// 🔥 无论是否有主测试,都触发碰撞检测完成事件,通知生成报告
// 使用ClashDetective权威结果而不是预计算结果
// 如果权威结果为0个碰撞传入空列表以触发祝贺对话框
var finalCollisions = _clashDetectiveCollisionCount > 0 ? validCollisions : new List<CollisionResult>();
LogManager.Info($"触发CollisionDetected事件通知生成报告{_clashDetectiveCollisionCount}个碰撞,权威数据)");
var eventArgs = new CollisionDetectedEventArgs(finalCollisions);
OnCollisionDetected(eventArgs);
}
catch (Exception ex)
{
@ -1013,7 +1013,7 @@ namespace NavisworksTransport
/// 获取当前路径的Clash结果
/// </summary>
/// <param name="pathName">路径名称</param>
/// <returns>当前路径的碰撞结果列表</returns>
/// <returns>当前路径的碰撞结果列表(如果没有结果返回空列表)</returns>
public List<CollisionResult> GetCurrentPathClashResults(string testName)
{
lock (_clashResultsCacheLock)
@ -1036,9 +1036,11 @@ namespace NavisworksTransport
LogManager.Info($"[ClashDetective结果] 已从数据库加载 '{testName}' 的结果并缓存:{loadedResults.Count}个碰撞");
return loadedResults;
}
// 没有找到结果,返回空列表
LogManager.Info($"[ClashDetective结果] 未找到测试 '{testName}' 的碰撞结果,返回空列表");
return new List<CollisionResult>();
}
throw new InvalidOperationException($"未找到测试 '{testName}' 的ClashDetective结果缓存和数据库中都没有");
}
/// <summary>
@ -1050,6 +1052,47 @@ namespace NavisworksTransport
return GetCurrentPathClashResults(_currentTestName);
}
/// <summary>
/// 清理当前测试的缓存
/// </summary>
public void ClearCurrentTestCache()
{
if (string.IsNullOrEmpty(_currentTestName))
{
return;
}
lock (_clashResultsCacheLock)
{
if (_clashDetectiveResultsCache.ContainsKey(_currentTestName))
{
_clashDetectiveResultsCache.Remove(_currentTestName);
LogManager.Info($"[ClashDetective缓存] 已清理当前测试 '{_currentTestName}' 的缓存");
}
}
}
/// <summary>
/// 清空当前测试名称
/// </summary>
public void ClearCurrentTestName()
{
if (!string.IsNullOrEmpty(_currentTestName))
{
LogManager.Info($"[ClashDetective] 清空当前测试名称: {_currentTestName}");
_currentTestName = null;
}
}
/// <summary>
/// 设置当前测试名称
/// </summary>
public void SetCurrentTestName(string testName)
{
_currentTestName = testName;
LogManager.Info($"[ClashDetective] 设置当前测试名称: {_currentTestName}");
}
/// <summary>
/// 从测试中提取碰撞结果
/// </summary>

View File

@ -2094,8 +2094,7 @@ namespace NavisworksTransport
return new RenderStyle(Color.FromByteRGB(255, 152, 0), 0.8); // Material Orange连线20%透明
case RenderStyleName.VehicleSpace:
return new RenderStyle(Color.FromByteRGB(158, 158, 158), 0.4); // Material Grey车辆空间60%透明
return new RenderStyle(Color.FromByteRGB(129, 199, 132), 0.4); // Material Light Green通行空间60%透明
case RenderStyleName.PreviewPoint:
return new RenderStyle(Color.White, 0.7); // 白色预览点30%透明

View File

@ -1520,8 +1520,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
UpdateMediaControlProperties(); // 更新媒体控制属性
// 先清除所有碰撞高亮包括预计算和ClashDetective
ModelHighlightHelper.ClearCollisionHighlights();
// 检查并高亮ClashDetective结果只在动画自然完成时进行
CheckAndHighlightClashDetectiveResults();
// 生成碰撞报告(无论有无碰撞)
GenerateAndSaveCollisionReport();
// 高亮ClashDetective结果只在动画自然完成时进行
HighlightClashDetectiveResults();
break;
case NavisworksTransport.Core.Animation.AnimationState.Stopped:
CanStartAnimation = true;
@ -1542,9 +1544,73 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
/// <summary>
/// 检查并高亮ClashDetective结果
/// 生成并保存碰撞报告(无论有无碰撞都生成)
/// </summary>
private void CheckAndHighlightClashDetectiveResults()
private async void GenerateAndSaveCollisionReport()
{
try
{
var animationManager = Core.Animation.PathAnimationManager.GetInstance();
var hasAnimationCollisions = animationManager?.AllCollisionResults?.Count > 0;
// 如果当前动画没有碰撞数据但CurrentTestName存在说明是旧数据
// 需要清空CurrentTestName避免使用上一次的测试数据
if (!hasAnimationCollisions && !string.IsNullOrEmpty(_clashIntegration?.CurrentTestName))
{
LogManager.Info("当前动画无碰撞数据清空ClashDetectiveIntegration的CurrentTestName");
_clashIntegration.ClearCurrentTestName();
}
// 如果没有测试名称,创建一个临时的测试名称(用于无碰撞情况)
if (string.IsNullOrEmpty(_clashIntegration?.CurrentTestName))
{
var tempTestName = $"无碰撞_{DateTime.Now:yyyyMMdd_HHmmss}";
LogManager.Info($"创建临时测试名称用于无碰撞报告: {tempTestName}");
_clashIntegration.SetCurrentTestName(tempTestName);
}
// 统一使用GenerateCollisionReportCommand生成报告无论有无碰撞
UpdateMainStatus($"正在生成碰撞报告...", -1, true);
var generateReportCommand = NavisworksTransport.Commands.GenerateCollisionReportCommand.CreateComprehensive();
var result = await generateReportCommand.ExecuteAsync();
if (result.IsSuccess && result is PathPlanningResult<CollisionReportResult> reportResult)
{
// 缓存报告结果,供后续查看使用
_lastGeneratedReport = reportResult.Data;
// 保存到数据库
await SaveCollisionReportToDatabase(reportResult.Data);
var collisionCount = reportResult.Data.TotalCollisions;
if (collisionCount > 0)
{
UpdateMainStatus($"✅ 碰撞报告已生成并保存:{collisionCount} 个碰撞");
LogManager.Info("碰撞报告已自动生成并保存到数据库");
}
else
{
UpdateMainStatus($"✅ 碰撞报告已生成并保存0 个碰撞");
LogManager.Info("碰撞报告已自动生成并保存到数据库(无碰撞)");
}
}
else
{
UpdateMainStatus($"碰撞报告生成失败: {result.ErrorMessage}");
LogManager.Error($"自动生成碰撞报告失败: {result.ErrorMessage}");
}
}
catch (Exception ex)
{
LogManager.Error($"生成碰撞报告失败: {ex.Message}");
}
}
/// <summary>
/// 高亮ClashDetective结果
/// </summary>
private void HighlightClashDetectiveResults()
{
try
{
@ -1576,58 +1642,26 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
catch (Exception ex)
{
LogManager.Error($"检查并高亮ClashDetective结果失败: {ex.Message}");
LogManager.Error($"高亮ClashDetective结果失败: {ex.Message}");
}
}
/// <summary>
/// 处理ClashDetective的碰撞检测事件 - 自动生成报告并保存数据库
/// 处理ClashDetective的碰撞检测事件 - 已废弃报告生成统一在CheckAndHighlightClashDetectiveResults中处理
/// </summary>
private async void OnCollisionDetected(object sender, CollisionDetectedEventArgs e)
private void OnCollisionDetected(object sender, CollisionDetectedEventArgs e)
{
// 报告生成已统一在CheckAndHighlightClashDetectiveResults中处理
// 此事件保留用于日志记录和未来扩展
try
{
// 获取ClashDetective结果
var clashResults = _clashIntegration?.GetCurrentTestResults();
var collisionCount = clashResults?.Count ?? 0;
if (collisionCount > 0)
{
UpdateMainStatus($"发现 {collisionCount} 个碰撞点,正在生成报告...", -1, true);
LogManager.Info($"碰撞检测完成,发现 {collisionCount} 个碰撞,开始自动生成报告");
// 自动生成碰撞报告
var generateReportCommand = NavisworksTransport.Commands.GenerateCollisionReportCommand.CreateComprehensive();
var result = await generateReportCommand.ExecuteAsync();
if (result.IsSuccess && result is PathPlanningResult<CollisionReportResult> reportResult)
{
// 缓存报告结果,供后续查看使用
_lastGeneratedReport = reportResult.Data;
// 保存到数据库
await SaveCollisionReportToDatabase(reportResult.Data);
UpdateMainStatus($"✅ 碰撞报告已生成并保存:{collisionCount} 个碰撞");
LogManager.Info("碰撞报告已自动生成并保存到数据库");
// 高亮ClashDetective结果
ModelHighlightHelper.HighlightClashDetectiveResults(_clashIntegration.CurrentTestName, _clashIntegration.GetCurrentPathClashResults);
HasClashDetectiveResults = true;
LogManager.Info("已自动高亮ClashDetective检测结果");
}
else
{
UpdateMainStatus($"发现 {collisionCount} 个碰撞点(报告生成失败)");
LogManager.Error($"自动生成碰撞报告失败: {result.ErrorMessage}");
}
}
// 无碰撞的情况由OnAnimationCollisionDetected方法处理这里不做任何操作
LogManager.Info($"[OnCollisionDetected] 碰撞检测事件触发,碰撞数量: {collisionCount}");
}
catch (Exception ex)
{
LogManager.Error($"处理碰撞检测事件失败: {ex.Message}", ex);
UpdateMainStatus("处理碰撞检测事件失败");
}
}