在碰撞报告中显示排除对象清单

This commit is contained in:
tian 2026-02-10 10:24:01 +08:00
parent e221d42812
commit 9a7a2da3c6
5 changed files with 288 additions and 32 deletions

View File

@ -6,6 +6,10 @@
1. [.] (功能)增加预计算结果分析和排除建议 1. [.] (功能)增加预计算结果分析和排除建议
2. [ ] (优化)考虑在碰撞报告中,给每一个碰撞元素自动建立截图 2. [ ] (优化)考虑在碰撞报告中,给每一个碰撞元素自动建立截图
3. [ ] (优化)考虑是否给截图按碰撞记录组织成子文件夹
4. [ ] 优化研究如何利用ClashDetective的多线程支持打开多线程
5. [ ] 优化给每个检测到的碰撞对象增加单独视角45度近距离
6. [ ] (优化)点击碰撞列表的碰撞详情时,要把运动物体移动到位,查看碰撞情况
### [2026/2/6] ### [2026/2/6]

View File

@ -126,6 +126,9 @@ namespace NavisworksTransport.Commands
// 截图列表 - 支持多张截图 // 截图列表 - 支持多张截图
public List<CollisionReportScreenshot> Screenshots { get; set; } = new List<CollisionReportScreenshot>(); public List<CollisionReportScreenshot> Screenshots { get; set; } = new List<CollisionReportScreenshot>();
// 排除对象列表
public List<ExcludedObjectRecord> ExcludedObjects { get; set; } = new List<ExcludedObjectRecord>();
} }
/// <summary> /// <summary>
@ -305,6 +308,21 @@ namespace NavisworksTransport.Commands
}).ToList(); }).ToList();
LogManager.Info($"从数据库加载了 {result.Screenshots.Count} 张截图 (ResultId={testRecord.Id})"); LogManager.Info($"从数据库加载了 {result.Screenshots.Count} 张截图 (ResultId={testRecord.Id})");
} }
// 加载排除对象列表
try
{
var excludedObjects = pathDatabase.GetExcludedObjectsForClashDetectiveResult(testRecord.Id);
if (excludedObjects != null && excludedObjects.Count > 0)
{
result.ExcludedObjects = excludedObjects;
LogManager.Info($"从数据库加载了 {excludedObjects.Count} 个排除对象 (ResultId={testRecord.Id})");
}
}
catch (Exception ex)
{
LogManager.Error($"加载排除对象列表失败: {ex.Message}");
}
} }
} }
catch (Exception ex) catch (Exception ex)

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Windows.Input; using System.Windows.Input;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Utils; using NavisworksTransport.Utils;
using NavisworksTransport.Commands; using NavisworksTransport.Commands;
using System.IO; using System.IO;
@ -35,11 +36,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels
/// </summary> /// </summary>
public class CollisionReportItem public class CollisionReportItem
{ {
public int Index { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string Description { get; set; } public string Description { get; set; }
public string StatusText { get; set; } public string StatusText { get; set; }
public string StatusColor { get; set; } public string StatusColor { get; set; }
public string Details { get; set; } public string Details { get; set; }
public string Item1FullPath { get; set; }
public string Item2FullPath { get; set; }
public CollisionResult CollisionData { get; set; } public CollisionResult CollisionData { get; set; }
} }
@ -84,6 +88,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
private double _duration; private double _duration;
private double _detectionTolerance; private double _detectionTolerance;
private CollisionReportResult _currentReport; private CollisionReportResult _currentReport;
private ObservableCollection<ExcludedObjectRecord> _excludedObjects;
#endregion #endregion
@ -314,6 +319,32 @@ namespace NavisworksTransport.UI.WPF.ViewModels
/// </summary> /// </summary>
public int ScreenshotCount => Screenshots?.Count ?? 0; public int ScreenshotCount => Screenshots?.Count ?? 0;
/// <summary>
/// 排除对象列表
/// </summary>
public ObservableCollection<ExcludedObjectRecord> ExcludedObjects
{
get => _excludedObjects;
set
{
if (SetProperty(ref _excludedObjects, value))
{
OnPropertyChanged(nameof(HasExcludedObjects));
OnPropertyChanged(nameof(ExcludedObjectsCount));
}
}
}
/// <summary>
/// 是否有排除对象
/// </summary>
public bool HasExcludedObjects => ExcludedObjects?.Count > 0;
/// <summary>
/// 排除对象数量
/// </summary>
public int ExcludedObjectsCount => ExcludedObjects?.Count ?? 0;
/// <summary> /// <summary>
/// 获取截图的BitmapImage /// 获取截图的BitmapImage
/// </summary> /// </summary>
@ -425,6 +456,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 初始化集合 // 初始化集合
AnimationCollisions = new ObservableCollection<CollisionReportItem>(); AnimationCollisions = new ObservableCollection<CollisionReportItem>();
CollidedObjectsList = new ObservableCollection<string>(); CollidedObjectsList = new ObservableCollection<string>();
ExcludedObjects = new ObservableCollection<ExcludedObjectRecord>();
Statistics = new CollisionReportStatistics(); Statistics = new CollisionReportStatistics();
@ -474,6 +506,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
AnimationCollisions.Clear(); AnimationCollisions.Clear();
CollidedObjectsList.Clear(); CollidedObjectsList.Clear();
Screenshots.Clear(); Screenshots.Clear();
ExcludedObjects.Clear();
// 加载截图列表 // 加载截图列表
if (reportResult.Screenshots?.Count > 0) if (reportResult.Screenshots?.Count > 0)
@ -500,6 +533,16 @@ namespace NavisworksTransport.UI.WPF.ViewModels
} }
} }
// 加载排除对象列表
if (reportResult.ExcludedObjects?.Count > 0)
{
foreach (var excludedObj in reportResult.ExcludedObjects)
{
ExcludedObjects.Add(excludedObj);
}
LogManager.Info($"碰撞报告加载了 {ExcludedObjects.Count} 个排除对象");
}
// 设置动画参数 // 设置动画参数
PathName = reportResult.PathName; PathName = reportResult.PathName;
FrameRate = reportResult.FrameRate; FrameRate = reportResult.FrameRate;
@ -586,10 +629,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
return; return;
var collisionItems = new List<CollisionReportItem>(); var collisionItems = new List<CollisionReportItem>();
int index = 1;
foreach (var collision in collisions) foreach (var collision in collisions)
{ {
var item = CreateCollisionReportItem(collision); var item = CreateCollisionReportItem(collision, index++);
collisionItems.Add(item); collisionItems.Add(item);
} }
@ -605,28 +649,63 @@ namespace NavisworksTransport.UI.WPF.ViewModels
/// <summary> /// <summary>
/// 创建碰撞报告项目 /// 创建碰撞报告项目
/// </summary> /// </summary>
private CollisionReportItem CreateCollisionReportItem(CollisionResult collision) private CollisionReportItem CreateCollisionReportItem(CollisionResult collision, int index)
{ {
// 获取元素名称和全路径
// 获取元素名称 - Item1和Item2已经是容器对象在创建CollisionResult时已用FindNamedParentContainer处理
var item1Name = ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item1); var item1Name = ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item1);
var item2Name = ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2); var item2Name = ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2);
var item1Path = GetModelItemFullPath(collision.Item1);
var item2Path = GetModelItemFullPath(collision.Item2);
var title = $"{item1Name} ↔ {item2Name}"; var title = $"{item1Name} ↔ {item2Name}";
var item = new CollisionReportItem var item = new CollisionReportItem
{ {
Title = string.IsNullOrEmpty(title.Trim().Replace("↔", "").Trim()) ? "【空标题测试】" : title, Index = index,
Description = collision.DisplayName ?? "【空描述测试】", Title = string.IsNullOrEmpty(title.Trim().Replace("↔", "").Trim()) ? "未命名碰撞" : title,
StatusText = GetStatusDisplayText(collision.Status), StatusText = GetStatusDisplayText(collision.Status),
StatusColor = GetStatusColor(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}", Details = $"位置: ({collision.Center.X:F2}, {collision.Center.Y:F2}, {collision.Center.Z:F2})",
Item1FullPath = $"🚛 运动物体: {item1Path}",
Item2FullPath = $"💥 被撞对象: {item2Path}",
CollisionData = collision CollisionData = collision
}; };
return item; return item;
} }
/// <summary>
/// 获取ModelItem的完整层级路径
/// </summary>
private string GetModelItemFullPath(ModelItem item)
{
if (item == null) return "未知对象";
try
{
var pathParts = new List<string>();
var current = item;
int levels = 0;
while (current != null && levels < 20)
{
var name = ModelItemAnalysisHelper.GetSafeDisplayName(current);
if (!string.IsNullOrEmpty(name) && name != "未命名对象")
{
pathParts.Insert(0, name);
}
current = current.Parent;
levels++;
}
return pathParts.Count > 0 ? string.Join(" > ", pathParts) : "未知对象";
}
catch
{
return ModelItemAnalysisHelper.GetSafeDisplayName(item);
}
}
/// <summary> /// <summary>
/// 获取状态显示文本 /// 获取状态显示文本

