完善了碰撞报告
This commit is contained in:
parent
3df7124cf8
commit
6893b7efeb
@ -12,6 +12,7 @@ using NavisworksTransport.Core;
|
||||
using NavisworksTransport.PathPlanning;
|
||||
using NavisworksTransport.Utils;
|
||||
using NavisworksTransport.UI.WPF.Views;
|
||||
using NavisworksTransport.Core.Animation;
|
||||
|
||||
namespace NavisworksTransport.Commands
|
||||
{
|
||||
@ -54,6 +55,17 @@ namespace NavisworksTransport.Commands
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 string MovingObjectInfo { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 碰撞报告结果类
|
||||
/// </summary>
|
||||
@ -65,6 +77,7 @@ namespace NavisworksTransport.Commands
|
||||
public int IndependentCollisions { get; set; }
|
||||
public List<CollisionResult> AllCollisions { get; set; } = new List<CollisionResult>();
|
||||
public long GenerationTimeMs { get; set; }
|
||||
public string MovingObjectInfo { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -99,33 +112,36 @@ namespace NavisworksTransport.Commands
|
||||
{
|
||||
UpdateProgress(30, "收集碰撞数据...");
|
||||
|
||||
// 收集所有碰撞数据
|
||||
var allCollisions = CollectAllCollisionData();
|
||||
result.AllCollisions = allCollisions;
|
||||
// 收集所有碰撞数据及统计信息
|
||||
var collisionData = CollectAllCollisionData();
|
||||
result.AllCollisions = collisionData.AllCollisions;
|
||||
|
||||
// 分类统计
|
||||
result.AnimationCollisions = allCollisions.Count(c => c.DisplayName.Contains("动画") || c.DisplayName.Contains("精确碰撞"));
|
||||
result.IndependentCollisions = allCollisions.Count(c => c.DisplayName.Contains("独立检测"));
|
||||
result.TotalCollisions = allCollisions.Count;
|
||||
// 直接使用收集到的统计数字,无需参数传递!
|
||||
result.AnimationCollisions = collisionData.BoundingBoxTestCount; // 包围盒测试数量
|
||||
result.IndependentCollisions = collisionData.ClashDetectiveCollisionCount; // Clash Detective结果数量
|
||||
result.TotalCollisions = collisionData.ClashDetectiveCollisionCount; // 总数以权威结果为准
|
||||
result.MovingObjectInfo = collisionData.MovingObjectInfo; // 运动物体信息
|
||||
|
||||
LogManager.Info($"碰撞报告计数 - 动画检测: {result.AnimationCollisions}, Clash Detective: {result.IndependentCollisions}, 总计: {result.TotalCollisions}");
|
||||
|
||||
UpdateProgress(60, "生成报告内容...");
|
||||
|
||||
// 生成报告内容
|
||||
result.ReportContent = GenerateReportContent(allCollisions, _parameters.Type, _parameters.IncludeDetails);
|
||||
result.ReportContent = GenerateReportContent(collisionData, _parameters.Type, _parameters.IncludeDetails);
|
||||
|
||||
UpdateProgress(90, "处理报告显示...");
|
||||
|
||||
// 自动高亮(如果启用)
|
||||
if (_parameters.AutoHighlight && allCollisions.Count > 0)
|
||||
if (_parameters.AutoHighlight && collisionData.AllCollisions.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var clashIntegration = ClashDetectiveIntegration.Instance;
|
||||
if (clashIntegration != null)
|
||||
var highlightIntegration = ClashDetectiveIntegration.Instance;
|
||||
if (highlightIntegration != null)
|
||||
{
|
||||
var highlightColor = Color.Green; // 绿色 (Navisworks API中没有Orange)
|
||||
clashIntegration.ManageHighlightsByCategory("report", allCollisions, highlightColor, true);
|
||||
LogManager.Info($"自动高亮显示报告中的 {allCollisions.Count} 个碰撞对象");
|
||||
highlightIntegration.ManageHighlightsByCategory("report", collisionData.AllCollisions, highlightColor, true);
|
||||
LogManager.Info($"自动高亮显示报告中的 {collisionData.AllCollisions.Count} 个碰撞对象");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -161,15 +177,19 @@ namespace NavisworksTransport.Commands
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 收集所有碰撞数据
|
||||
/// 收集所有碰撞数据及统计信息
|
||||
/// </summary>
|
||||
private List<CollisionResult> CollectAllCollisionData()
|
||||
private CollisionDataResult CollectAllCollisionData()
|
||||
{
|
||||
var result = new CollisionDataResult();
|
||||
var allCollisions = new List<CollisionResult>();
|
||||
|
||||
try
|
||||
{
|
||||
LogManager.Info("开始收集所有碰撞数据...");
|
||||
LogManager.Info("开始收集所有碰撞数据及统计信息...");
|
||||
|
||||
// 收集运动物体信息
|
||||
result.MovingObjectInfo = GetMovingObjectInfo();
|
||||
|
||||
var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
|
||||
var documentClash = doc.GetClash();
|
||||
@ -177,16 +197,28 @@ namespace NavisworksTransport.Commands
|
||||
if (documentClash == null)
|
||||
{
|
||||
LogManager.Warning("无法获取 Clash Detective 文档,无法收集碰撞数据");
|
||||
return allCollisions;
|
||||
return result;
|
||||
}
|
||||
|
||||
// 遍历所有测试
|
||||
int animationTestCount = 0; // 包围盒测试数量
|
||||
int totalCollisionCount = 0; // Clash Detective总碰撞数
|
||||
|
||||
// 遍历所有测试,区分动画测试和统计信息
|
||||
foreach (var test in documentClash.TestsData.Tests)
|
||||
{
|
||||
if (test is ClashTest clashTest)
|
||||
{
|
||||
var testCollisions = ExtractCollisionsFromTest(clashTest);
|
||||
allCollisions.AddRange(testCollisions);
|
||||
|
||||
// 统计信息:如果是动画相关测试,记录包围盒测试数量
|
||||
if (clashTest.DisplayName.Contains("动画路径碰撞"))
|
||||
{
|
||||
animationTestCount = documentClash.TestsData.Tests.Cast<ClashTest>()
|
||||
.Where(t => t.DisplayName.Contains("动画路径碰撞"))
|
||||
.Count();
|
||||
totalCollisionCount += clashTest.Children.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,14 +228,19 @@ namespace NavisworksTransport.Commands
|
||||
.Select(g => g.First())
|
||||
.ToList();
|
||||
|
||||
LogManager.Info($"收集到 {allCollisions.Count} 个碰撞记录,去重后 {uniqueCollisions.Count} 个");
|
||||
result.AllCollisions = uniqueCollisions;
|
||||
result.BoundingBoxTestCount = animationTestCount;
|
||||
result.ClashDetectiveCollisionCount = totalCollisionCount > 0 ? totalCollisionCount : uniqueCollisions.Count;
|
||||
|
||||
return uniqueCollisions;
|
||||
LogManager.Info($"收集完成 - 包围盒测试: {result.BoundingBoxTestCount}个, Clash Detective: {result.ClashDetectiveCollisionCount}个, 去重后碰撞: {uniqueCollisions.Count}个");
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"收集碰撞数据失败: {ex.Message}");
|
||||
return allCollisions;
|
||||
result.AllCollisions = allCollisions;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,11 +307,12 @@ namespace NavisworksTransport.Commands
|
||||
/// <summary>
|
||||
/// 生成报告内容
|
||||
/// </summary>
|
||||
private string GenerateReportContent(List<CollisionResult> collisions,
|
||||
private string GenerateReportContent(CollisionDataResult collisionData,
|
||||
CollisionReportParameters.ReportType reportType, bool includeDetails)
|
||||
{
|
||||
var report = new StringBuilder();
|
||||
var now = DateTime.Now;
|
||||
var collisions = collisionData.AllCollisions;
|
||||
|
||||
// 报告头部
|
||||
report.AppendLine("========================================");
|
||||
@ -282,19 +320,21 @@ namespace NavisworksTransport.Commands
|
||||
report.AppendLine("========================================");
|
||||
report.AppendLine($"生成时间: {now:yyyy年MM月dd日 HH:mm:ss}");
|
||||
report.AppendLine($"报告类型: {GetReportTypeName(reportType)}");
|
||||
|
||||
// 使用收集到的运动物体信息
|
||||
if (!string.IsNullOrEmpty(collisionData.MovingObjectInfo))
|
||||
{
|
||||
report.AppendLine($"{collisionData.MovingObjectInfo}");
|
||||
}
|
||||
report.AppendLine();
|
||||
|
||||
// 总体统计
|
||||
report.AppendLine("=== 总体统计 ===");
|
||||
report.AppendLine($"总碰撞数量: {collisions.Count}");
|
||||
|
||||
var animationCollisions = collisions.Where(c => c.DisplayName.Contains("动画") || c.DisplayName.Contains("精确碰撞")).ToList();
|
||||
var independentCollisions = collisions.Where(c => c.DisplayName.Contains("独立检测")).ToList();
|
||||
var otherCollisions = collisions.Except(animationCollisions).Except(independentCollisions).ToList();
|
||||
|
||||
report.AppendLine($"动画过程碰撞: {animationCollisions.Count}");
|
||||
report.AppendLine($"独立检测碰撞: {independentCollisions.Count}");
|
||||
report.AppendLine($"其他碰撞: {otherCollisions.Count}");
|
||||
// 使用收集到的统计数字
|
||||
report.AppendLine($"包围盒测试发现: {collisionData.BoundingBoxTestCount}个碰撞 (快速粗略检测结果)");
|
||||
report.AppendLine($"Clash Detective确认: {collisionData.ClashDetectiveCollisionCount}个碰撞 (精确权威检测结果)");
|
||||
report.AppendLine($"总碰撞数量: {collisionData.ClashDetectiveCollisionCount}个 (以权威结果为准)");
|
||||
report.AppendLine();
|
||||
|
||||
// 按状态分类
|
||||
@ -317,56 +357,16 @@ namespace NavisworksTransport.Commands
|
||||
{
|
||||
report.AppendLine("=== 详细碰撞信息 ===");
|
||||
|
||||
// 按类型分组显示
|
||||
if (reportType == CollisionReportParameters.ReportType.Comprehensive ||
|
||||
reportType == CollisionReportParameters.ReportType.Animation)
|
||||
report.AppendLine("--- 碰撞详情 ---");
|
||||
foreach (var collision in collisions.Take(10)) // 限制显示数量
|
||||
{
|
||||
if (animationCollisions.Count > 0)
|
||||
{
|
||||
report.AppendLine("--- 动画过程碰撞 ---");
|
||||
foreach (var collision in animationCollisions.Take(10)) // 限制显示数量
|
||||
{
|
||||
AppendCollisionDetail(report, collision);
|
||||
}
|
||||
if (animationCollisions.Count > 10)
|
||||
{
|
||||
report.AppendLine($"... 还有 {animationCollisions.Count - 10} 个动画碰撞未显示");
|
||||
}
|
||||
report.AppendLine();
|
||||
}
|
||||
AppendCollisionDetail(report, collision);
|
||||
}
|
||||
|
||||
if (reportType == CollisionReportParameters.ReportType.Comprehensive ||
|
||||
reportType == CollisionReportParameters.ReportType.Independent)
|
||||
if (collisions.Count > 10)
|
||||
{
|
||||
if (independentCollisions.Count > 0)
|
||||
{
|
||||
report.AppendLine("--- 独立检测碰撞 ---");
|
||||
foreach (var collision in independentCollisions.Take(10)) // 限制显示数量
|
||||
{
|
||||
AppendCollisionDetail(report, collision);
|
||||
}
|
||||
if (independentCollisions.Count > 10)
|
||||
{
|
||||
report.AppendLine($"... 还有 {independentCollisions.Count - 10} 个独立检测碰撞未显示");
|
||||
}
|
||||
report.AppendLine();
|
||||
}
|
||||
}
|
||||
|
||||
if (otherCollisions.Count > 0)
|
||||
{
|
||||
report.AppendLine("--- 其他碰撞 ---");
|
||||
foreach (var collision in otherCollisions.Take(5))
|
||||
{
|
||||
AppendCollisionDetail(report, collision);
|
||||
}
|
||||
if (otherCollisions.Count > 5)
|
||||
{
|
||||
report.AppendLine($"... 还有 {otherCollisions.Count - 5} 个其他碰撞未显示");
|
||||
}
|
||||
report.AppendLine();
|
||||
report.AppendLine($"... 还有 {collisions.Count - 10} 个碰撞未显示");
|
||||
}
|
||||
report.AppendLine();
|
||||
}
|
||||
|
||||
// 建议和结论
|
||||
@ -383,14 +383,7 @@ namespace NavisworksTransport.Commands
|
||||
report.AppendLine(" 3. 考虑增加临时障碍物标记");
|
||||
report.AppendLine(" 4. 重新评估物流流程设计");
|
||||
|
||||
if (animationCollisions.Count > independentCollisions.Count)
|
||||
{
|
||||
report.AppendLine(" 5. 动画过程碰撞较多,建议检查实时检测设置");
|
||||
}
|
||||
else if (independentCollisions.Count > animationCollisions.Count)
|
||||
{
|
||||
report.AppendLine(" 5. 独立检测发现更多碰撞,建议增强实时监控");
|
||||
}
|
||||
report.AppendLine(" 5. 建议进行更详细的碰撞检测分析");
|
||||
}
|
||||
|
||||
report.AppendLine();
|
||||
@ -409,9 +402,15 @@ namespace NavisworksTransport.Commands
|
||||
var item1Name = collision.Item1?.DisplayName ?? "未知对象";
|
||||
var item2Name = collision.Item2?.DisplayName ?? "未知对象";
|
||||
|
||||
// 转换距离单位为米
|
||||
var distanceInMeters = ConvertDistanceToMeters(collision.Distance);
|
||||
|
||||
report.AppendLine($"• {item1Name} ↔ {item2Name}");
|
||||
report.AppendLine($" 状态: {GetStatusName(collision.Status)}, 距离: {collision.Distance:F3}m");
|
||||
report.AppendLine($" 位置: ({collision.Center.X:F2}, {collision.Center.Y:F2}, {collision.Center.Z:F2})");
|
||||
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();
|
||||
}
|
||||
@ -593,5 +592,92 @@ namespace NavisworksTransport.Commands
|
||||
AutoHighlight = autoHighlight
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取运动物体信息
|
||||
/// </summary>
|
||||
private string GetMovingObjectInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
LogManager.Debug("[GetMovingObjectInfo] 开始获取运动物体信息");
|
||||
|
||||
// 尝试获取当前选中的模型项作为运动对象
|
||||
var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
|
||||
LogManager.Debug($"[GetMovingObjectInfo] 文档: {doc != null}, 选择: {doc?.CurrentSelection != null}");
|
||||
|
||||
if (doc?.CurrentSelection?.SelectedItems?.Count > 0)
|
||||
{
|
||||
var selectedItems = doc.CurrentSelection.SelectedItems;
|
||||
LogManager.Debug($"[GetMovingObjectInfo] 选中项数量: {selectedItems.Count}");
|
||||
|
||||
if (selectedItems.Count == 1)
|
||||
{
|
||||
var item = selectedItems.First();
|
||||
var displayName = item?.DisplayName ?? "未知对象";
|
||||
LogManager.Debug($"[GetMovingObjectInfo] 单个对象名称: '{displayName}'");
|
||||
return $"运动对象: {displayName}";
|
||||
}
|
||||
else
|
||||
{
|
||||
var displayNames = selectedItems.Take(3).Select(item => item?.DisplayName ?? "未知对象");
|
||||
var summary = string.Join(", ", displayNames);
|
||||
if (selectedItems.Count > 3)
|
||||
{
|
||||
summary += $" 等{selectedItems.Count}个对象";
|
||||
}
|
||||
LogManager.Debug($"[GetMovingObjectInfo] 多个对象摘要: '{summary}'");
|
||||
return $"运动对象: {summary}";
|
||||
}
|
||||
}
|
||||
|
||||
LogManager.Debug("[GetMovingObjectInfo] 未选择对象,返回默认信息");
|
||||
return "运动对象: 物流运输对象 (建议先选择要运动的模型元素)";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"获取运动物体信息失败: {ex.Message}");
|
||||
return "运动对象: 获取信息失败";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,6 +29,26 @@ namespace NavisworksTransport
|
||||
|
||||
// 几何对象列表缓存,用于避免重复获取对象列表
|
||||
private static List<ModelItem> _allGeometryItemsCache = null;
|
||||
|
||||
// 碰撞检测计数器
|
||||
private int _animationCollisionCount = 0; // 动画过程中简单包围盒检测的碰撞数量
|
||||
private int _clashDetectiveCollisionCount = 0; // Clash Detective最终检测的碰撞数量
|
||||
|
||||
/// <summary>
|
||||
/// 动画过程中检测到的碰撞数量(仅供参考统计)
|
||||
/// </summary>
|
||||
public int AnimationCollisionCount
|
||||
{
|
||||
get { return _animationCollisionCount; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clash Detective检测到的权威碰撞数量
|
||||
/// </summary>
|
||||
public int ClashDetectiveCollisionCount
|
||||
{
|
||||
get { return _clashDetectiveCollisionCount; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单例实例
|
||||
@ -839,6 +859,22 @@ namespace NavisworksTransport
|
||||
LogManager.Error($"动画结束后自动高亮失败: {highlightEx.Message}");
|
||||
}
|
||||
|
||||
// 更新Clash Detective碰撞计数器 - 统计实际创建的测试数量
|
||||
var finalClashDetectiveCount = 0;
|
||||
if (_documentClash != null)
|
||||
{
|
||||
// 计算所有动画相关测试的碰撞总数
|
||||
var animationTests = _documentClash.TestsData.Tests.Cast<ClashTest>()
|
||||
.Where(t => t.DisplayName.Contains("动画路径碰撞") || t.DisplayName.Contains("动画碰撞"))
|
||||
.ToList();
|
||||
|
||||
finalClashDetectiveCount = animationTests.Sum(t => t.Children.Count);
|
||||
LogManager.Info($"统计Clash Detective最终碰撞数量: {animationTests.Count}个测试,总共{finalClashDetectiveCount}个碰撞");
|
||||
}
|
||||
|
||||
_clashDetectiveCollisionCount = finalClashDetectiveCount;
|
||||
LogManager.Info($"Clash Detective碰撞计数器已更新: {_clashDetectiveCollisionCount}");
|
||||
|
||||
// 清空缓存
|
||||
_cachedResults.Clear();
|
||||
LogManager.Info("=== 动画碰撞测试(位置恢复方案)完成 ===");
|
||||
@ -2247,6 +2283,10 @@ namespace NavisworksTransport
|
||||
{
|
||||
LogManager.Info($"未发现碰撞");
|
||||
}
|
||||
|
||||
// 更新动画碰撞计数器
|
||||
_animationCollisionCount = results.Count;
|
||||
LogManager.Info($"动画碰撞计数器已更新: {_animationCollisionCount}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@ -95,11 +95,6 @@ namespace NavisworksTransport.PathPlanning
|
||||
|
||||
// 统计变量
|
||||
var totalItems = modelItems?.Count() ?? 0;
|
||||
var itemsWithGeometry = 0;
|
||||
var channelItemsExcluded = 0;
|
||||
var itemsWithoutBounds = 0;
|
||||
var itemsOutOfBounds = 0;
|
||||
var itemsAddedToHash = 0;
|
||||
|
||||
LogManager.Info($"【垂直扫描处理器】 输入统计 - 总模型项: {totalItems}, 将排除通道元素: {channelItemsSet.Count}");
|
||||
LogManager.Info($"【垂直扫描处理器】 扫描边界: [{bounds.Min.X:F1},{bounds.Min.Y:F1},{bounds.Min.Z:F1}] - [{bounds.Max.X:F1},{bounds.Max.Y:F1},{bounds.Max.Z:F1}]");
|
||||
|
||||
@ -8,6 +8,13 @@ namespace NavisworksTransport.UI.WPF.Converters
|
||||
/// <summary>
|
||||
/// 布尔值到可见性的转换器
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 通用值到可见性转换器
|
||||
/// - 布尔值:true/false → Visible/Collapsed
|
||||
/// - 字符串:非空非白字符 → Visible,空/null → Collapsed
|
||||
/// - 数字:非零 → Visible,零 → Collapsed
|
||||
/// - 对象:非null → Visible,null → Collapsed
|
||||
/// </summary>
|
||||
public class BoolToVisibilityConverter : IValueConverter
|
||||
{
|
||||
/// <summary>
|
||||
@ -17,21 +24,52 @@ namespace NavisworksTransport.UI.WPF.Converters
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isVisible = false;
|
||||
|
||||
// 处理布尔值
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
// 检查是否需要反向转换
|
||||
bool isInverse = parameter?.ToString()?.Equals("Inverse", StringComparison.OrdinalIgnoreCase) == true;
|
||||
|
||||
if (isInverse)
|
||||
{
|
||||
return boolValue ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
return boolValue ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
isVisible = boolValue;
|
||||
}
|
||||
// 处理字符串 - 非空非白字符字符串为true
|
||||
else if (value is string stringValue)
|
||||
{
|
||||
isVisible = !string.IsNullOrWhiteSpace(stringValue);
|
||||
}
|
||||
// 处理数字类型
|
||||
else if (value is int intValue)
|
||||
{
|
||||
isVisible = intValue != 0;
|
||||
}
|
||||
else if (value is long longValue)
|
||||
{
|
||||
isVisible = longValue != 0;
|
||||
}
|
||||
else if (value is double doubleValue)
|
||||
{
|
||||
isVisible = Math.Abs(doubleValue) > double.Epsilon;
|
||||
}
|
||||
else if (value is float floatValue)
|
||||
{
|
||||
isVisible = Math.Abs(floatValue) > float.Epsilon;
|
||||
}
|
||||
// 处理其他对象 - 非null为true
|
||||
else
|
||||
{
|
||||
isVisible = value != null;
|
||||
}
|
||||
|
||||
// 检查是否需要反向转换
|
||||
bool isInverse = parameter?.ToString()?.Equals("Inverse", StringComparison.OrdinalIgnoreCase) == true;
|
||||
|
||||
if (isInverse)
|
||||
{
|
||||
return isVisible ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
return isVisible ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
|
||||
@ -82,4 +82,44 @@ namespace NavisworksTransport.UI.WPF.Converters
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 布尔值到可见性转换器(标准命名)
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 严格布尔值到可见性转换器(只接受布尔值)
|
||||
/// </summary>
|
||||
public class BooleanToVisibilityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
// 只接受严格的布尔值
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
// 检查是否需要反向转换
|
||||
bool isInverse = parameter?.ToString()?.Equals("Inverse", StringComparison.OrdinalIgnoreCase) == true;
|
||||
|
||||
if (isInverse)
|
||||
{
|
||||
return boolValue ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
return boolValue ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
// 非布尔值直接返回Collapsed
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is Visibility visibility)
|
||||
{
|
||||
return visibility == Visibility.Visible;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -963,7 +963,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
if (success)
|
||||
{
|
||||
var cacheStats = _logisticsAnimationManager.GetCacheStats();
|
||||
GenerationStatus = $"动画对象分析完成 - {cacheStats}";
|
||||
GenerationStatus = $"动画对象分析完成";
|
||||
LogManager.Info($"[缓存预计算] 预计算成功 - {cacheStats}");
|
||||
}
|
||||
else
|
||||
@ -1348,7 +1348,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
if (reportData.IsValid)
|
||||
{
|
||||
CollisionSummary = $"共找到 {reportData.TotalTests} 个测试,{reportData.TotalCollisions} 个碰撞点";
|
||||
// 直接使用报告数据统计
|
||||
CollisionSummary = $"动画检测: {reportData.TotalTests}个 | Clash Detective权威结果: {reportData.TotalCollisions}个";
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1362,7 +1363,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 调用ViewCollisionReportCommand显示详细报告窗口
|
||||
try
|
||||
{
|
||||
// 创建综合碰撞报告命令并执行
|
||||
// 创建综合碰撞报告命令(现在不需要传递参数了!)
|
||||
var reportCommand = NavisworksTransport.Commands.ViewCollisionReportCommand.CreateComprehensive(autoHighlight: false);
|
||||
|
||||
// 执行命令,UI显示会在正确的线程中处理
|
||||
|
||||
@ -12,6 +12,7 @@ using System.IO;
|
||||
using System.Text;
|
||||
using Microsoft.Win32;
|
||||
using System.Threading.Tasks;
|
||||
using Autodesk.Navisworks.Api;
|
||||
|
||||
namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
@ -51,7 +52,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
public int TotalCollisions { get; set; }
|
||||
public int AnimationCollisions { get; set; }
|
||||
public int IndependentCollisions { get; set; }
|
||||
public int OtherCollisions { get; set; }
|
||||
public int NewCollisions { get; set; }
|
||||
public int ActiveCollisions { get; set; }
|
||||
public int ReviewedCollisions { get; set; }
|
||||
@ -73,13 +73,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
private CollisionReportStatistics _statistics;
|
||||
private ObservableCollection<CollisionReportItem> _animationCollisions;
|
||||
private ObservableCollection<CollisionReportItem> _independentCollisions;
|
||||
private ObservableCollection<CollisionReportItem> _otherCollisions;
|
||||
private string _progressMessage;
|
||||
private int _progressPercentage;
|
||||
private bool _isGenerating;
|
||||
private bool _hasCollisions;
|
||||
private string _summaryMessage;
|
||||
private string _recommendationMessage;
|
||||
private string _movingObjectInfo;
|
||||
|
||||
#endregion
|
||||
|
||||
@ -130,14 +130,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
set => SetProperty(ref _independentCollisions, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 其他碰撞列表
|
||||
/// </summary>
|
||||
public ObservableCollection<CollisionReportItem> OtherCollisions
|
||||
{
|
||||
get => _otherCollisions;
|
||||
set => SetProperty(ref _otherCollisions, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进度消息
|
||||
@ -193,6 +185,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
set => SetProperty(ref _recommendationMessage, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 运动物体信息
|
||||
/// </summary>
|
||||
public string MovingObjectInfo
|
||||
{
|
||||
get => _movingObjectInfo;
|
||||
set => SetProperty(ref _movingObjectInfo, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 命令属性
|
||||
@ -226,7 +227,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 初始化集合
|
||||
AnimationCollisions = new ObservableCollection<CollisionReportItem>();
|
||||
IndependentCollisions = new ObservableCollection<CollisionReportItem>();
|
||||
OtherCollisions = new ObservableCollection<CollisionReportItem>();
|
||||
|
||||
Statistics = new CollisionReportStatistics();
|
||||
|
||||
@ -269,7 +269,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
// 清空现有数据
|
||||
AnimationCollisions.Clear();
|
||||
IndependentCollisions.Clear();
|
||||
OtherCollisions.Clear();
|
||||
|
||||
// 设置运动物体信息
|
||||
MovingObjectInfo = reportResult.MovingObjectInfo;
|
||||
|
||||
// 更新统计信息
|
||||
UpdateStatistics(reportResult);
|
||||
@ -328,7 +330,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
TotalCollisions = reportResult.TotalCollisions,
|
||||
AnimationCollisions = reportResult.AnimationCollisions,
|
||||
IndependentCollisions = reportResult.IndependentCollisions,
|
||||
OtherCollisions = reportResult.TotalCollisions - reportResult.AnimationCollisions - reportResult.IndependentCollisions,
|
||||
GenerationTime = $"{reportResult.GenerationTimeMs}ms",
|
||||
ReportType = "综合碰撞报告"
|
||||
};
|
||||
@ -352,39 +353,20 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
if (collisions == null || collisions.Count == 0)
|
||||
return;
|
||||
|
||||
var animationList = new List<CollisionReportItem>();
|
||||
var independentList = new List<CollisionReportItem>();
|
||||
var otherList = new List<CollisionReportItem>();
|
||||
|
||||
foreach (var collision in collisions)
|
||||
{
|
||||
var item = CreateCollisionReportItem(collision);
|
||||
|
||||
if (collision.DisplayName.Contains("动画") || collision.DisplayName.Contains("精确碰撞"))
|
||||
{
|
||||
animationList.Add(item);
|
||||
}
|
||||
else if (collision.DisplayName.Contains("独立检测"))
|
||||
{
|
||||
independentList.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
otherList.Add(item);
|
||||
}
|
||||
independentList.Add(item);
|
||||
}
|
||||
|
||||
// 更新UI集合
|
||||
SafeExecute(() =>
|
||||
{
|
||||
foreach (var item in animationList.OrderBy(i => i.Title))
|
||||
AnimationCollisions.Add(item);
|
||||
|
||||
foreach (var item in independentList.OrderBy(i => i.Title))
|
||||
IndependentCollisions.Add(item);
|
||||
|
||||
foreach (var item in otherList.OrderBy(i => i.Title))
|
||||
OtherCollisions.Add(item);
|
||||
}, "更新碰撞报告项目列表", true);
|
||||
}
|
||||
|
||||
@ -393,20 +375,27 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
private CollisionReportItem CreateCollisionReportItem(CollisionResult collision)
|
||||
{
|
||||
var item1Name = collision.Item1?.DisplayName ?? "未知对象";
|
||||
var item2Name = collision.Item2?.DisplayName ?? "未知对象";
|
||||
|
||||
return new CollisionReportItem
|
||||
// 获取元素名称 - 向上
|
||||
var item1Name = NavisworksApiHelper.GetModelItemNameWithAncestorFallback(collision.Item1);
|
||||
var item2Name = NavisworksApiHelper.GetModelItemNameWithAncestorFallback(collision.Item2);
|
||||
|
||||
var title = $"{item1Name} ↔ {item2Name}";
|
||||
|
||||
var item = new CollisionReportItem
|
||||
{
|
||||
Title = $"{item1Name} ↔ {item2Name}",
|
||||
Description = collision.DisplayName,
|
||||
Title = string.IsNullOrEmpty(title.Trim().Replace("↔", "").Trim()) ? "【空标题测试】" : title,
|
||||
Description = collision.DisplayName ?? "【空描述测试】",
|
||||
StatusText = GetStatusDisplayText(collision.Status),
|
||||
StatusColor = GetStatusColor(collision.Status),
|
||||
Details = $"距离: {collision.Distance:F3}m\n位置: ({collision.Center.X:F2}, {collision.Center.Y:F2}, {collision.Center.Z:F2})\nGUID: {collision.ClashGuid}",
|
||||
CollisionData = collision
|
||||
};
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取状态显示文本
|
||||
/// </summary>
|
||||
@ -486,6 +475,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置空报告状态
|
||||
/// </summary>
|
||||
@ -579,14 +569,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
report.AppendLine("========================================");
|
||||
report.AppendLine($"生成时间: {now:yyyy年MM月dd日 HH:mm:ss}");
|
||||
report.AppendLine($"报告类型: {Statistics.ReportType}");
|
||||
report.AppendLine();
|
||||
|
||||
|
||||
// 总体统计
|
||||
report.AppendLine("=== 总体统计 ===");
|
||||
report.AppendLine($"总碰撞数量: {Statistics.TotalCollisions}");
|
||||
report.AppendLine($"动画过程碰撞: {Statistics.AnimationCollisions}");
|
||||
report.AppendLine($"独立检测碰撞: {Statistics.IndependentCollisions}");
|
||||
report.AppendLine($"其他碰撞: {Statistics.OtherCollisions}");
|
||||
report.AppendLine($"碰撞数量: {Statistics.TotalCollisions}");
|
||||
report.AppendLine($"动画检测碰撞(参考): {Statistics.AnimationCollisions}");
|
||||
report.AppendLine($"ClashDetective检测碰撞: {Statistics.IndependentCollisions}");
|
||||
report.AppendLine();
|
||||
|
||||
// 按状态分类
|
||||
@ -598,12 +586,18 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
report.AppendLine($"已解决: {Statistics.ResolvedCollisions}");
|
||||
report.AppendLine();
|
||||
|
||||
// 运动物体信息
|
||||
if (!string.IsNullOrEmpty(MovingObjectInfo))
|
||||
{
|
||||
report.AppendLine($"{MovingObjectInfo}");
|
||||
}
|
||||
report.AppendLine();
|
||||
|
||||
// 详细碰撞信息
|
||||
if (HasCollisions)
|
||||
{
|
||||
AddCollisionDetailsToTextReport(report, "动画过程碰撞", AnimationCollisions);
|
||||
AddCollisionDetailsToTextReport(report, "独立检测碰撞", IndependentCollisions);
|
||||
AddCollisionDetailsToTextReport(report, "其他碰撞", OtherCollisions);
|
||||
}
|
||||
|
||||
// 总结和建议
|
||||
|
||||
@ -135,7 +135,7 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Text="{Binding Title}" Style="{StaticResource CollisionTitleStyle}"/>
|
||||
<TextBlock Grid.Row="0" Text="{Binding Title}" Style="{StaticResource CollisionDescriptionStyle}" FontWeight="SemiBold"/>
|
||||
|
||||
<Border Grid.Row="1" Style="{StaticResource StatusTagStyle}" Background="{Binding StatusColor}">
|
||||
<TextBlock Text="{Binding StatusText}" Style="{StaticResource StatusTextStyle}"/>
|
||||
@ -191,7 +191,7 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
|
||||
|
||||
<!-- 总体统计信息 -->
|
||||
<Label Content="总体统计" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<UniformGrid Columns="4" Margin="0,0,0,15">
|
||||
<UniformGrid Columns="3" Margin="0,0,0,15">
|
||||
<Border Style="{StaticResource StatisticItemStyle}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
@ -222,16 +222,6 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
|
||||
<TextBlock Grid.Row="1" Text="{Binding Statistics.IndependentCollisions}" Style="{StaticResource StatisticValueStyle}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border Style="{StaticResource StatisticItemStyle}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="其他碰撞" Style="{StaticResource StatisticLabelStyle}"/>
|
||||
<TextBlock Grid.Row="1" Text="{Binding Statistics.OtherCollisions}" Style="{StaticResource StatisticValueStyle}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UniformGrid>
|
||||
|
||||
<!-- 按状态分类统计 -->
|
||||
@ -269,6 +259,27 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
|
||||
</Border>
|
||||
</UniformGrid>
|
||||
|
||||
<!-- 运动物体信息 -->
|
||||
<Border Style="{StaticResource StatisticItemStyle}"
|
||||
Margin="0,0,0,15"
|
||||
Background="#FFF0F8FF"
|
||||
BorderBrush="#FFB0D4F1">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBlock Text="🚛 运动物体信息"
|
||||
FontSize="11"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{StaticResource NavisworksPrimaryBrush}"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,5"/>
|
||||
<TextBlock Text="{Binding MovingObjectInfo}"
|
||||
FontSize="12"
|
||||
FontWeight="Normal"
|
||||
Foreground="#FF333333"
|
||||
HorizontalAlignment="Center"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 总结信息 -->
|
||||
<Label Content="总结与建议" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<Border Style="{StaticResource StatisticItemStyle}" Margin="0,0,0,10">
|
||||
@ -288,14 +299,6 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
|
||||
<!-- 详细碰撞信息 -->
|
||||
<StackPanel Visibility="{Binding HasCollisions, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
|
||||
<!-- 动画过程碰撞 -->
|
||||
<StackPanel Visibility="{Binding AnimationCollisions.Count, Converter={StaticResource CountToVisibilityConverter}}">
|
||||
<Label Content="动画过程碰撞" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<ItemsControl ItemsSource="{Binding AnimationCollisions}"
|
||||
ItemTemplate="{StaticResource CollisionItemTemplate}"
|
||||
Margin="0,0,0,10"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 独立检测碰撞 -->
|
||||
<StackPanel Visibility="{Binding IndependentCollisions.Count, Converter={StaticResource CountToVisibilityConverter}}">
|
||||
<Label Content="独立检测碰撞" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
@ -304,13 +307,6 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
|
||||
Margin="0,0,0,10"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 其他碰撞 -->
|
||||
<StackPanel Visibility="{Binding OtherCollisions.Count, Converter={StaticResource CountToVisibilityConverter}}">
|
||||
<Label Content="其他碰撞" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<ItemsControl ItemsSource="{Binding OtherCollisions}"
|
||||
ItemTemplate="{StaticResource CollisionItemTemplate}"
|
||||
Margin="0,0,0,10"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
|
||||
@ -97,5 +97,78 @@ namespace NavisworksTransport.Utils
|
||||
System.Windows.Application.Current.Dispatcher.Invoke(operation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取ModelItem的显示名称,支持向上溯源父节点
|
||||
/// 如果当前节点没有名称,会向上查找父节点直到找到有名称的节点
|
||||
/// </summary>
|
||||
/// <param name="item">要获取名称的ModelItem</param>
|
||||
/// <param name="maxDepth">最大向上查找深度,防止无限递归</param>
|
||||
/// <returns>元素的显示名称</returns>
|
||||
public static string GetModelItemNameWithAncestorFallback(ModelItem item, int maxDepth = 10)
|
||||
{
|
||||
if (item == null) return "未知对象";
|
||||
|
||||
try
|
||||
{
|
||||
var current = item;
|
||||
int depth = 0;
|
||||
|
||||
while (current != null && depth < maxDepth)
|
||||
{
|
||||
// 只查找DisplayName
|
||||
if (!string.IsNullOrEmpty(current.DisplayName))
|
||||
{
|
||||
return current.DisplayName;
|
||||
}
|
||||
|
||||
// 向上一级父节点继续查找
|
||||
current = current.Parent;
|
||||
depth++;
|
||||
}
|
||||
|
||||
// 如果所有父节点都没有DisplayName,返回默认名称
|
||||
LogManager.Debug($"[元素名称获取] 向上查找{depth}层后仍未找到DisplayName,返回默认名称");
|
||||
return depth > 0 ? "未命名对象(已溯源)" : "未命名对象";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"获取ModelItem DisplayName失败: {ex.Message}");
|
||||
return "获取失败";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取ModelItem的直接显示名称(不溯源父节点)
|
||||
/// 仅从当前节点获取名称,适用于不需要父节点信息的场景
|
||||
/// </summary>
|
||||
/// <param name="item">要获取名称的ModelItem</param>
|
||||
/// <returns>元素的显示名称</returns>
|
||||
public static string GetModelItemName(ModelItem item)
|
||||
{
|
||||
if (item == null) return "未知对象";
|
||||
|
||||
try
|
||||
{
|
||||
// 1. 尝试DisplayName
|
||||
if (!string.IsNullOrEmpty(item.DisplayName))
|
||||
{
|
||||
return item.DisplayName;
|
||||
}
|
||||
|
||||
// 2. 尝试ClassDisplayName
|
||||
if (!string.IsNullOrEmpty(item.ClassDisplayName))
|
||||
{
|
||||
return item.ClassDisplayName;
|
||||
}
|
||||
|
||||
return "未命名对象";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"获取ModelItem名称失败: {ex.Message}");
|
||||
return "获取失败";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user