Stabilize hoisting pose flow and bounds inspection

This commit is contained in:
tian 2026-04-01 23:53:11 +08:00
parent e71ea81cdf
commit 953306fdb1
4 changed files with 270 additions and 55 deletions

View File

@ -1,6 +1,7 @@
using Autodesk.Navisworks.Api; using Autodesk.Navisworks.Api;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using NavisworksTransport.Core.Animation; using NavisworksTransport.Core.Animation;
using NavisworksTransport.Utils.CoordinateSystem;
namespace NavisworksTransport.UnitTests.CoordinateSystem namespace NavisworksTransport.UnitTests.CoordinateSystem
{ {
@ -42,5 +43,49 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
Assert.AreEqual(fallbackRotation.C, resolved.C, 1e-9); Assert.AreEqual(fallbackRotation.C, resolved.C, 1e-9);
Assert.AreEqual(fallbackRotation.D, resolved.D, 1e-9); Assert.AreEqual(fallbackRotation.D, resolved.D, 1e-9);
} }
[TestMethod]
public void ShouldPreservePathRotationForFrames_ShouldEnableHoistingWhenTranslationModeHasLockedRotation()
{
bool shouldPreserve = PathAnimationManager.ShouldPreservePathRotationForFrames(
PathType.Hoisting,
ObjectStartPlacementMode.PreserveInitialPose,
hasPreservedRotation: true);
Assert.IsTrue(shouldPreserve);
}
[TestMethod]
public void ShouldPreservePathRotationForFrames_ShouldEnableRailWhenTranslationModeHasLockedRotation()
{
bool shouldPreserve = PathAnimationManager.ShouldPreservePathRotationForFrames(
PathType.Rail,
ObjectStartPlacementMode.PreserveInitialPose,
hasPreservedRotation: true);
Assert.IsTrue(shouldPreserve);
}
[TestMethod]
public void ShouldPreservePathRotationForFrames_ShouldDisableGroundEvenInTranslationMode()
{
bool shouldPreserve = PathAnimationManager.ShouldPreservePathRotationForFrames(
PathType.Ground,
ObjectStartPlacementMode.PreserveInitialPose,
hasPreservedRotation: true);
Assert.IsFalse(shouldPreserve);
}
[TestMethod]
public void ShouldPreservePathRotationForFrames_ShouldDisableWhenLockedRotationMissing()
{
bool shouldPreserve = PathAnimationManager.ShouldPreservePathRotationForFrames(
PathType.Hoisting,
ObjectStartPlacementMode.PreserveInitialPose,
hasPreservedRotation: false);
Assert.IsFalse(shouldPreserve);
}
} }
} }

View File