View File

@ -130,22 +130,45 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
CommandParameter="{Binding}"/> CommandParameter="{Binding}"/>
</Border.InputBindings> </Border.InputBindings>
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.ColumnDefinitions>
<RowDefinition Height="Auto"/> <ColumnDefinition Width="Auto"/>
<RowDefinition Height="Auto"/> <ColumnDefinition Width="*"/>
<RowDefinition Height="Auto"/> </Grid.ColumnDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Title}" Style="{StaticResource CollisionDescriptionStyle}" FontWeight="SemiBold"/> <!-- 序号 -->
<TextBlock Grid.Column="0"
Text="{Binding Index, StringFormat={}{0}.}"
FontWeight="Bold"
Foreground="#FF2B579A"
FontSize="14"
VerticalAlignment="Top"
Margin="0,0,8,0"/>
<Border Grid.Row="1" Style="{StaticResource StatusTagStyle}" Background="{Binding StatusColor}"> <StackPanel Grid.Column="1">
<TextBlock Text="{Binding StatusText}" Style="{StaticResource StatusTextStyle}"/> <!-- 标题 -->
</Border> <TextBlock Text="{Binding Title}" Style="{StaticResource CollisionDescriptionStyle}" FontWeight="SemiBold"/>
<TextBlock Grid.Row="2" Text="{Binding Description}" Style="{StaticResource CollisionDescriptionStyle}"/> <!-- 全路径 -->
<TextBlock Text="{Binding Item1FullPath}"
Style="{StaticResource CollisionDescriptionStyle}"
Margin="0,2,0,0"
FontSize="10"
Foreground="#FF666666"
TextTrimming="CharacterEllipsis"/>
<TextBlock Text="{Binding Item2FullPath}"
Style="{StaticResource CollisionDescriptionStyle}"
Margin="0,1,0,0"
FontSize="10"
Foreground="#FF666666"
TextTrimming="CharacterEllipsis"/>
<TextBlock Grid.Row="3" Text="{Binding Details}" Style="{StaticResource CollisionDescriptionStyle}" Margin="0,3,0,0"/> <!-- 位置信息 -->
<TextBlock Text="{Binding Details}"
Style="{StaticResource CollisionDescriptionStyle}"
Margin="0,3,0,0"
FontSize="10"
Foreground="#FF999999"/>
</StackPanel>
</Grid> </Grid>
</Border> </Border>
</DataTemplate> </DataTemplate>
@ -265,8 +288,8 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="检测间隙(米)" Style="{StaticResource StatisticLabelStyle}"/> <TextBlock Grid.Row="0" Text="检测容差(米)" Style="{StaticResource StatisticLabelStyle}"/>
<TextBlock Grid.Row="1" Text="{Binding DetectionGap, StringFormat={}{0:F2}}" Style="{StaticResource StatisticValueStyle}"/> <TextBlock Grid.Row="1" Text="{Binding DetectionTolerance, StringFormat={}{0:F2}}" Style="{StaticResource StatisticValueStyle}"/>
</Grid> </Grid>
</Border> </Border>
</UniformGrid> </UniformGrid>
@ -449,16 +472,29 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
<!-- 碰撞构件清单 --> <!-- 碰撞构件清单 -->
<StackPanel Visibility="{Binding CollidedObjectsList.Count, Converter={StaticResource CountToVisibilityConverter}}" Margin="0,0,0,15"> <StackPanel Visibility="{Binding CollidedObjectsList.Count, Converter={StaticResource CountToVisibilityConverter}}" Margin="0,0,0,15">
<Label Content="碰撞构件清单" Style="{StaticResource SectionHeaderStyle}"/> <Grid>
<Border Style="{StaticResource StatisticItemStyle}" MaxHeight="150"> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Content="碰撞构件清单" Style="{StaticResource SectionHeaderStyle}" Grid.Column="0"/>
<TextBlock Grid.Column="1"
Text="{Binding UniqueCollidedObjectsCount, StringFormat='{}{0} 个'}"
VerticalAlignment="Center"
Foreground="#FF666666"
FontSize="11"
Margin="0,0,10,0"/>
</Grid>
<Border Style="{StaticResource StatisticItemStyle}" MaxHeight="150" Background="#FFFDF2F2" BorderBrush="#FFF5C6C6">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled"> <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ItemsControl ItemsSource="{Binding CollidedObjectsList}"> <ItemsControl ItemsSource="{Binding CollidedObjectsList}">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Orientation="Horizontal" Margin="5,2"> <StackPanel Orientation="Horizontal" Margin="5,2">
<TextBlock Text="•" FontWeight="Bold" Foreground="{StaticResource NavisworksPrimaryBrush}" Margin="0,0,8,0"/> <TextBlock Text="⚠️" Margin="0,0,6,0"/>
<TextBlock Text="{Binding}" <TextBlock Text="{Binding}"
Style="{StaticResource DialogContentTextStyle}" FontWeight="SemiBold"
Foreground="#FF721C24"
TextWrapping="Wrap"/> TextWrapping="Wrap"/>
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
@ -468,6 +504,60 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
</Border> </Border>
</StackPanel> </StackPanel>
<!-- 排除对象清单 -->
<StackPanel Visibility="{Binding HasExcludedObjects, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="0,0,0,15">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Content="排除对象清单" Style="{StaticResource SectionHeaderStyle}" Grid.Column="0"/>
<TextBlock Grid.Column="1"
Text="{Binding ExcludedObjectsCount, StringFormat='{}{0} 个'}"
VerticalAlignment="Center"
Foreground="#FF666666"
FontSize="11"
Margin="0,0,10,0"/>
</Grid>
<Border Style="{StaticResource StatisticItemStyle}" MaxHeight="200" Background="#FFFEF9E7" BorderBrush="#FFF9E79F">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ItemsControl ItemsSource="{Binding ExcludedObjects}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5,3">
<StackPanel Orientation="Horizontal">
<TextBlock Text="🚫" Margin="0,0,6,0"/>
<TextBlock Text="{Binding DisplayName}"
FontWeight="SemiBold"
Foreground="#FF856404"
TextWrapping="Wrap"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="20,2,0,0">
<TextBlock Text="原因: " FontSize="10" Foreground="#FF666666"/>
<TextBlock Text="{Binding Reason, TargetNullValue='无', FallbackValue='无'}"
FontSize="10"
Foreground="#FF666666"
TextWrapping="Wrap"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="20,2,0,0">
<TextBlock Text="时间: " FontSize="10" Foreground="#FF999999"/>
<TextBlock Text="{Binding ExcludedTime, StringFormat={}{0:yyyy-MM-dd HH:mm}}"
FontSize="10"
Foreground="#FF999999"/>
<TextBlock Text=" | " FontSize="10" Foreground="#FF999999"/>
<TextBlock Text="{Binding PathId}"
FontSize="10"
Foreground="#FF999999"
FontStyle="Italic"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Border>
</StackPanel>
<!-- 总结信息 --> <!-- 总结信息 -->
<Label Content="总结与建议" Style="{StaticResource SectionHeaderStyle}"/> <Label Content="总结与建议" Style="{StaticResource SectionHeaderStyle}"/>
<Border Style="{StaticResource StatisticItemStyle}" Margin="0,0,0,10"> <Border Style="{StaticResource StatisticItemStyle}" Margin="0,0,0,10">

