新增 ModelItemBoundsWindow 窗口以显示选中模型元素的包围盒信息;调整碰撞检测报告窗口高度

This commit is contained in:
tian 2026-02-05 23:42:50 +08:00
parent c0333810ec
commit 39749dcf3d
6 changed files with 499 additions and 1 deletions

View File

@ -242,6 +242,9 @@
<Compile Include="src\UI\WPF\Views\EditCoordinatesWindow.xaml.cs">
<DependentUpon>EditCoordinatesWindow.xaml</DependentUpon>
</Compile>
<Compile Include="src\UI\WPF\Views\ModelItemBoundsWindow.xaml.cs">
<DependentUpon>ModelItemBoundsWindow.xaml</DependentUpon>
</Compile>
<Compile Include="src\UI\WPF\Views\EditRotationWindow.xaml.cs">
<DependentUpon>EditRotationWindow.xaml</DependentUpon>
</Compile>
@ -317,6 +320,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="src\UI\WPF\Views\ModelItemBoundsWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="src\UI\WPF\Views\EditRotationWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -17,7 +17,7 @@ NavisworksTransport 碰撞检测报告对话框 - 采用与主界面一致的Nav
xmlns:local="clr-namespace:NavisworksTransport.UI.WPF.Converters"
mc:Ignorable="d"
Title="碰撞检测报告"
Height="1200"
Height="1080"
Width="900"
ResizeMode="CanResize"
WindowStartupLocation="CenterOwner"

View File

@ -0,0 +1,228 @@
<Window x:Class="NavisworksTransport.UI.WPF.Views.ModelItemBoundsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="元素包围盒信息" Height="440" Width="420"
WindowStartupLocation="CenterScreen"
ResizeMode="CanResize"
ShowInTaskbar="True"
Topmost="False"
Background="White">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/NavisworksTransportPlugin;component/src/UI/WPF/Resources/NavisworksStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 标题栏 -->
<Border Grid.Row="0" Background="#FFF8FBFF" BorderBrush="#FFD4E7FF" BorderThickness="0,0,0,1" Padding="20,12">
<StackPanel>
<TextBlock Text="元素包围盒信息" FontWeight="SemiBold" FontSize="14" Foreground="#FF2B579A"/>
<TextBlock Text="当前选中模型元素的包围盒信息(单位:模型单位)" FontSize="10" Foreground="#FF666666" Margin="0,3,0,0"/>
</StackPanel>
</Border>
<!-- 信息区域 -->
<Border Grid.Row="1" Padding="20,12">
<StackPanel>
<!-- 元素名称 -->
<Border Background="#FFF0F7FF" BorderBrush="#FFD4E7FF" BorderThickness="1" Padding="10,8" Margin="0,0,0,12">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="元素名称:" FontSize="10" Foreground="#FF666666" VerticalAlignment="Center"/>
<TextBox Grid.Column="1" Text="{Binding ElementName}" FontSize="10" FontWeight="SemiBold" Foreground="#FF2B579A" VerticalAlignment="Center" Margin="5,0,0,0" IsReadOnly="True" BorderThickness="0" Background="Transparent"/>
</Grid>
</Border>
<!-- 尺寸信息 -->
<TextBlock Text="尺寸信息" FontWeight="SemiBold" FontSize="11" Foreground="#FF333333" Margin="0,0,0,6"/>
<Grid Margin="0,0,0,12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- X尺寸 -->
<Grid Grid.Column="0" Margin="0,0,3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="X:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding SizeX, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<!-- Y尺寸 -->
<Grid Grid.Column="1" Margin="3,0,3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Y:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding SizeY, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<!-- Z尺寸 -->
<Grid Grid.Column="2" Margin="3,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Z:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding SizeZ, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
</Grid>
<!-- 中心点坐标 -->
<TextBlock Text="中心点坐标" FontWeight="SemiBold" FontSize="11" Foreground="#FF333333" Margin="0,0,0,6"/>
<Grid Margin="0,0,0,12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- X -->
<Grid Grid.Column="0" Margin="0,0,3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="X:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding CenterX, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<!-- Y -->
<Grid Grid.Column="1" Margin="3,0,3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Y:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding CenterY, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<!-- Z -->
<Grid Grid.Column="2" Margin="3,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Z:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding CenterZ, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
</Grid>
<!-- 顶面中心点 -->
<TextBlock Text="顶面中心点坐标" FontWeight="SemiBold" FontSize="11" Foreground="#FF333333" Margin="0,0,0,6"/>
<Grid Margin="0,0,0,12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- X -->
<Grid Grid.Column="0" Margin="0,0,3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="X:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding TopCenterX, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<!-- Y -->
<Grid Grid.Column="1" Margin="3,0,3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Y:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding TopCenterY, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<!-- Z -->
<Grid Grid.Column="2" Margin="3,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Z:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding TopCenterZ, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
</Grid>
<!-- 底面中心点 -->
<TextBlock Text="底面中心点坐标" FontWeight="SemiBold" FontSize="11" Foreground="#FF333333" Margin="0,0,0,6"/>
<Grid Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- X -->
<Grid Grid.Column="0" Margin="0,0,3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="X:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding BottomCenterX, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<!-- Y -->
<Grid Grid.Column="1" Margin="3,0,3,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Y:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding BottomCenterY, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<!-- Z -->
<Grid Grid.Column="2" Margin="3,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Z:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/>
<TextBox Grid.Column="1" Text="{Binding BottomCenterZ, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
</Grid>
</StackPanel>
</Border>
<!-- 按钮栏 -->
<Border Grid.Row="2" Background="#FFF8FBFF" BorderBrush="#FFD4E7FF" BorderThickness="0,1,0,0" Padding="20,12">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="刷新"
Click="OnRefreshClick"
Style="{StaticResource ActionButtonStyle}"
Width="90"
Height="32"
Margin="0,0,10,0"
ToolTip="刷新选中元素的包围盒信息"/>
<Button Content="关闭"
Click="OnCloseClick"
Style="{StaticResource SecondaryButtonStyle}"
Width="90"
Height="32"/>
</StackPanel>
</Border>
</Grid>
</Window>

