增加碰撞构件清单
This commit is contained in:
parent
760786d9b1
commit
519382f375
@ -2440,7 +2440,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
else
|
||||
{
|
||||
// 无碰撞:清除碰撞高亮(保留车辆高亮)
|
||||
ModelHighlightHelper.ClearCategory(ModelHighlightHelper.CollisionResultsCategory);
|
||||
ModelHighlightHelper.ClearCategory(ModelHighlightHelper.PrecomputeCollisionResultsCategory);
|
||||
LogManager.Debug($"[高亮状态] 帧{_currentFrameIndex}: 清除碰撞高亮");
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ namespace NavisworksTransport
|
||||
public class ClashDetectiveIntegration
|
||||
{
|
||||
private static ClashDetectiveIntegration _instance;
|
||||
private const string CollisionHighlightsCategory = ModelHighlightHelper.CollisionResultsCategory;
|
||||
private const string CollisionHighlightsCategory = ModelHighlightHelper.PrecomputeCollisionResultsCategory;
|
||||
|
||||
private DocumentClash _documentClash;
|
||||
private List<ClashResult> _currentCollisions;
|
||||
|
||||
@ -77,30 +77,78 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
public Guid InstanceGuid { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 碰撞构件ViewModel
|
||||
/// </summary>
|
||||
public class CollisionObjectViewModel
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string ObjectName { get; set; }
|
||||
public string ModelPath { get; set; }
|
||||
public int ResultId { get; set; }
|
||||
public string TestName { get; set; }
|
||||
public int? ModelIndex { get; set; }
|
||||
public string PathId { get; set; }
|
||||
public ModelItem ModelItem { get; set; }
|
||||
public ICommand HighlightCommand { get; set; }
|
||||
public ICommand ClearHighlightCommand { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ClashDetective碰撞检测结果视图模型
|
||||
/// </summary>
|
||||
public class ClashDetectiveResultViewModel
|
||||
{
|
||||
private readonly Action _refreshCallback;
|
||||
|
||||
public ClashDetectiveResultViewModel(ClashDetectiveResultRecord record, Action refreshCallback)
|
||||
{
|
||||
Record = record ?? throw new ArgumentNullException(nameof(record));
|
||||
_refreshCallback = refreshCallback ?? throw new ArgumentNullException(nameof(refreshCallback));
|
||||
ViewCommand = new RelayCommand(() => ExecuteView());
|
||||
ReportCommand = new RelayCommand(() => ExecuteReport());
|
||||
DeleteCommand = new RelayCommand(() => ExecuteDelete());
|
||||
}
|
||||
private readonly Action _refreshCallback;
|
||||
|
||||
public ClashDetectiveResultViewModel(ClashDetectiveResultRecord record, Action refreshCallback)
|
||||
{
|
||||
Record = record ?? throw new ArgumentNullException(nameof(record));
|
||||
_refreshCallback = refreshCallback ?? throw new ArgumentNullException(nameof(refreshCallback));
|
||||
ViewCommand = new RelayCommand(() => ExecuteView());
|
||||
ReportCommand = new RelayCommand(() => ExecuteReport());
|
||||
DeleteCommand = new RelayCommand(() => ExecuteDelete());
|
||||
CollisionObjects = new ObservableCollection<CollisionObjectViewModel>();
|
||||
}
|
||||
|
||||
public ClashDetectiveResultRecord Record { get; }
|
||||
public string TestTimeDisplay => Record.TestTime.ToString("MM-dd HH:mm:ss");
|
||||
public string CollisionCountDisplay => $"{Record.CollisionCount}个";
|
||||
public ICommand ViewCommand { get; }
|
||||
public ICommand ReportCommand { get; }
|
||||
public ICommand DeleteCommand { get; }
|
||||
public ObservableCollection<CollisionObjectViewModel> CollisionObjects { get; }
|
||||
|
||||
public void ExecuteHighlightCollisionObject(CollisionObjectViewModel collisionObject)
|
||||
{
|
||||
if (collisionObject == null) return;
|
||||
|
||||
public ClashDetectiveResultRecord Record { get; }
|
||||
public string TestTimeDisplay => Record.TestTime.ToString("MM-dd HH:mm:ss");
|
||||
public string CollisionCountDisplay => $"{Record.CollisionCount}个";
|
||||
public ICommand ViewCommand { get; }
|
||||
public ICommand ReportCommand { get; }
|
||||
public ICommand DeleteCommand { get; }
|
||||
try
|
||||
{
|
||||
LogManager.Info($"[碰撞构件] 高亮显示构件: {collisionObject.DisplayName}");
|
||||
|
||||
private void ExecuteView()
|
||||
// 清除之前的高亮
|
||||
ModelHighlightHelper.ClearAllHighlights();
|
||||
|
||||
// 直接使用ModelItem高亮
|
||||
if (collisionObject.ModelItem != null && ModelItemAnalysisHelper.IsModelItemValid(collisionObject.ModelItem))
|
||||
{
|
||||
ModelHighlightHelper.HighlightItems(
|
||||
ModelHighlightHelper.ClashDetectiveResultsCategory,
|
||||
new[] { collisionObject.ModelItem });
|
||||
LogManager.Info($"[碰撞构件] 已高亮构件: {collisionObject.DisplayName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Warning($"[碰撞构件] ModelItem无效或为空: {collisionObject.DisplayName}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[碰撞构件] 高亮显示失败: {ex.Message}", ex);
|
||||
}
|
||||
} private void ExecuteView()
|
||||
{
|
||||
// 高亮显示该次检测的碰撞对象
|
||||
var clashIntegration = ClashDetectiveIntegration.Instance;
|
||||
@ -191,7 +239,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
private DateTime? _manualTargetsLastSyncTime;
|
||||
private const int ManualCollisionTargetLimit = 60;
|
||||
private const string ManualTargetsHighlightCategory = ModelHighlightHelper.ManualTargetsCategory;
|
||||
private const string CollisionResultsHighlightCategory = ModelHighlightHelper.CollisionResultsCategory;
|
||||
private const string CollisionResultsHighlightCategory = ModelHighlightHelper.PrecomputeCollisionResultsCategory;
|
||||
|
||||
#endregion
|
||||
|
||||
@ -596,13 +644,29 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
#region ClashDetective结果管理
|
||||
|
||||
private ObservableCollection<ClashDetectiveResultViewModel> _clashDetectiveResults = new ObservableCollection<ClashDetectiveResultViewModel>();
|
||||
private ClashDetectiveResultViewModel _selectedClashDetectiveResult;
|
||||
|
||||
public ObservableCollection<ClashDetectiveResultViewModel> ClashDetectiveResults => _clashDetectiveResults;
|
||||
|
||||
public ClashDetectiveResultViewModel SelectedClashDetectiveResult
|
||||
{
|
||||
get => _selectedClashDetectiveResult;
|
||||
set
|
||||
{
|
||||
if (_selectedClashDetectiveResult != value)
|
||||
{
|
||||
_selectedClashDetectiveResult = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand RefreshClashDetectiveResultsCommand { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region 媒体控制属性
|
||||
|
||||
/// <summary>
|
||||
@ -753,6 +817,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
DocumentStateManager.Instance.DocumentInvalidated += OnDocumentInvalidated;
|
||||
DocumentStateManager.Instance.DocumentReady += OnDocumentReady;
|
||||
|
||||
// 设置静态实例
|
||||
_instance = this;
|
||||
|
||||
LogManager.Info("AnimationControlViewModel初始化完成 - 支持统一状态栏");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -1770,7 +1837,61 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
foreach (var record in records)
|
||||
{
|
||||
_clashDetectiveResults.Add(new ClashDetectiveResultViewModel(record, RefreshClashDetectiveResultsList));
|
||||
var resultViewModel = new ClashDetectiveResultViewModel(record, RefreshClashDetectiveResultsList);
|
||||
|
||||
// 同时加载该结果的碰撞构件清单
|
||||
var collisionObjectRecords = pathDatabase.GetClashDetectiveCollisionObjects(record.Id);
|
||||
if (collisionObjectRecords != null)
|
||||
{
|
||||
int index = 1;
|
||||
foreach (var objRecord in collisionObjectRecords)
|
||||
{
|
||||
CollisionObjectViewModel objViewModel = null;
|
||||
ModelItem modelItem = null;
|
||||
string modelPath = "路径获取失败";
|
||||
|
||||
// 通过 ModelIndex 和 PathId 重建 ModelItem
|
||||
if (objRecord.ModelIndex.HasValue && !string.IsNullOrEmpty(objRecord.PathId))
|
||||
{
|
||||
try
|
||||
{
|
||||
var pathIdObj = new Autodesk.Navisworks.Api.DocumentParts.ModelItemPathId
|
||||
{
|
||||
ModelIndex = objRecord.ModelIndex.Value,
|
||||
PathId = objRecord.PathId
|
||||
};
|
||||
modelItem = Application.ActiveDocument.Models.ResolvePathId(pathIdObj);
|
||||
|
||||
// 获取完整的节点树路径
|
||||
if (modelItem != null)
|
||||
{
|
||||
modelPath = BuildModelPath(modelItem);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[碰撞构件] 无法通过 PathId 找到 ModelItem: ModelIndex={objRecord.ModelIndex}, PathId={objRecord.PathId}, 错误: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
objViewModel = new CollisionObjectViewModel
|
||||
{
|
||||
Index = index++,
|
||||
DisplayName = objRecord.DisplayName,
|
||||
ObjectName = objRecord.ObjectName,
|
||||
ModelPath = modelPath,
|
||||
ResultId = objRecord.ResultId,
|
||||
TestName = record.TestName,
|
||||
ModelIndex = objRecord.ModelIndex,
|
||||
PathId = objRecord.PathId,
|
||||
ModelItem = modelItem,
|
||||
HighlightCommand = new RelayCommand(() => resultViewModel.ExecuteHighlightCollisionObject(objViewModel))
|
||||
};
|
||||
resultViewModel.CollisionObjects.Add(objViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
_clashDetectiveResults.Add(resultViewModel);
|
||||
}
|
||||
|
||||
// 更新HasClashDetectiveResults属性
|
||||
|
||||
@ -432,7 +432,9 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
MinHeight="120"
|
||||
MaxHeight="200"
|
||||
BorderBrush="#FFE2E8F0"
|
||||
BorderThickness="1">
|
||||
BorderThickness="1"
|
||||
SelectionMode="Single"
|
||||
SelectionChanged="OnClashDetectiveResultSelectionChanged">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="测试名称" Width="140">
|
||||
@ -461,7 +463,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Header="操作" Width="200">
|
||||
<GridViewColumn Header="操作" Width="260">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
@ -495,7 +497,73 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 区域6: 当前路径信息 -->
|
||||
<!-- 区域7: 碰撞构件清单 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,15" Padding="12">
|
||||
<StackPanel>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Grid.Column="0" Content="碰撞构件清单" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
<Button Grid.Column="1"
|
||||
Content="清除高亮"
|
||||
Command="{Binding ClearClashDetectiveHighlightsCommand}"
|
||||
Style="{StaticResource SecondaryButtonStyle}"
|
||||
Height="22"
|
||||
Padding="8,2"
|
||||
Margin="0,0,0,0"/>
|
||||
</Grid>
|
||||
|
||||
<TextBlock Text="请先在碰撞检测历史中选择一个检测结果"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
Foreground="#FF777777"
|
||||
Visibility="{Binding ClashDetectiveResults.Count, Converter={StaticResource BoolToVisConverter}, ConverterParameter=Inverse}"
|
||||
Margin="0,5,0,0"/>
|
||||
|
||||
<ListView ItemsSource="{Binding SelectedClashDetectiveResult.CollisionObjects}"
|
||||
Margin="0,5,0,0"
|
||||
Visibility="{Binding SelectedClashDetectiveResult.CollisionObjects.Count, Converter={StaticResource BoolToVisConverter}}"
|
||||
MinHeight="120"
|
||||
MaxHeight="200"
|
||||
BorderBrush="#FFE2E8F0"
|
||||
BorderThickness="1"
|
||||
SelectionMode="Single"
|
||||
SelectionChanged="OnCollisionObjectSelectionChanged">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="序号" Width="50">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Index}"
|
||||
HorizontalAlignment="Center"/>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Header="构件名称" Width="400">
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding DisplayName}"
|
||||
FontWeight="SemiBold"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
ToolTip="{Binding DisplayName}"/>
|
||||
<TextBlock Text="{Binding ModelPath}"
|
||||
Style="{StaticResource StatusTextStyle}"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
ToolTip="{Binding ModelPath}"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 区域8: 当前路径信息 -->
|
||||
<Border BorderBrush="#FFD4E7FF" BorderThickness="1" CornerRadius="0" Margin="0,0,0,0" Padding="12">
|
||||
<StackPanel>
|
||||
<Label Content="当前路径信息" Style="{StaticResource SectionHeaderStyle}"/>
|
||||
|
||||
@ -82,5 +82,54 @@ namespace NavisworksTransport.UI.WPF.Views
|
||||
LogManager.Error($"AnimationControlView资源清理失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 碰撞检测结果选择变化事件处理
|
||||
/// </summary>
|
||||
private void OnClashDetectiveResultSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ViewModel == null) return;
|
||||
|
||||
// 获取选中的结果
|
||||
var listView = sender as ListView;
|
||||
if (listView?.SelectedItem is ClashDetectiveResultViewModel selectedResult)
|
||||
{
|
||||
ViewModel.SelectedClashDetectiveResult = selectedResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewModel.SelectedClashDetectiveResult = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[AnimationControlView] 处理碰撞检测结果选择变化失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 碰撞构件选择变化事件处理
|
||||
/// </summary>
|
||||
private void OnCollisionObjectSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ViewModel == null || ViewModel.SelectedClashDetectiveResult == null) return;
|
||||
|
||||
// 获取选中的构件
|
||||
var listView = sender as ListView;
|
||||
if (listView?.SelectedItem is CollisionObjectViewModel selectedObject)
|
||||
{
|
||||
// 触发高亮
|
||||
ViewModel.SelectedClashDetectiveResult.ExecuteHighlightCollisionObject(selectedObject);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[AnimationControlView] 处理碰撞构件选择变化失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10,7 +10,7 @@ namespace NavisworksTransport.Utils
|
||||
/// </summary>
|
||||
public static class ModelHighlightHelper
|
||||
{
|
||||
public const string CollisionResultsCategory = "collisionResults";
|
||||
public const string PrecomputeCollisionResultsCategory = "collisionResults";
|
||||
public const string ManualTargetsCategory = "manualTargets";
|
||||
public const string ChannelPreviewCategory = "channelPreview";
|
||||
public const string ClashDetectiveResultsCategory = "clashDetectiveResults";
|
||||
@ -43,7 +43,7 @@ namespace NavisworksTransport.Utils
|
||||
{ "report", Color.Green },
|
||||
{ "preview", Color.Blue },
|
||||
{ ManualTargetsCategory, Color.FromByteRGB(255, 170, 0) },
|
||||
{ CollisionResultsCategory, Color.FromByteRGB(244, 67, 54) }, // Material Red(预计算碰撞)
|
||||
{ PrecomputeCollisionResultsCategory, Color.FromByteRGB(244, 67, 54) }, // Material Red(预计算碰撞)
|
||||
{ ChannelPreviewCategory, Color.Green },
|
||||
{ ClashDetectiveResultsCategory, Color.Red },
|
||||
{ AnimatedObjectCategory, Color.FromByteRGB(76, 175, 80) } // Material Green(动画车辆)
|
||||
@ -125,7 +125,7 @@ namespace NavisworksTransport.Utils
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
ClearCategory(CollisionResultsCategory);
|
||||
ClearCategory(PrecomputeCollisionResultsCategory);
|
||||
ClearCategory(ClashDetectiveResultsCategory);
|
||||
}
|
||||
}
|
||||
@ -255,14 +255,14 @@ namespace NavisworksTransport.Utils
|
||||
{
|
||||
if (clearPrevious)
|
||||
{
|
||||
ClearCategory(CollisionResultsCategory);
|
||||
ClearCategory(PrecomputeCollisionResultsCategory);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (clearPrevious)
|
||||
{
|
||||
ClearCategory(CollisionResultsCategory);
|
||||
ClearCategory(PrecomputeCollisionResultsCategory);
|
||||
}
|
||||
|
||||
var highlightItems = new List<ModelItem>();
|
||||
@ -279,7 +279,7 @@ namespace NavisworksTransport.Utils
|
||||
}
|
||||
}
|
||||
|
||||
HighlightItems(CollisionResultsCategory, highlightItems);
|
||||
HighlightItems(PrecomputeCollisionResultsCategory, highlightItems);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user