View File

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Commands; using NavisworksTransport.Commands;
namespace NavisworksTransport.Utils namespace NavisworksTransport.Utils
@ -42,8 +44,10 @@ namespace NavisworksTransport.Utils
html.AppendLine(".stat-label { font-size: 12px; color: #666; margin-bottom: 5px; }"); html.AppendLine(".stat-label { font-size: 12px; color: #666; margin-bottom: 5px; }");
html.AppendLine(".stat-value { font-size: 18px; font-weight: bold; color: #2c5aa0; }"); html.AppendLine(".stat-value { font-size: 18px; font-weight: bold; color: #2c5aa0; }");
html.AppendLine(".moving-object { background: #f0f8ff; padding: 15px; border-radius: 8px; text-align: center; margin: 15px 0; border: 1px solid #b0d4f1; }"); html.AppendLine(".moving-object { background: #f0f8ff; padding: 15px; border-radius: 8px; text-align: center; margin: 15px 0; border: 1px solid #b0d4f1; }");
html.AppendLine(".collided-list { background: #f8fbff; padding: 15px; border-radius: 8px; margin: 15px 0; max-height: 200px; overflow-y: auto; }"); html.AppendLine(".collided-list { background: #fdf2f2; padding: 15px; border-radius: 8px; margin: 15px 0; max-height: 200px; overflow-y: auto; border: 1px solid #f5c6c6; }");
html.AppendLine(".list-item { margin: 5px 0; padding: 5px; border-left: 3px solid #2c5aa0; padding-left: 10px; }"); html.AppendLine(".collided-list .list-item { margin: 5px 0; padding: 5px; border-left: 3px solid #dc3545; padding-left: 10px; color: #721c24; font-weight: 500; }");
html.AppendLine(".excluded-list { background: #fef9e7; padding: 15px; border-radius: 8px; margin: 15px 0; max-height: 250px; overflow-y: auto; border: 1px solid #f9e79f; }");
html.AppendLine(".excluded-list .list-item { margin: 5px 0; padding: 5px; border-left: 3px solid #f9e79f; padding-left: 10px; color: #856404; }");
html.AppendLine(".recommendation { background: #fff3cd; padding: 15px; border-radius: 8px; border-left: 4px solid #ffc107; margin: 15px 0; }"); html.AppendLine(".recommendation { background: #fff3cd; padding: 15px; border-radius: 8px; border-left: 4px solid #ffc107; margin: 15px 0; }");
html.AppendLine(".collision-item { background: white; margin: 10px 0; padding: 15px; border-radius: 6px; border: 1px solid #eee; }"); html.AppendLine(".collision-item { background: white; margin: 10px 0; padding: 15px; border-radius: 6px; border: 1px solid #eee; }");
html.AppendLine(".collision-title { font-weight: bold; color: #333; margin-bottom: 8px; }"); html.AppendLine(".collision-title { font-weight: bold; color: #333; margin-bottom: 8px; }");
@ -201,6 +205,7 @@ namespace NavisworksTransport.Utils
{ {
html.AppendLine("<h2>碰撞构件清单</h2>"); html.AppendLine("<h2>碰撞构件清单</h2>");
html.AppendLine("<div class='collided-list'>"); html.AppendLine("<div class='collided-list'>");
html.AppendLine($"<p style='margin: 0 0 10px 0; color: #721c24;'><strong>⚠️ 发现 {report.UniqueCollidedObjectsCount} 个碰撞构件</strong></p>");
int index = 1; int index = 1;
foreach (var objName in report.CollidedObjectsList.Take(50)) // 限制显示前50个 foreach (var objName in report.CollidedObjectsList.Take(50)) // 限制显示前50个
{ {
@ -214,6 +219,31 @@ namespace NavisworksTransport.Utils
html.AppendLine("</div>"); html.AppendLine("</div>");
} }
// 排除对象清单
if (report.ExcludedObjects?.Count > 0)
{
html.AppendLine("<h2>排除对象清单</h2>");
html.AppendLine("<div class='excluded-list'>");
html.AppendLine($"<p style='margin: 0 0 10px 0; color: #856404;'><strong>🚫 以下 {report.ExcludedObjects.Count} 个对象被排除在碰撞检测之外</strong></p>");
int index = 1;
foreach (var excludedObj in report.ExcludedObjects.Take(30)) // 限制显示前30个
{
string displayName = !string.IsNullOrEmpty(excludedObj.DisplayName) ? excludedObj.DisplayName : excludedObj.ObjectName ?? "未知对象";
string reason = !string.IsNullOrEmpty(excludedObj.Reason) ? $"原因: {excludedObj.Reason}" : "无";
string time = excludedObj.ExcludedTime > DateTime.MinValue ? $"时间: {excludedObj.ExcludedTime:yyyy-MM-dd HH:mm}" : "";
html.AppendLine($"<div class='list-item'>");
html.AppendLine($"<strong>{index}. {displayName}</strong>");
html.AppendLine($"<span style='color: #856404; font-size: 11px; margin-left: 10px;'>({reason}{(!string.IsNullOrEmpty(time) ? " | " + time : "")})</span>");
html.AppendLine("</div>");
index++;
}
if (report.ExcludedObjects.Count > 30)
{
html.AppendLine($"<div class='list-item'><em>... 还有 {report.ExcludedObjects.Count - 30} 个排除对象</em></div>");
}
html.AppendLine("</div>");
}
// 总结与建议 // 总结与建议
html.AppendLine("<h2>总结与建议</h2>"); html.AppendLine("<h2>总结与建议</h2>");
html.AppendLine("<div class='recommendation'>"); html.AppendLine("<div class='recommendation'>");
@ -271,13 +301,16 @@ namespace NavisworksTransport.Utils
string item2Name = collision.Item2 != null ? ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2) : "未知对象"; string item2Name = collision.Item2 != null ? ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2) : "未知对象";
html.AppendLine($"<div class='collision-title'>{collisionIndex}. {item1Name} ↔ {item2Name}</div>"); html.AppendLine($"<div class='collision-title'>{collisionIndex}. {item1Name} ↔ {item2Name}</div>");
// 碰撞距离 // 全路径
html.AppendLine($"<p><strong>碰撞距离:</strong> {collision.Distance:F3} 米</p>"); string item1Path = GetModelItemFullPath(collision.Item1);
string item2Path = GetModelItemFullPath(collision.Item2);
html.AppendLine($"<p style='font-size: 11px; color: #666; margin: 3px 0;'>🚛 <strong>运动物体:</strong> {item1Path}</p>");
html.AppendLine($"<p style='font-size: 11px; color: #666; margin: 3px 0;'>💥 <strong>被撞对象:</strong> {item2Path}</p>");
// 碰撞位置 // 碰撞位置
if (collision.Center != null) if (collision.Center != null)
{ {
html.AppendLine($"<p><strong>碰撞位置:</strong> ({collision.Center.X:F2}, {collision.Center.Y:F2}, {collision.Center.Z:F2})</p>"); html.AppendLine($"<p style='font-size: 11px; color: #999; margin: 3px 0;'><strong>位置:</strong> ({collision.Center.X:F2}, {collision.Center.Y:F2}, {collision.Center.Z:F2})</p>");
} }
html.AppendLine("</div>"); html.AppendLine("</div>");
@ -330,6 +363,38 @@ namespace NavisworksTransport.Utils
} }
} }
/// <summary>
/// 获取ModelItem的完整层级路径
/// </summary>
private static string GetModelItemFullPath(ModelItem item)
{
if (item == null) return "未知对象";
try
{
var pathParts = new List<string>();
var current = item;
int levels = 0;
while (current != null && levels < 20)
{
var name = ModelItemAnalysisHelper.GetSafeDisplayName(current);
if (!string.IsNullOrEmpty(name) && name != "未命名对象")
{
pathParts.Insert(0, name);
}
current = current.Parent;
levels++;
}
return pathParts.Count > 0 ? string.Join(" > ", pathParts) : "未知对象";
}
catch
{
return ModelItemAnalysisHelper.GetSafeDisplayName(item);
}
}
/// <summary> /// <summary>
/// 自动生成并保存HTML报告到默认目录 /// 自动生成并保存HTML报告到默认目录
/// </summary> /// </summary>