View File

@ -0,0 +1,187 @@
using System;
using System.Windows;
using Autodesk.Navisworks.Api;
namespace NavisworksTransport.UI.WPF.Views
{
/// <summary>
/// 显示选中模型元素包围盒信息的窗口
/// </summary>
public partial class ModelItemBoundsWindow : Window
{
#region
/// <summary>元素名称</summary>
public string ElementName { get; set; } = "未选择元素";
/// <summary>X方向尺寸</summary>
public double SizeX { get; set; }
/// <summary>Y方向尺寸</summary>
public double SizeY { get; set; }
/// <summary>Z方向尺寸</summary>
public double SizeZ { get; set; }
/// <summary>中心点X坐标</summary>
public double CenterX { get; set; }
/// <summary>中心点Y坐标</summary>
public double CenterY { get; set; }
/// <summary>中心点Z坐标</summary>
public double CenterZ { get; set; }
/// <summary>顶面中心点X坐标</summary>
public double TopCenterX { get; set; }
/// <summary>顶面中心点Y坐标</summary>
public double TopCenterY { get; set; }
/// <summary>顶面中心点Z坐标</summary>
public double TopCenterZ { get; set; }
/// <summary>底面中心点X坐标</summary>
public double BottomCenterX { get; set; }
/// <summary>底面中心点Y坐标</summary>
public double BottomCenterY { get; set; }
/// <summary>底面中心点Z坐标</summary>
public double BottomCenterZ { get; set; }
#endregion
/// <summary>
/// 构造函数
/// </summary>
public ModelItemBoundsWindow()
{
try
{
InitializeComponent();
DataContext = this;
RefreshBoundsInfo();
}
catch (Exception ex)
{
LogManager.Error($"包围盒信息窗口初始化失败: {ex.Message}", ex);
MessageBox.Show($"包围盒信息窗口初始化失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 刷新包围盒信息
/// </summary>
public void RefreshBoundsInfo()
{
try
{
var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
if (doc == null)
{
ElementName = "未找到活动文档";
ClearBoundsData();
return;
}
var selectedItems = doc.CurrentSelection.SelectedItems;
if (selectedItems.Count == 0)
{
ElementName = "未选择任何元素";
ClearBoundsData();
return;
}
// 获取第一个选中的元素
var item = selectedItems[0];
if (item == null)
{
ElementName = "无法获取选中元素";
ClearBoundsData();
return;
}
// 获取元素名称
ElementName = item.DisplayName ?? "未命名元素";
// 获取包围盒
Autodesk.Navisworks.Api.BoundingBox3D bounds = item.BoundingBox();
if (bounds == null)
{
ElementName = "无法获取包围盒信息";
ClearBoundsData();
return;
}
// 计算尺寸
SizeX = bounds.Max.X - bounds.Min.X;
SizeY = bounds.Max.Y - bounds.Min.Y;
SizeZ = bounds.Max.Z - bounds.Min.Z;
// 计算中心点
CenterX = (bounds.Min.X + bounds.Max.X) / 2.0;
CenterY = (bounds.Min.Y + bounds.Max.Y) / 2.0;
CenterZ = (bounds.Min.Z + bounds.Max.Z) / 2.0;
// 计算顶面中心点Z最大
TopCenterX = CenterX;
TopCenterY = CenterY;
TopCenterZ = bounds.Max.Z;
// 计算底面中心点Z最小
BottomCenterX = CenterX;
BottomCenterY = CenterY;
BottomCenterZ = bounds.Min.Z;
}
catch (Exception ex)
{
LogManager.Error($"获取包围盒信息失败: {ex.Message}", ex);
ElementName = $"获取失败: {ex.Message}";
ClearBoundsData();
}
finally
{
// 通知UI更新
OnPropertyChanged();
}
}
/// <summary>
/// 清空包围盒数据
/// </summary>
private void ClearBoundsData()
{
SizeX = SizeY = SizeZ = 0;
CenterX = CenterY = CenterZ = 0;
TopCenterX = TopCenterY = TopCenterZ = 0;
BottomCenterX = BottomCenterY = BottomCenterZ = 0;
}
/// <summary>
/// 通知所有属性变更
/// </summary>
private void OnPropertyChanged()
{
// 重新设置 DataContext 触发刷新
DataContext = null;
DataContext = this;
}
/// <summary>
/// 刷新按钮点击
/// </summary>
private void OnRefreshClick(object sender, RoutedEventArgs e)
{
RefreshBoundsInfo();
}
/// <summary>
/// 关闭按钮点击
/// </summary>
private void OnCloseClick(object sender, RoutedEventArgs e)
{
Close();
}
}
}

View File

@ -292,6 +292,24 @@ NavisworksTransport 路径编辑页签视图 - 采用与动画控制和分层管
Foreground="#FF2B579A"
Margin="0,5,0,0"/>
<!-- 路径点列表标题栏和工具按钮 -->
<Grid Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="路径点列表" VerticalAlignment="Center" FontSize="11" Foreground="#FF666666"/>
<Button Grid.Column="1"
Content="🎯"
FontSize="14"
ToolTip="查看选中模型元素的包围盒信息"
Click="OnMeasureBoundsButtonClick"
Style="{StaticResource SecondaryButtonStyle}"
Width="28"
Height="24"
Padding="2"/>
</Grid>
<!-- 路径点列表 -->
<ListView ItemsSource="{Binding SelectedPathRoute.Points}"
SelectedItem="{Binding SelectedPathPoint}"

View File

@ -3,6 +3,7 @@ using System.Drawing.Imaging;
using System.Windows;
using System.Windows.Controls;
using NavisworksTransport.UI.WPF.ViewModels;
using NavisworksTransport.UI.WPF.Views;
namespace NavisworksTransport.UI.WPF.Views
{
@ -249,5 +250,62 @@ namespace NavisworksTransport.UI.WPF.Views
if (format.Equals(ImageFormat.Bmp)) return "bmp";
return "png";
}
/// <summary>
/// 测量包围盒按钮点击事件,打开元素包围盒信息窗口
/// </summary>
private void OnMeasureBoundsButtonClick(object sender, RoutedEventArgs e)
{
try
{
LogManager.Info("测量包围盒按钮被点击准备打开ModelItemBoundsWindow窗口");
// 创建或复用窗口实例
if (_boundsWindow == null || !_boundsWindow.IsVisible)
{
_boundsWindow = new ModelItemBoundsWindow();
// 在Navisworks环境中尝试找到合适的父窗口
try
{
var parentWindow = Window.GetWindow(this);
if (parentWindow != null)
{
_boundsWindow.Owner = parentWindow;
LogManager.Info("设置ModelItemBoundsWindow的Owner为当前窗口");
}
else
{
LogManager.Info("未找到父窗口将以独立窗口方式显示ModelItemBoundsWindow");
}
}
catch (Exception ownerEx)
{
LogManager.Warning($"设置Owner失败将以独立窗口显示: {ownerEx.Message}");
}
// 使用 Show() 而非 ShowDialog(),允许窗口一直开着
_boundsWindow.Show();
LogManager.Info("ModelItemBoundsWindow窗口已显示非模态");
}
else
{
// 窗口已存在,刷新信息并激活
_boundsWindow.RefreshBoundsInfo();
_boundsWindow.Activate();
LogManager.Info("ModelItemBoundsWindow窗口已存在已刷新并激活");
}
}
catch (Exception ex)
{
LogManager.Error($"打开包围盒信息窗口失败: {ex.Message}");
LogManager.Error($"异常详情: {ex}");
}
}
/// <summary>
/// 包围盒信息窗口实例保持引用以防止被GC回收
/// </summary>
private ModelItemBoundsWindow _boundsWindow;
}
}