678 lines
26 KiB
C#
678 lines
26 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using Autodesk.Navisworks.Api;
|
||
using Autodesk.Navisworks.Api.Clash;
|
||
using NavisworksTransport.Utils;
|
||
using NavisworksTransport.UI.WPF.Views;
|
||
|
||
namespace NavisworksTransport.Commands
|
||
{
|
||
/// <summary>
|
||
/// 碰撞报告参数类
|
||
/// </summary>
|
||
public class CollisionReportParameters
|
||
{
|
||
/// <summary>
|
||
/// 报告类型
|
||
/// </summary>
|
||
public enum ReportType
|
||
{
|
||
/// <summary>动画碰撞报告</summary>
|
||
Animation,
|
||
/// <summary>独立碰撞检测报告</summary>
|
||
Independent,
|
||
/// <summary>综合报告(包含所有类型)</summary>
|
||
Comprehensive
|
||
}
|
||
|
||
/// <summary>
|
||
/// 要生成的报告类型
|
||
/// </summary>
|
||
public ReportType Type { get; set; } = ReportType.Comprehensive;
|
||
|
||
/// <summary>
|
||
/// 是否包含详细信息
|
||
/// </summary>
|
||
public bool IncludeDetails { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 是否自动高亮报告中的碰撞对象
|
||
/// </summary>
|
||
public bool AutoHighlight { get; set; } = false;
|
||
|
||
public PathPlanningResult ValidateParameters()
|
||
{
|
||
return PathPlanningResult.Success("参数验证通过");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 碰撞数据收集结果
|
||
/// </summary>
|
||
public class CollisionDataResult
|
||
{
|
||
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;
|
||
|
||
// 新增:被撞物体去重统计
|
||
public HashSet<string> UniqueCollidedObjects { get; set; } = new HashSet<string>();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 碰撞报告结果类
|
||
/// </summary>
|
||
public class CollisionReportResult
|
||
{
|
||
public string ReportContent { get; set; }
|
||
public int TotalCollisions { get; set; }
|
||
public int AnimationCollisions { get; set; } // 检测点数量
|
||
public List<CollisionResult> AllCollisions { get; set; } = new List<CollisionResult>();
|
||
public long GenerationTimeMs { get; set; }
|
||
public string MovingObjectInfo { get; set; } = string.Empty;
|
||
|
||
// 新增:被撞物体清单
|
||
public List<string> CollidedObjectsList { get; set; } = new List<string>();
|
||
public int UniqueCollidedObjectsCount { get; set; }
|
||
|
||
// 新增:动画参数
|
||
public string PathName { get; set; }
|
||
public int FrameRate { get; set; }
|
||
public double Duration { get; set; }
|
||
public double DetectionGap { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成碰撞报告Command
|
||
/// </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; // 指定的测试名称(用于历史报告)
|
||
|
||
public GenerateCollisionReportCommand(CollisionReportParameters parameters = null)
|
||
: base("GenerateCollisionReport", "生成碰撞报告", "生成并显示详细的碰撞检测报告")
|
||
{
|
||
_parameters = parameters ?? new CollisionReportParameters();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置要生成报告的测试名称
|
||
/// </summary>
|
||
public void SetTestName(string testName)
|
||
{
|
||
_specificTestName = testName;
|
||
}
|
||
|
||
protected override PathPlanningResult ValidateParameters()
|
||
{
|
||
return _parameters.ValidateParameters();
|
||
}
|
||
|
||
protected override async Task<PathPlanningResult> ExecuteInternalAsync(CancellationToken cancellationToken)
|
||
{
|
||
var startTime = DateTime.UtcNow;
|
||
|
||
UpdateProgress(10, "开始生成碰撞报告...");
|
||
|
||
// 获取ClashDetectiveIntegration实例
|
||
var clashIntegration = ClashDetectiveIntegration.Instance;
|
||
|
||
// 使用指定的测试名称(如果有),否则使用当前测试名称
|
||
var targetTestName = _specificTestName ?? clashIntegration?.CurrentTestName;
|
||
|
||
if (string.IsNullOrEmpty(targetTestName))
|
||
{
|
||
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
|
||
{
|
||
UpdateProgress(30, "收集碰撞数据...");
|
||
|
||
// 收集所有碰撞数据及统计信息(同步执行,避免 COM 线程问题)
|
||
var collisionData = CollectAllCollisionData();
|
||
result.AllCollisions = collisionData.AllCollisions;
|
||
|
||
// 修改统计数据
|
||
result.AnimationCollisions = collisionData.AnimationCollisions;
|
||
result.TotalCollisions = collisionData.ClashDetectiveCollisionCount;
|
||
result.MovingObjectInfo = collisionData.MovingObjectInfo;
|
||
|
||
// 新增:被撞物体清单
|
||
result.CollidedObjectsList = collisionData.UniqueCollidedObjects.OrderBy(x => x).ToList();
|
||
result.UniqueCollidedObjectsCount = collisionData.UniqueCollidedObjects.Count;
|
||
|
||
// 新增:从动画管理器获取动画参数
|
||
var animationManager = Core.Animation.PathAnimationManager.GetInstance();
|
||
if (animationManager != null)
|
||
{
|
||
result.FrameRate = animationManager.AnimationFrameRate;
|
||
result.Duration = animationManager.AnimationDuration;
|
||
result.DetectionGap = animationManager.DetectionGap;
|
||
// PathName需要从动画管理器获取
|
||
result.PathName = animationManager.PathName ?? "未知路径";
|
||
}
|
||
|
||
LogManager.Info($"碰撞报告计数 - 检查点: {result.AnimationCollisions}, Clash Detective: {result.TotalCollisions}");
|
||
|
||
UpdateProgress(70, "生成报告内容...");
|
||
|
||
// 生成报告内容
|
||
result.ReportContent = GenerateReportContent(collisionData, _parameters.Type, _parameters.IncludeDetails);
|
||
|
||
UpdateProgress(90, "处理报告显示...");
|
||
|
||
// 自动高亮(如果启用)
|
||
if (_parameters.AutoHighlight && collisionData.AllCollisions.Count > 0)
|
||
{
|
||
try
|
||
{
|
||
var highlightIntegration = ClashDetectiveIntegration.Instance;
|
||
if (highlightIntegration != null)
|
||
{
|
||
ModelHighlightHelper.HighlightCollisionResults(collisionData.AllCollisions, clearPrevious: true);
|
||
LogManager.Info($"自动高亮显示报告中的 {collisionData.AllCollisions.Count} 个碰撞对象");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"自动高亮报告对象失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
UpdateProgress(100, "报告生成完成");
|
||
|
||
// 显示报告(UI线程)
|
||
ShowReport(result);
|
||
|
||
// 将报告结果缓存起来
|
||
lock (_cacheLock)
|
||
{
|
||
_reportCache[targetTestName] = result;
|
||
LogManager.Info($"碰撞报告已缓存: {targetTestName}, 缓存总数: {_reportCache.Count}");
|
||
}
|
||
}
|
||
catch (OperationCanceledException)
|
||
{
|
||
return PathPlanningResult.Failure("报告生成被取消");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"生成碰撞报告失败: {ex.Message}");
|
||
return PathPlanningResult.Failure($"报告生成失败: {ex.Message}");
|
||
}
|
||
|
||
result.GenerationTimeMs = (long)(DateTime.UtcNow - startTime).TotalMilliseconds;
|
||
|
||
var message = result.TotalCollisions > 0 ?
|
||
$"碰撞报告生成完成:发现 {result.TotalCollisions} 个碰撞" :
|
||
"碰撞报告生成完成:未发现碰撞";
|
||
|
||
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>
|
||
/// 收集所有碰撞数据及统计信息
|
||
/// </summary>
|
||
private CollisionDataResult CollectAllCollisionData()
|
||
{
|
||
var result = new CollisionDataResult();
|
||
var allCollisions = new List<CollisionResult>();
|
||
|
||
try
|
||
{
|
||
LogManager.Info("开始收集所有碰撞数据及统计信息...");
|
||
|
||
var clashIntegration = ClashDetectiveIntegration.Instance;
|
||
if (clashIntegration == null)
|
||
{
|
||
throw new InvalidOperationException("无法获取ClashDetectiveIntegration实例");
|
||
}
|
||
|
||
// 从动画管理器获取当前路径名称
|
||
var animationManager = Core.Animation.PathAnimationManager.GetInstance();
|
||
var currentPathName = animationManager?.PathName;
|
||
|
||
// 使用指定的测试名称(如果有),否则使用当前测试名称
|
||
var targetTestName = _specificTestName ?? clashIntegration?.CurrentTestName;
|
||
|
||
if (string.IsNullOrEmpty(targetTestName))
|
||
{
|
||
throw new InvalidOperationException("无法确定测试名称,请先运行碰撞检测或选择历史记录");
|
||
}
|
||
|
||
// 获取碰撞结果(先检查缓存,没有则从数据库加载)
|
||
var testCollisionsRaw = clashIntegration.GetCurrentPathClashResults(targetTestName);
|
||
|
||
if (testCollisionsRaw == null || testCollisionsRaw.Count == 0)
|
||
{
|
||
throw new InvalidOperationException($"未找到测试 '{targetTestName}' 的ClashDetective碰撞结果");
|
||
}
|
||
|
||
LogManager.Info($"从缓存获取ClashDetective结果: {testCollisionsRaw.Count}个碰撞,测试名称:{targetTestName}");
|
||
|
||
// 直接使用缓存中的CollisionResult对象(已经过复合对象处理和去重)
|
||
allCollisions.AddRange(testCollisionsRaw);
|
||
|
||
// 统计碰撞总数
|
||
result.ClashDetectiveCollisionCount = testCollisionsRaw.Count;
|
||
LogManager.Debug($"测试 '{targetTestName}' 包含 {testCollisionsRaw.Count} 个碰撞");
|
||
|
||
// 统计被撞物体(缓存中已经是复合对象,不需要再去重)
|
||
var nameCountDict = new Dictionary<string, int>();
|
||
var uniqueCollidedObjectsList = new List<string>();
|
||
|
||
foreach (var collision in testCollisionsRaw)
|
||
{
|
||
if (collision.Item2 != null)
|
||
{
|
||
// Item2已经是容器对象(在创建CollisionResult时已用FindNamedParentContainer处理)
|
||
var item2Name = ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2) ?? "未知对象";
|
||
|
||
// 为相同名称的对象添加编号区分
|
||
if (nameCountDict.ContainsKey(item2Name))
|
||
{
|
||
nameCountDict[item2Name]++;
|
||
uniqueCollidedObjectsList.Add($"{item2Name} #{nameCountDict[item2Name]}");
|
||
}
|
||
else
|
||
{
|
||
nameCountDict[item2Name] = 1;
|
||
uniqueCollidedObjectsList.Add(item2Name);
|
||
}
|
||
}
|
||
}
|
||
|
||
result.AllCollisions = allCollisions;
|
||
result.UniqueCollidedObjects = new HashSet<string>(uniqueCollidedObjectsList);
|
||
result.BoundingBoxTestCount = 0;
|
||
|
||
// 设置动画碰撞数量
|
||
result.AnimationCollisions = clashIntegration?.AnimationCollisionCount ?? 0;
|
||
|
||
// 从碰撞结果的Item1中获取运动构件信息
|
||
if (allCollisions.Count > 0 && allCollisions[0].Item1 != null)
|
||
{
|
||
// Item1已经是容器对象(在创建CollisionResult时已用FindNamedParentContainer处理)
|
||
var movingItemName = ModelItemAnalysisHelper.GetSafeDisplayName(allCollisions[0].Item1) ?? "未知运动构件";
|
||
result.MovingObjectInfo = $"运动构件: {movingItemName}";
|
||
}
|
||
else
|
||
{
|
||
result.MovingObjectInfo = "运动构件: 未知";
|
||
}
|
||
|
||
LogManager.Info($"收集完成 - Clash Detective权威结果: {result.ClashDetectiveCollisionCount}个, 碰撞对象: {allCollisions.Count}个, 被撞构件: {uniqueCollidedObjectsList.Count}个");
|
||
|
||
return result;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"收集碰撞数据失败: {ex.Message}");
|
||
result.AllCollisions = allCollisions;
|
||
return result;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成报告内容
|
||
/// </summary>
|
||
private string GenerateReportContent(CollisionDataResult collisionData,
|
||
CollisionReportParameters.ReportType reportType, bool includeDetails)
|
||
{
|
||
var report = new StringBuilder();
|
||
var now = DateTime.Now;
|
||
var collisions = collisionData.AllCollisions;
|
||
|
||
// 报告头部
|
||
report.AppendLine("========================================");
|
||
report.AppendLine(" NavisworksTransport 碰撞检测报告");
|
||
report.AppendLine("========================================");
|
||
report.AppendLine($"生成时间: {now:yyyy年MM月dd日 HH:mm:ss}");
|
||
report.AppendLine($"报告类型: {GetReportTypeName(reportType)}");
|
||
|
||
// 运动构件信息(原运动物体信息)
|
||
if (!string.IsNullOrEmpty(collisionData.MovingObjectInfo))
|
||
{
|
||
var movingInfo = collisionData.MovingObjectInfo.Replace("运动对象", "运动构件");
|
||
report.AppendLine($"{movingInfo}");
|
||
}
|
||
report.AppendLine();
|
||
|
||
// 总体统计
|
||
report.AppendLine("=== 总体统计 ===");
|
||
var clashIntegration = ClashDetectiveIntegration.Instance;
|
||
var animationCollisionCount = clashIntegration?.AnimationCollisionCount ?? 0;
|
||
|
||
report.AppendLine($"总碰撞数: {collisionData.ClashDetectiveCollisionCount}个");
|
||
report.AppendLine($"碰撞构件: {collisionData.UniqueCollidedObjects.Count}个");
|
||
report.AppendLine($"检测点: {animationCollisionCount}个");
|
||
report.AppendLine();
|
||
|
||
// 碰撞构件清单(新增)
|
||
if (collisionData.UniqueCollidedObjects?.Count > 0)
|
||
{
|
||
report.AppendLine("=== 碰撞构件清单 ===");
|
||
int index = 1;
|
||
foreach (var objName in collisionData.UniqueCollidedObjects.OrderBy(x => x).Take(20)) // 限制显示前20个
|
||
{
|
||
report.AppendLine($" {index}. {objName}");
|
||
index++;
|
||
}
|
||
if (collisionData.UniqueCollidedObjects.Count > 20)
|
||
{
|
||
report.AppendLine($" ... 还有 {collisionData.UniqueCollidedObjects.Count - 20} 个构件");
|
||
}
|
||
report.AppendLine();
|
||
}
|
||
|
||
// 详细信息
|
||
if (includeDetails && collisions.Count > 0)
|
||
{
|
||
report.AppendLine("=== 详细碰撞信息 ===");
|
||
|
||
report.AppendLine("--- 碰撞详情 ---");
|
||
foreach (var collision in collisions.Take(10)) // 限制显示数量
|
||
{
|
||
AppendCollisionDetail(report, collision);
|
||
}
|
||
if (collisions.Count > 10)
|
||
{
|
||
report.AppendLine($"... 还有 {collisions.Count - 10} 个碰撞未显示");
|
||
}
|
||
report.AppendLine();
|
||
}
|
||
|
||
// 建议和结论
|
||
report.AppendLine("=== 建议与结论 ===");
|
||
if (collisions.Count == 0)
|
||
{
|
||
report.AppendLine("✅ 未发现碰撞问题,路径规划良好。");
|
||
}
|
||
else
|
||
{
|
||
report.AppendLine($"⚠️ 发现 {collisions.Count} 个碰撞问题,建议采取以下措施:");
|
||
report.AppendLine(" 1. 调整路径规划,避开碰撞区域");
|
||
report.AppendLine(" 2. 检查车辆尺寸和安全边距设置");
|
||
report.AppendLine(" 3. 考虑增加临时障碍物标记");
|
||
report.AppendLine(" 4. 重新评估物流流程设计");
|
||
|
||
report.AppendLine(" 5. 建议进行更详细的碰撞检测分析");
|
||
}
|
||
|
||
report.AppendLine();
|
||
report.AppendLine("========================================");
|
||
report.AppendLine($"报告生成完成 - {now:HH:mm:ss}");
|
||
report.AppendLine("========================================");
|
||
|
||
return report.ToString();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加碰撞详细信息到报告中
|
||
/// </summary>
|
||
private void AppendCollisionDetail(StringBuilder report, CollisionResult collision)
|
||
{
|
||
var item1Name = collision.Item1?.DisplayName ?? "未知对象";
|
||
var item2Name = collision.Item2?.DisplayName ?? "未知对象";
|
||
|
||
// 转换距离单位为米
|
||
var distanceInMeters = ConvertDistanceToMeters(collision.Distance);
|
||
|
||
report.AppendLine($"• {item1Name} ↔ {item2Name}");
|
||
report.AppendLine($" 状态: {GetStatusName(collision.Status)}, 距离: {distanceInMeters:F3}m");
|
||
|
||
// 转换位置坐标单位为米
|
||
var centerInMeters = ConvertPointToMeters(collision.Center);
|
||
report.AppendLine($" 位置: ({centerInMeters.X:F2}, {centerInMeters.Y:F2}, {centerInMeters.Z:F2})m");
|
||
report.AppendLine($" GUID: {collision.ClashGuid}");
|
||
report.AppendLine();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取报告类型名称
|
||
/// </summary>
|
||
private string GetReportTypeName(CollisionReportParameters.ReportType reportType)
|
||
{
|
||
switch (reportType)
|
||
{
|
||
case CollisionReportParameters.ReportType.Animation:
|
||
return "动画碰撞报告";
|
||
case CollisionReportParameters.ReportType.Independent:
|
||
return "独立检测报告";
|
||
case CollisionReportParameters.ReportType.Comprehensive:
|
||
return "综合碰撞报告";
|
||
default:
|
||
return "未知类型";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取碰撞状态名称
|
||
/// </summary>
|
||
private string GetStatusName(ClashResultStatus status)
|
||
{
|
||
switch (status)
|
||
{
|
||
case ClashResultStatus.New:
|
||
return "新发现";
|
||
case ClashResultStatus.Active:
|
||
return "活跃";
|
||
case ClashResultStatus.Reviewed:
|
||
return "已审阅";
|
||
case ClashResultStatus.Approved:
|
||
return "已批准";
|
||
case ClashResultStatus.Resolved:
|
||
return "已解决";
|
||
default:
|
||
return "未知";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 显示报告
|
||
/// </summary>
|
||
private void ShowReport(CollisionReportResult reportResult)
|
||
{
|
||
try
|
||
{
|
||
// 确保在UI线程中执行
|
||
if (System.Windows.Application.Current != null)
|
||
{
|
||
if (System.Windows.Application.Current.Dispatcher.CheckAccess())
|
||
{
|
||
// 已在UI线程上
|
||
ShowReportInternal(reportResult);
|
||
}
|
||
else
|
||
{
|
||
// 切换到UI线程
|
||
System.Windows.Application.Current.Dispatcher.Invoke(() => ShowReportInternal(reportResult));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 如果WPF Application不存在,回退到原来的方式
|
||
ShowReportInternal(reportResult);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"显示报告失败: {ex.Message}");
|
||
System.Windows.MessageBox.Show($"显示报告失败: {ex.Message}", "错误",
|
||
System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 内部报告显示方法
|
||
/// </summary>
|
||
private void ShowReportInternal(CollisionReportResult reportResult)
|
||
{
|
||
try
|
||
{
|
||
// 使用新的WPF碰撞报告对话框
|
||
var reportDialog = CollisionReportDialog.ShowReport(reportResult);
|
||
|
||
if (reportDialog != null)
|
||
{
|
||
LogManager.Info("WPF碰撞报告对话框显示成功");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Error($"显示WPF报告对话框失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建综合报告命令
|
||
/// </summary>
|
||
public static GenerateCollisionReportCommand CreateComprehensive(bool autoHighlight = false)
|
||
{
|
||
return new GenerateCollisionReportCommand(new CollisionReportParameters
|
||
{
|
||
Type = CollisionReportParameters.ReportType.Comprehensive,
|
||
IncludeDetails = true,
|
||
AutoHighlight = autoHighlight
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将距离转换为米
|
||
/// </summary>
|
||
private double ConvertDistanceToMeters(double distance)
|
||
{
|
||
try
|
||
{
|
||
var conversionFactor = UnitsConverter.GetUnitsToMetersConversionFactor();
|
||
return distance * conversionFactor;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Warning($"距离单位转换失败: {ex.Message},使用原始值");
|
||
return distance;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将3D点坐标转换为米
|
||
/// </summary>
|
||
private Point3D ConvertPointToMeters(Point3D point)
|
||
{
|
||
try
|
||
{
|
||
var conversionFactor = UnitsConverter.GetUnitsToMetersConversionFactor();
|
||
return new Point3D(
|
||
point.X * conversionFactor,
|
||
point.Y * conversionFactor,
|
||
point.Z * conversionFactor
|
||
);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogManager.Warning($"坐标单位转换失败: {ex.Message},使用原始值");
|
||
return point;
|
||
}
|
||
}
|
||
}
|
||
} |