@ -218,8 +218,8 @@ namespace NavisworksTransport.Core.Animation
private bool _savedObjectHasCustomRotation = false; private bool _savedObjectHasCustomRotation = false;
private bool _hasSavedObjectState = false; private bool _hasSavedObjectState = false;
private ObjectStartPlacementMode _objectStartPlacementMode = ObjectStartPlacementMode.AlignToPathPose; private ObjectStartPlacementMode _objectStartPlacementMode = ObjectStartPlacementMode.AlignToPathPose;
private Rotation3D _railPreservedPoseRotation = Rotation3D.Identity; private Rotation3D _pathPreservedPoseRotation = Rotation3D.Identity;
private bool _hasRailPreservedPoseRotation = false; private bool _hasPathPreservedPoseRotation = false;
private bool IsVirtualObjectMode => _animatedObjectMode == AnimatedObjectMode.VirtualObject; private bool IsVirtualObjectMode => _animatedObjectMode == AnimatedObjectMode.VirtualObject;
private bool IsRealObjectMode => _animatedObjectMode == AnimatedObjectMode.RealObject; private bool IsRealObjectMode => _animatedObjectMode == AnimatedObjectMode.RealObject;
@ -1022,18 +1022,19 @@ namespace NavisworksTransport.Core.Animation
{ {
var pathPoints = _route.Points.Select(p => p.Position).ToList(); var pathPoints = _route.Points.Select(p => p.Position).ToList();
MoveObjectToPathStartUsingCurrentPlacementMode(_animatedObject, pathPoints); MoveObjectToPathStartUsingCurrentPlacementMode(_animatedObject, pathPoints);
if (_route.PathType == PathType.Rail && if (ShouldPreservePathRotationForFrames(
_objectStartPlacementMode == ObjectStartPlacementMode.PreserveInitialPose && _route.PathType,
_hasTrackedRotation) _objectStartPlacementMode,
_hasTrackedRotation))
{ {
_railPreservedPoseRotation = _trackedRotation; _pathPreservedPoseRotation = _trackedRotation;
_hasRailPreservedPoseRotation = true; _hasPathPreservedPoseRotation = true;
LogManager.Info("[预计算] Rail平移模式已锁定起点姿态为整段动画旋转基线"); LogManager.Info($"[预计算] {_route.PathType.GetDisplayName()}平移模式已锁定起点姿态为整段动画旋转基线");
} }
else else
{ {
_railPreservedPoseRotation = Rotation3D.Identity; _pathPreservedPoseRotation = Rotation3D.Identity;
_hasRailPreservedPoseRotation = false; _hasPathPreservedPoseRotation = false;
} }
LogManager.Info("[预计算] 物体已移动到路径起点"); LogManager.Info("[预计算] 物体已移动到路径起点");
} }
@ -1340,11 +1341,12 @@ namespace NavisworksTransport.Core.Animation
Collisions = new List<CollisionResult>() Collisions = new List<CollisionResult>()
}; };
if (_route.PathType == PathType.Rail && if (ShouldPreservePathRotationForFrames(
_objectStartPlacementMode == ObjectStartPlacementMode.PreserveInitialPose && _route.PathType,
_hasRailPreservedPoseRotation) _objectStartPlacementMode,
_hasPathPreservedPoseRotation))
{ {
frame.Rotation = _railPreservedPoseRotation; frame.Rotation = _pathPreservedPoseRotation;
frame.HasCustomRotation = true; frame.HasCustomRotation = true;
} }
else if (_route.PathType == PathType.Rail && else if (_route.PathType == PathType.Rail &&
@ -3972,6 +3974,19 @@ namespace NavisworksTransport.Core.Animation
: fallbackRotation; : fallbackRotation;
} }
internal static bool ShouldPreservePathRotationForFrames(
PathType pathType,
ObjectStartPlacementMode placementMode,
bool hasPreservedRotation)
{
if (!hasPreservedRotation || placementMode != ObjectStartPlacementMode.PreserveInitialPose)
{
return false;
}
return pathType == PathType.Rail || pathType == PathType.Hoisting;
}
private void SyncTrackedRotationToDisplayedPose(ModelItem sourceObject) private void SyncTrackedRotationToDisplayedPose(ModelItem sourceObject)
{ {
if (sourceObject == null) if (sourceObject == null)
@ -5181,7 +5196,7 @@ namespace NavisworksTransport.Core.Animation
public void SetObjectRotationCorrection(LocalEulerRotationCorrection rotationCorrection) public void SetObjectRotationCorrection(LocalEulerRotationCorrection rotationCorrection)
{ {
_objectStartPlacementMode = ObjectStartPlacementMode.AlignToPathPose; _objectStartPlacementMode = ObjectStartPlacementMode.AlignToPathPose;
_hasRailPreservedPoseRotation = false; _hasPathPreservedPoseRotation = false;
_objectRotationCorrection = rotationCorrection; _objectRotationCorrection = rotationCorrection;
ResetPlanarRealObjectBasePoseCache(); ResetPlanarRealObjectBasePoseCache();
@ -5224,7 +5239,7 @@ namespace NavisworksTransport.Core.Animation
_objectStartPlacementMode = placementMode; _objectStartPlacementMode = placementMode;
if (placementMode != ObjectStartPlacementMode.PreserveInitialPose) if (placementMode != ObjectStartPlacementMode.PreserveInitialPose)
{ {
_hasRailPreservedPoseRotation = false; _hasPathPreservedPoseRotation = false;
} }
LogManager.Debug($"[起点摆放] 当前模式已设置为: {_objectStartPlacementMode}"); LogManager.Debug($"[起点摆放] 当前模式已设置为: {_objectStartPlacementMode}");
} }

View File

@ -1,7 +1,7 @@
<Window x:Class="NavisworksTransport.UI.WPF.Views.ModelItemBoundsWindow" <Window x:Class="NavisworksTransport.UI.WPF.Views.ModelItemBoundsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="元素包围盒信息" Height="460" Width="420" Title="元素包围盒信息" Height="640" Width="440"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
ResizeMode="CanResize" ResizeMode="CanResize"
ShowInTaskbar="True" ShowInTaskbar="True"
@ -26,7 +26,7 @@
<Border Grid.Row="0" Background="#FFF8FBFF" BorderBrush="#FFD4E7FF" BorderThickness="0,0,0,1" Padding="20,12"> <Border Grid.Row="0" Background="#FFF8FBFF" BorderBrush="#FFD4E7FF" BorderThickness="0,0,0,1" Padding="20,12">
<StackPanel> <StackPanel>
<TextBlock Text="元素包围盒信息" FontWeight="SemiBold" FontSize="14" Foreground="#FF2B579A"/> <TextBlock Text="元素包围盒信息" FontWeight="SemiBold" FontSize="14" Foreground="#FF2B579A"/>
<TextBlock Text="当前选中模型元素的包围盒信息(单位:模型单位)" FontSize="10" Foreground="#FF666666" Margin="0,3,0,0"/> <TextBlock Text="同时显示宿主包围盒顶/底中心与对象姿态语义顶/底中心(单位:模型单位)" FontSize="10" Foreground="#FF666666" Margin="0,3,0,0"/>
</StackPanel> </StackPanel>
</Border> </Border>
@ -138,8 +138,8 @@
</Button> </Button>
</Grid> </Grid>
<!-- 顶面中心点 --> <!-- 宿主包围盒顶面中心点 -->
<TextBlock Text="顶面中心点坐标" FontWeight="SemiBold" FontSize="11" Foreground="#FF333333" Margin="0,0,0,6"/> <TextBlock Text="宿主包围盒顶面中心点坐标" FontWeight="SemiBold" FontSize="11" Foreground="#FF333333" Margin="0,0,0,6"/>
<Grid Margin="0,0,0,12"> <Grid Margin="0,0,0,12">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
@ -155,7 +155,7 @@
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="X:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/> <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"/> <TextBox Grid.Column="1" Text="{Binding HostTopCenterX, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid> </Grid>
<!-- Y --> <!-- Y -->
@ -165,7 +165,7 @@
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Y:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/> <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"/> <TextBox Grid.Column="1" Text="{Binding HostTopCenterY, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid> </Grid>
<!-- Z --> <!-- Z -->
@ -175,7 +175,7 @@
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Z:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/> <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"/> <TextBox Grid.Column="1" Text="{Binding HostTopCenterZ, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid> </Grid>
<!-- 复制按钮 --> <!-- 复制按钮 -->
@ -183,7 +183,7 @@
x:Name="CopyTopButton" x:Name="CopyTopButton"
Style="{StaticResource IconButtonStyle}" Style="{StaticResource IconButtonStyle}"
Click="OnCopyTopCenterClick" Click="OnCopyTopCenterClick"
ToolTip="复制顶面中心点坐标" ToolTip="复制宿主包围盒顶面中心点坐标"
Margin="3,0,0,0"> Margin="3,0,0,0">
<Path Data="{StaticResource CopyIconGeometry}" <Path Data="{StaticResource CopyIconGeometry}"
Fill="{StaticResource NavisworksPrimaryBrush}" Fill="{StaticResource NavisworksPrimaryBrush}"
@ -191,9 +191,9 @@
</Button> </Button>
</Grid> </Grid>
<!-- 底面中心点 --> <!-- 宿主包围盒底面中心点 -->
<TextBlock Text="底面中心点坐标" FontWeight="SemiBold" FontSize="11" Foreground="#FF333333" Margin="0,0,0,6"/> <TextBlock Text="宿主包围盒底面中心点坐标" FontWeight="SemiBold" FontSize="11" Foreground="#FF333333" Margin="0,0,0,6"/>
<Grid Margin="0,0,0,0"> <Grid Margin="0,0,0,12">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
@ -208,7 +208,7 @@
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="X:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/> <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"/> <TextBox Grid.Column="1" Text="{Binding HostBottomCenterX, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid> </Grid>
<!-- Y --> <!-- Y -->
@ -218,7 +218,7 @@
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Y:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/> <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"/> <TextBox Grid.Column="1" Text="{Binding HostBottomCenterY, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid> </Grid>
<!-- Z --> <!-- Z -->
@ -228,7 +228,7 @@
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Z:" FontSize="11" Foreground="#FF666666" VerticalAlignment="Center" Margin="0,0,3,0"/> <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"/> <TextBox Grid.Column="1" Text="{Binding HostBottomCenterZ, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid> </Grid>
<!-- 复制按钮 --> <!-- 复制按钮 -->
@ -236,7 +236,105 @@
x:Name="CopyBottomButton" x:Name="CopyBottomButton"
Style="{StaticResource IconButtonStyle}" Style="{StaticResource IconButtonStyle}"
Click="OnCopyBottomCenterClick" Click="OnCopyBottomCenterClick"
ToolTip="复制底面中心点坐标" ToolTip="复制宿主包围盒底面中心点坐标"
Margin="3,0,0,0">
<Path Data="{StaticResource CopyIconGeometry}"
Fill="{StaticResource NavisworksPrimaryBrush}"
Width="14" Height="14" Stretch="Uniform"/>
</Button>
</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="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<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 OrientedTopCenterX, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<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 OrientedTopCenterY, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<Grid Grid.Column="2" Margin="3,0,3,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 OrientedTopCenterZ, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<Button Grid.Column="3"
x:Name="CopyOrientedTopButton"
Style="{StaticResource IconButtonStyle}"
Click="OnCopyOrientedTopCenterClick"
ToolTip="复制对象姿态语义顶面中心点坐标"
Margin="3,0,0,0">
<Path Data="{StaticResource CopyIconGeometry}"
Fill="{StaticResource NavisworksPrimaryBrush}"
Width="14" Height="14" Stretch="Uniform"/>
</Button>
</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="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<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 OrientedBottomCenterX, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<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 OrientedBottomCenterY, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<Grid Grid.Column="2" Margin="3,0,3,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 OrientedBottomCenterZ, StringFormat=0.000}" FontSize="11" IsReadOnly="True" Padding="4,2"/>
</Grid>
<Button Grid.Column="3"
x:Name="CopyOrientedBottomButton"
Style="{StaticResource IconButtonStyle}"
Click="OnCopyOrientedBottomCenterClick"
ToolTip="复制对象姿态语义底面中心点坐标"
Margin="3,0,0,0"> Margin="3,0,0,0">
<Path Data="{StaticResource CopyIconGeometry}" <Path Data="{StaticResource CopyIconGeometry}"
Fill="{StaticResource NavisworksPrimaryBrush}" Fill="{StaticResource NavisworksPrimaryBrush}"

View File

@ -4,6 +4,8 @@ using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading; using System.Windows.Threading;
using Autodesk.Navisworks.Api; using Autodesk.Navisworks.Api;
using NavisworksTransport.Utils;
using NavisworksTransport.Utils.CoordinateSystem;
namespace NavisworksTransport.UI.WPF.Views namespace NavisworksTransport.UI.WPF.Views
{ {
@ -35,23 +37,41 @@ namespace NavisworksTransport.UI.WPF.Views
/// <summary>中心点Z坐标</summary> /// <summary>中心点Z坐标</summary>
public double CenterZ { get; set; } public double CenterZ { get; set; }
/// <summary>顶面中心点X坐标</summary> /// <summary>宿主包围盒顶面中心点X坐标</summary>
public double TopCenterX { get; set; } public double HostTopCenterX { get; set; }
/// <summary>顶面中心点Y坐标</summary> /// <summary>宿主包围盒顶面中心点Y坐标</summary>
public double TopCenterY { get; set; } public double HostTopCenterY { get; set; }
/// <summary>顶面中心点Z坐标</summary> /// <summary>宿主包围盒顶面中心点Z坐标</summary>
public double TopCenterZ { get; set; } public double HostTopCenterZ { get; set; }
/// <summary>底面中心点X坐标</summary> /// <summary>宿主包围盒底面中心点X坐标</summary>
public double BottomCenterX { get; set; } public double HostBottomCenterX { get; set; }
/// <summary>底面中心点Y坐标</summary> /// <summary>宿主包围盒底面中心点Y坐标</summary>
public double BottomCenterY { get; set; } public double HostBottomCenterY { get; set; }
/// <summary>底面中心点Z坐标</summary> /// <summary>宿主包围盒底面中心点Z坐标</summary>
public double BottomCenterZ { get; set; } public double HostBottomCenterZ { get; set; }
/// <summary>对象姿态语义顶面中心点X坐标</summary>
public double OrientedTopCenterX { get; set; }
/// <summary>对象姿态语义顶面中心点Y坐标</summary>
public double OrientedTopCenterY { get; set; }
/// <summary>对象姿态语义顶面中心点Z坐标</summary>
public double OrientedTopCenterZ { get; set; }
/// <summary>对象姿态语义底面中心点X坐标</summary>
public double OrientedBottomCenterX { get; set; }
/// <summary>对象姿态语义底面中心点Y坐标</summary>
public double OrientedBottomCenterY { get; set; }
/// <summary>对象姿态语义底面中心点Z坐标</summary>
public double OrientedBottomCenterZ { get; set; }
#endregion #endregion
@ -127,15 +147,36 @@ namespace NavisworksTransport.UI.WPF.Views
CenterY = (bounds.Min.Y + bounds.Max.Y) / 2.0; CenterY = (bounds.Min.Y + bounds.Max.Y) / 2.0;
CenterZ = (bounds.Min.Z + bounds.Max.Z) / 2.0; CenterZ = (bounds.Min.Z + bounds.Max.Z) / 2.0;
// 计算顶面中心点Z最大 HostCoordinateAdapter adapter = CoordinateSystemManager.Instance.CreateHostAdapter();
TopCenterX = CenterX;
TopCenterY = CenterY;
TopCenterZ = bounds.Max.Z;
// 计算底面中心点Z最小 Point3D hostBottomCenter = ModelItemTransformHelper.GetHostBottomAnchorPoint(bounds, adapter);
BottomCenterX = CenterX; double hostHeight = ModelItemTransformHelper.GetHostHeight(bounds, adapter);
BottomCenterY = CenterY; Point3D hostTopCenter = new Point3D(
BottomCenterZ = bounds.Min.Z; hostBottomCenter.X + adapter.HostUpVector.X * hostHeight,
hostBottomCenter.Y + adapter.HostUpVector.Y * hostHeight,
hostBottomCenter.Z + adapter.HostUpVector.Z * hostHeight);
HostBottomCenterX = hostBottomCenter.X;
HostBottomCenterY = hostBottomCenter.Y;
HostBottomCenterZ = hostBottomCenter.Z;
HostTopCenterX = hostTopCenter.X;
HostTopCenterY = hostTopCenter.Y;
HostTopCenterZ = hostTopCenter.Z;
Point3D orientedBottomCenter = ModelItemTransformHelper.GetStableBottomAnchorPoint(bounds, item.Transform);
Vector3D objectUp = ModelItemTransformHelper.GetUpDirectionFromTransform(item.Transform);
Vector3D localSize = ModelItemTransformHelper.EstimateLocalBoxSize(bounds, item.Transform);
Point3D orientedTopCenter = new Point3D(
orientedBottomCenter.X + objectUp.X * localSize.Z,
orientedBottomCenter.Y + objectUp.Y * localSize.Z,
orientedBottomCenter.Z + objectUp.Z * localSize.Z);
OrientedBottomCenterX = orientedBottomCenter.X;
OrientedBottomCenterY = orientedBottomCenter.Y;
OrientedBottomCenterZ = orientedBottomCenter.Z;
OrientedTopCenterX = orientedTopCenter.X;
OrientedTopCenterY = orientedTopCenter.Y;
OrientedTopCenterZ = orientedTopCenter.Z;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -157,8 +198,10 @@ namespace NavisworksTransport.UI.WPF.Views
{ {
SizeX = SizeY = SizeZ = 0; SizeX = SizeY = SizeZ = 0;
CenterX = CenterY = CenterZ = 0; CenterX = CenterY = CenterZ = 0;
TopCenterX = TopCenterY = TopCenterZ = 0; HostTopCenterX = HostTopCenterY = HostTopCenterZ = 0;
BottomCenterX = BottomCenterY = BottomCenterZ = 0; HostBottomCenterX = HostBottomCenterY = HostBottomCenterZ = 0;
OrientedTopCenterX = OrientedTopCenterY = OrientedTopCenterZ = 0;
OrientedBottomCenterX = OrientedBottomCenterY = OrientedBottomCenterZ = 0;
} }
/// <summary> /// <summary>
@ -202,7 +245,7 @@ namespace NavisworksTransport.UI.WPF.Views
/// </summary> /// </summary>
private void OnCopyTopCenterClick(object sender, RoutedEventArgs e) private void OnCopyTopCenterClick(object sender, RoutedEventArgs e)
{ {
string coordinate = string.Format("{0:0.000}, {1:0.000}, {2:0.000}", TopCenterX, TopCenterY, TopCenterZ); string coordinate = string.Format("{0:0.000}, {1:0.000}, {2:0.000}", HostTopCenterX, HostTopCenterY, HostTopCenterZ);
bool success = ClipboardHelper.TrySetText(coordinate, "元素包围盒信息"); bool success = ClipboardHelper.TrySetText(coordinate, "元素包围盒信息");
ShowButtonFeedback(CopyTopButton, success); ShowButtonFeedback(CopyTopButton, success);
} }
@ -212,11 +255,25 @@ namespace NavisworksTransport.UI.WPF.Views
/// </summary> /// </summary>
private void OnCopyBottomCenterClick(object sender, RoutedEventArgs e) private void OnCopyBottomCenterClick(object sender, RoutedEventArgs e)
{ {
string coordinate = string.Format("{0:0.000}, {1:0.000}, {2:0.000}", BottomCenterX, BottomCenterY, BottomCenterZ); string coordinate = string.Format("{0:0.000}, {1:0.000}, {2:0.000}", HostBottomCenterX, HostBottomCenterY, HostBottomCenterZ);
bool success = ClipboardHelper.TrySetText(coordinate, "元素包围盒信息"); bool success = ClipboardHelper.TrySetText(coordinate, "元素包围盒信息");
ShowButtonFeedback(CopyBottomButton, success); ShowButtonFeedback(CopyBottomButton, success);
} }
private void OnCopyOrientedTopCenterClick(object sender, RoutedEventArgs e)
{
string coordinate = string.Format("{0:0.000}, {1:0.000}, {2:0.000}", OrientedTopCenterX, OrientedTopCenterY, OrientedTopCenterZ);
bool success = ClipboardHelper.TrySetText(coordinate, "元素包围盒信息");
ShowButtonFeedback(CopyOrientedTopButton, success);
}
private void OnCopyOrientedBottomCenterClick(object sender, RoutedEventArgs e)
{
string coordinate = string.Format("{0:0.000}, {1:0.000}, {2:0.000}", OrientedBottomCenterX, OrientedBottomCenterY, OrientedBottomCenterZ);
bool success = ClipboardHelper.TrySetText(coordinate, "元素包围盒信息");
ShowButtonFeedback(CopyOrientedBottomButton, success);
}
/// <summary> /// <summary>
/// 显示按钮点击反馈 /// 显示按钮点击反馈
/// </summary> /// </summary>