add ground object lift adjustment

This commit is contained in:
tian 2026-04-09 23:53:40 +08:00
parent 6020bfa979
commit da5f8a1ae1
11 changed files with 291 additions and 34 deletions

View File

@ -64,6 +64,8 @@
<Compile Include="UnitTests\CoordinateSystem\ObjectStartPlacementRequestTests.cs" />
<Compile Include="UnitTests\CoordinateSystem\CanonicalRailOffsetResolverTests.cs" />
<Compile Include="UnitTests\CoordinateSystem\CanonicalTrackedPositionResolverTests.cs" />
<Compile Include="UnitTests\CoordinateSystem\GroundPathObjectLiftOffsetTests.cs" />
<Compile Include="UnitTests\CoordinateSystem\GroundPassageSpaceOffsetTests.cs" />
<Compile Include="UnitTests\CoordinateSystem\FragmentRepresentativePoseHelperTests.cs" />
<Compile Include="UnitTests\CoordinateSystem\HoistingCoordinateHelperTests.cs" />
<Compile Include="UnitTests\CoordinateSystem\HoistingRealObjectPoseHelperTests.cs" />

View File

@ -0,0 +1,17 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NavisworksTransport.Core;
namespace NavisworksTransport.UnitTests.CoordinateSystem
{
[TestClass]
public class GroundPassageSpaceOffsetTests
{
[TestMethod]
public void GroundPassageSpaceVerticalOffset_ShouldStayAtHalfHeight_WhenHeightAlreadyIncludesLift()
{
double verticalOffset = PathPointRenderPlugin.ResolveGroundPathObjectSpaceVerticalOffset(5.7);
Assert.AreEqual(2.85, verticalOffset, 1e-9);
}
}
}

View File

@ -0,0 +1,42 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NavisworksTransport.Core.Animation;
using NavisworksTransport.Utils.CoordinateSystem;
using System.Numerics;
namespace NavisworksTransport.UnitTests.CoordinateSystem
{
[TestClass]
public class GroundPathObjectLiftOffsetTests
{
[TestMethod]
public void YUp_GroundPathLift_ShouldOffsetAlongHostY()
{
Vector3 offset = PathAnimationManager.ResolveGroundPathObjectLiftOffsetVector(1.25, CoordinateSystemType.YUp);
AssertVector(offset, 0.0, 1.25, 0.0);
}
[TestMethod]
public void ZUp_GroundPathLift_ShouldOffsetAlongHostZ()
{
Vector3 offset = PathAnimationManager.ResolveGroundPathObjectLiftOffsetVector(1.25, CoordinateSystemType.ZUp);
AssertVector(offset, 0.0, 0.0, 1.25);
}
[TestMethod]
public void GroundPathLift_ShouldReturnZero_WhenLiftIsNotPositive()
{
Vector3 offset = PathAnimationManager.ResolveGroundPathObjectLiftOffsetVector(0.0, CoordinateSystemType.ZUp);
AssertVector(offset, 0.0, 0.0, 0.0);
}
private static void AssertVector(Vector3 actual, double x, double y, double z, double tolerance = 1e-6)
{
Assert.AreEqual(x, actual.X, tolerance);
Assert.AreEqual(y, actual.Y, tolerance);
Assert.AreEqual(z, actual.Z, tolerance);
}
}
}

View File

@ -14,6 +14,7 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
Assert.AreEqual(ObjectStartPlacementMode.PreserveInitialPose, request.PlacementMode);
Assert.IsTrue(request.PreserveInitialPose);
Assert.AreEqual(LocalEulerRotationCorrection.Zero, request.RotationCorrection);
Assert.AreEqual(0.0, request.VerticalLiftInMeters, 1e-9);
}
[TestMethod]
@ -21,11 +22,23 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
{
var correction = new LocalEulerRotationCorrection(15.0, 30.0, 45.0);
var request = ObjectStartPlacementRequest.CreateRotationCorrection(correction);
var request = ObjectStartPlacementRequest.CreateRotationCorrection(correction, 0.35);
Assert.AreEqual(ObjectStartPlacementMode.AlignToPathPose, request.PlacementMode);
Assert.IsFalse(request.PreserveInitialPose);
Assert.AreEqual(correction, request.RotationCorrection);
Assert.AreEqual(0.35, request.VerticalLiftInMeters, 1e-9);
}
[TestMethod]
public void TranslationOnlyRequest_ShouldKeepVerticalLift()
{
var request = ObjectStartPlacementRequest.CreateTranslationOnly(0.28);
Assert.AreEqual(ObjectStartPlacementMode.PreserveInitialPose, request.PlacementMode);
Assert.IsTrue(request.PreserveInitialPose);
Assert.AreEqual(LocalEulerRotationCorrection.Zero, request.RotationCorrection);
Assert.AreEqual(0.28, request.VerticalLiftInMeters, 1e-9);
}
}
}

View File

@ -133,6 +133,7 @@ namespace NavisworksTransport.Core.Animation
// === 角度修正 ===
private LocalEulerRotationCorrection _objectRotationCorrection = LocalEulerRotationCorrection.Zero; // 物体绕宿主 X/Y/Z 轴的角度修正
private double _groundPathObjectLiftHeight; // 地面路径物体额外提升高度(模型单位)
// === 碰撞排除列表缓存管理从LogisticsAnimationManager迁移===
private ModelItem _currentCachedAnimationObject;
@ -767,6 +768,7 @@ namespace NavisworksTransport.Core.Animation
{
// 地面路径:路径点在接触面上,动画跟踪点统一使用几何中心
startPosition = ResolveGroundTrackedCenter(startPosition, GetAnimatedObjectGroundContactHeight());
startPosition = ApplyGroundPathObjectLiftOffset(startPosition);
LogManager.Debug($"[移动到起点] 地面路径中心点=({startPosition.X:F2},{startPosition.Y:F2},{startPosition.Z:F2})");
}
@ -970,6 +972,7 @@ namespace NavisworksTransport.Core.Animation
else
{
startPosition = ResolveGroundTrackedCenter(startPosition, GetAnimatedObjectGroundContactHeight());
startPosition = ApplyGroundPathObjectLiftOffset(startPosition);
}
UpdateObjectPosition(startPosition);
@ -1293,10 +1296,13 @@ namespace NavisworksTransport.Core.Animation
}
framePosition = ResolveGroundTrackedCenter(framePosition, GetAnimatedObjectGroundContactHeight());
framePosition = ApplyGroundPathObjectLiftOffset(framePosition);
yawRadians = ComputeYawOnPath(i, allSampledPoints, edgeIndex, edgeProgress);
previousFramePoint = ResolveGroundTrackedCenter(sampledPreviousPoint, GetAnimatedObjectGroundContactHeight());
nextFramePoint = ResolveGroundTrackedCenter(sampledNextPoint, GetAnimatedObjectGroundContactHeight());
previousFramePoint = ApplyGroundPathObjectLiftOffset(
ResolveGroundTrackedCenter(sampledPreviousPoint, GetAnimatedObjectGroundContactHeight()));
nextFramePoint = ApplyGroundPathObjectLiftOffset(
ResolveGroundTrackedCenter(sampledNextPoint, GetAnimatedObjectGroundContactHeight()));
if ((_route.PathType == PathType.Ground || _route.PathType == PathType.Hoisting) &&
i > 0 &&
@ -5461,6 +5467,34 @@ namespace NavisworksTransport.Core.Animation
}
}
public void ApplyObjectStartPlacementRequest(ObjectStartPlacementRequest request)
{
_objectStartPlacementMode = request.PlacementMode;
if (_objectStartPlacementMode != ObjectStartPlacementMode.PreserveInitialPose)
{
_hasPathPreservedPoseRotation = false;
}
_objectRotationCorrection = request.RotationCorrection;
_groundPathObjectLiftHeight = UnitsConverter.ConvertFromMeters(request.VerticalLiftInMeters);
LogManager.Info(
$"[起点摆放] 已应用物体调整请求: 模式={_objectStartPlacementMode}, 角度={_objectRotationCorrection}, " +
$"提升高度={request.VerticalLiftInMeters:F3}m");
if (_animatedObject != null && _pathPoints != null && _pathPoints.Count > 0)
{
try
{
MoveObjectToPathStartUsingCurrentPlacementMode();
}
catch (Exception ex)
{
LogManager.Error($"[起点摆放] 应用物体调整请求失败: {ex.Message}");
}
}
}
/// <summary>
/// 保留给旧单轴调用方:按当前宿主 up 轴映射成三轴角度修正。
/// </summary>
@ -5479,6 +5513,12 @@ namespace NavisworksTransport.Core.Animation
LogManager.Debug($"[角度修正] 直接设置角度修正值: {_objectRotationCorrection}(不触发旋转)");
}
public void SetObjectStartVerticalLiftDirect(double verticalLiftInMeters)
{
_groundPathObjectLiftHeight = UnitsConverter.ConvertFromMeters(verticalLiftInMeters);
LogManager.Debug($"[起点摆放] 直接设置地面路径提升高度: {verticalLiftInMeters:F3}m");
}
public void SetObjectStartPlacementMode(ObjectStartPlacementMode placementMode)
{
_objectStartPlacementMode = placementMode;
@ -5512,6 +5552,36 @@ namespace NavisworksTransport.Core.Animation
: new LocalEulerRotationCorrection(0.0, 0.0, rotationCorrection);
}
internal static Vector3 ResolveGroundPathObjectLiftOffsetVector(
double verticalLiftModelUnits,
CoordinateSystemType hostType)
{
if (verticalLiftModelUnits <= 0.0)
{
return Vector3.Zero;
}
var adapter = new HostCoordinateAdapter(hostType);
return Vector3.Normalize(adapter.HostUpVector3) * (float)verticalLiftModelUnits;
}
private Point3D ApplyGroundPathObjectLiftOffset(Point3D trackedCenter)
{
if (_route == null || _route.PathType != PathType.Ground || _groundPathObjectLiftHeight <= 0.0)
{
return trackedCenter;
}
Vector3 offset = ResolveGroundPathObjectLiftOffsetVector(
_groundPathObjectLiftHeight,
CoordinateSystemManager.Instance.ResolvedType);
return new Point3D(
trackedCenter.X + offset.X,
trackedCenter.Y + offset.Y,
trackedCenter.Z + offset.Z);
}
#region
/// <summary>

View File

@ -1594,7 +1594,7 @@ namespace NavisworksTransport
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Ground)
{
// 地面路径:路径点是地面位置,通行空间底面在地面,中心需要向上偏移半个高度
verticalOffset = height / 2.0;
verticalOffset = ResolveGroundPathObjectSpaceVerticalOffset(height);
}
else if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Rail)
{
@ -2314,7 +2314,12 @@ namespace NavisworksTransport
/// <param name="passageAlongPath">沿路径方向的通行空间尺寸(模型单位)</param>
/// <param name="passageNormalToPathVertical">垂直段的高度(物体长度 + 2×安全间隙模型单位</param>
/// <param name="passageNormalToPathHorizontal">水平段的高度(物体高度 + 2×安全间隙模型单位</param>
public void SetPassageSpaceParameters(double passageAcrossPath, double passageNormalToPath, double passageAlongPath, double passageNormalToPathVertical, double passageNormalToPathHorizontal)
public void SetPassageSpaceParameters(
double passageAcrossPath,
double passageNormalToPath,
double passageAlongPath,
double passageNormalToPathVertical,
double passageNormalToPathHorizontal)
{
// 直接存储模型单位(调用方已转换)
_passageAlongPath = passageAlongPath;
@ -2329,6 +2334,11 @@ namespace NavisworksTransport
RefreshNormalPaths();
}
internal static double ResolveGroundPathObjectSpaceVerticalOffset(double objectSpaceHeight)
{
return objectSpaceHeight / 2.0;
}
#region
/// <summary>

View File

@ -357,6 +357,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 角度修正相关字段
private LocalEulerRotationCorrection _objectRotationCorrection = LocalEulerRotationCorrection.Zero; // 物体绕宿主 X/Y/Z 轴的角度修正
private double _objectGroundLiftHeightInMeters;
// 移动物体原始尺寸(米,在选择物体时保存)
private double _objectOriginalLength; // 物体原始长度X方向
@ -1688,7 +1689,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (!isSameObject)
{
_pathAnimationManager?.SetObjectRotationCorrectionDirect(LocalEulerRotationCorrection.Zero);
_pathAnimationManager?.SetObjectStartVerticalLiftDirect(0.0);
ObjectRotationCorrection = LocalEulerRotationCorrection.Zero;
_objectGroundLiftHeightInMeters = 0.0;
LogManager.Debug("[选择物体] 已重置角度修正值为0新物体");
}
else
@ -2124,6 +2127,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
_pathAnimationManager.RestoreObjectToCADPosition();
_pathAnimationManager.ClearAnimationResults();
_pathAnimationManager.SetObjectRotationCorrectionDirect(LocalEulerRotationCorrection.Zero);
_pathAnimationManager.SetObjectStartVerticalLiftDirect(0.0);
_pathAnimationManager.SetObjectStartPlacementMode(ObjectStartPlacementMode.AlignToPathPose);
LogManager.Info("已清除PathAnimationManager中的动画数据并归位物体");
}
@ -2133,6 +2137,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 3. 重置角度修正值为0
ObjectRotationCorrection = LocalEulerRotationCorrection.Zero;
_objectGroundLiftHeightInMeters = 0.0;
LogManager.Debug("[清除物体] 已重置角度修正值为0");
// 4. 重置属性
@ -2159,20 +2164,29 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
try
{
var dialog = new Views.EditRotationWindow(_objectRotationCorrection);
bool enableGroundLift = CurrentPathRoute?.PathType == PathType.Ground;
var dialog = new Views.EditRotationWindow(
_objectRotationCorrection,
_objectGroundLiftHeightInMeters,
enableGroundLift);
if (dialog.ShowDialog() == true)
{
var placementRequest = dialog.AdjustmentRequest;
if (placementRequest.PreserveInitialPose)
{
ApplyTranslationOnlyObjectPlacement();
return;
}
_pathAnimationManager?.SetObjectStartPlacementMode(ObjectStartPlacementMode.AlignToPathPose);
_objectGroundLiftHeightInMeters = placementRequest.VerticalLiftInMeters;
_pathAnimationManager?.ApplyObjectStartPlacementRequest(placementRequest);
ObjectRotationCorrection = placementRequest.RotationCorrection;
LogManager.Info($"物体角度修正已更新: {_objectRotationCorrection}");
UpdateMainStatus($"物体角度修正: {_objectRotationCorrection}");
string liftSummary = enableGroundLift
? $", 提升高度={_objectGroundLiftHeightInMeters:F3}m"
: string.Empty;
string statusSummary = placementRequest.PreserveInitialPose
? $"物体已调整为平移模式{liftSummary}"
: $"物体角度修正: {_objectRotationCorrection}{liftSummary}";
LogManager.Info(
$"物体调整已更新: 模式={placementRequest.PlacementMode}, 角度={_objectRotationCorrection}, " +
$"提升高度={_objectGroundLiftHeightInMeters:F3}m");
UpdateMainStatus(statusSummary);
// 更新通行空间可视化(考虑旋转后的尺寸)
UpdatePassageSpaceVisualization();
@ -2196,6 +2210,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
_objectRotationCorrection = LocalEulerRotationCorrection.Zero;
_pathAnimationManager.SetObjectRotationCorrectionDirect(LocalEulerRotationCorrection.Zero);
_pathAnimationManager.SetObjectStartVerticalLiftDirect(0.0);
_pathAnimationManager.SetObjectStartPlacementMode(ObjectStartPlacementMode.PreserveInitialPose);
OnPropertyChanged(nameof(ObjectRotationCorrection));
@ -4463,7 +4478,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 地面路径物体的长度方向X轴前进方向朝向路径方向
// 通行空间沿路径方向 = X方向尺寸长度垂直于路径方向 = Y方向尺寸宽度高度上方加间隙下方不需要因为有地面
passageAcrossPath = effectiveWidth + 2 * safetyMargin; // 旋转后宽度 + 2*间隙(垂直于路径方向)
passageNormalToPath = effectiveHeight + safetyMargin; // 法线方向高度 + 间隙(法线方向,只有上方)
passageNormalToPath = effectiveHeight + (_objectGroundLiftHeightInMeters * metersToUnitsPassage) + safetyMargin; // 物体高度 + 提升高度 + 上方间隙
passageAlongPath = effectiveLength; // 旋转后长度(沿路径方向)
// 地面路径不需要分段参数
passageNormalToPathVertical = passageNormalToPath;
@ -4507,7 +4522,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 物体的长度方向X轴前进方向朝向路径方向
// 通行空间沿路径方向 = X方向尺寸长度垂直于路径方向 = Y方向尺寸宽度高度上方加间隙下方不需要因为有地面
passageAcrossPath = effectiveWidth + 2 * safetyMargin; // 旋转后宽度 + 2*间隙(垂直于路径方向)
passageNormalToPath = effectiveHeight + safetyMargin; // 局部up方向高度 + 间隙(法线方向,只有上方)
passageNormalToPath = effectiveHeight + (_objectGroundLiftHeightInMeters * metersToUnitsPassage) + safetyMargin; // 物体高度 + 提升高度 + 上方间隙
passageAlongPath = effectiveLength; // 旋转后长度(沿路径方向)
// 地面路径不需要分段参数
passageNormalToPathVertical = passageNormalToPath;
@ -4551,7 +4566,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
passageAlongPath,
passageNormalToPathVertical,
passageNormalToPathHorizontal);
LogManager.Debug($"[通行空间可视化] 已设置通行空间参数: 沿路径={passageAlongPath / metersToUnitsPassage:F2}m, 垂直路径={passageAcrossPath / metersToUnitsPassage:F2}m, 法线={passageNormalToPath / metersToUnitsPassage:F2}m, 安全间隙={_safetyMarginInMeters:F2}m");
LogManager.Debug($"[通行空间可视化] 已设置通行空间参数: 沿路径={passageAlongPath / metersToUnitsPassage:F2}m, 垂直路径={passageAcrossPath / metersToUnitsPassage:F2}m, 法线={passageNormalToPath / metersToUnitsPassage:F2}m, 提升高度={_objectGroundLiftHeightInMeters:F2}m, 安全间隙={_safetyMarginInMeters:F2}m");
// 根据路径类型决定是否切换到物体通行空间模式
bool enableObjectSpace = false;

View File

@ -346,7 +346,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
<Button Content="选择物体"
Command="{Binding SelectAnimatedObjectCommand}"
Style="{StaticResource SecondaryButtonStyle}"/>
<Button Content="调整角度"
<Button Content="调整物体"
Command="{Binding EditObjectRotationCommand}"
IsEnabled="{Binding HasSelectedAnimatedObject}"
Style="{StaticResource SecondaryButtonStyle}"/>
@ -383,7 +383,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
<Run Text="m"/>
</TextBlock>
<Button Grid.Column="2"
Content="调整角度"
Content="调整物体"
Command="{Binding EditObjectRotationCommand}"
Style="{StaticResource SecondaryButtonStyle}"
Margin="10,0,0,0"/>

View File

@ -1,7 +1,7 @@
<Window x:Class="NavisworksTransport.UI.WPF.Views.EditRotationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="调整物体角度" Height="360" Width="400"
Title="调整物体" Height="430" Width="400"
WindowStartupLocation="CenterScreen"
ResizeMode="NoResize"
ShowInTaskbar="False"
@ -25,8 +25,8 @@
<!-- 标题栏 -->
<Border Grid.Row="0" Background="#FFF8FBFF" BorderBrush="#FFD4E7FF" BorderThickness="0,0,0,1" Padding="20,15">
<StackPanel>
<TextBlock Text="调整物体角度" FontWeight="SemiBold" FontSize="14" Foreground="#FF2B579A"/>
<TextBlock Text="设置物体在路径起点处绕宿主 X/Y/Z 轴旋转角度" FontSize="10" Foreground="#FF666666" Margin="0,3,0,0"/>
<TextBlock Text="调整物体" FontWeight="SemiBold" FontSize="14" Foreground="#FF2B579A"/>
<TextBlock Text="设置物体在路径起点处的角度修正;地面路径可额外输入提升高度" FontSize="10" Foreground="#FF666666" Margin="0,3,0,0"/>
</StackPanel>
</Border>
@ -95,6 +95,31 @@
BorderThickness="1"/>
<TextBlock Grid.Column="2" Text="°" VerticalAlignment="Center" FontSize="11" Foreground="#FF666666" Margin="8,0,0,0"/>
</Grid>
<Grid Margin="0,0,0,12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<TextBlock Text="提升高度:" VerticalAlignment="Center" FontSize="11" Foreground="#FF333333"/>
<TextBox Grid.Column="1"
x:Name="GroundLiftTextBox"
Text="{Binding GroundPathLiftHeightInMeters, StringFormat=0.###, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding IsGroundLiftEnabled}"
Height="28"
VerticalContentAlignment="Center"
Padding="8,0"
FontSize="11"
BorderBrush="#FFCCCCCC"
BorderThickness="1"/>
<TextBlock Grid.Column="2" Text="m" VerticalAlignment="Center" FontSize="11" Foreground="#FF666666" Margin="8,0,0,0"/>
</Grid>
<TextBlock Text="{Binding GroundLiftHint}"
FontSize="10"
Foreground="#FF666666"
Margin="0,0,0,12"/>
<!-- 快捷按钮 -->
<TextBlock Text="快捷角度(作用于当前焦点输入框):" FontSize="10" Foreground="#FF666666" Margin="0,0,0,8"/>

View File

@ -19,8 +19,10 @@ namespace NavisworksTransport.UI.WPF.Views
private double _rotationXDegrees;
private double _rotationYDegrees;
private double _rotationZDegrees;
private double _groundPathLiftHeightInMeters;
private RotationAxisTarget _activeAxisTarget = RotationAxisTarget.Z;
private ObjectStartPlacementRequest _adjustmentRequest;
private readonly bool _isGroundLiftEnabled;
public double RotationXDegrees
{
@ -67,9 +69,31 @@ namespace NavisworksTransport.UI.WPF.Views
public LocalEulerRotationCorrection RotationCorrection =>
new LocalEulerRotationCorrection(RotationXDegrees, RotationYDegrees, RotationZDegrees);
public double GroundPathLiftHeightInMeters
{
get => _groundPathLiftHeightInMeters;
set
{
if (Math.Abs(_groundPathLiftHeightInMeters - value) > 1e-9)
{
_groundPathLiftHeightInMeters = value;
OnPropertyChanged();
}
}
}
public bool IsGroundLiftEnabled => _isGroundLiftEnabled;
public string GroundLiftHint => _isGroundLiftEnabled
? "仅地面路径生效,用于模拟物体下方物流小车带来的整体抬升。"
: "提升高度当前仅对地面路径生效。";
public ObjectStartPlacementRequest AdjustmentRequest => _adjustmentRequest;
public EditRotationWindow(LocalEulerRotationCorrection currentRotation)
public EditRotationWindow(
LocalEulerRotationCorrection currentRotation,
double currentGroundLiftHeightInMeters,
bool isGroundLiftEnabled)
{
try
{
@ -77,7 +101,9 @@ namespace NavisworksTransport.UI.WPF.Views
RotationXDegrees = currentRotation.XDegrees;
RotationYDegrees = currentRotation.YDegrees;
RotationZDegrees = currentRotation.ZDegrees;
_adjustmentRequest = ObjectStartPlacementRequest.CreateRotationCorrection(currentRotation);
_isGroundLiftEnabled = isGroundLiftEnabled;
GroundPathLiftHeightInMeters = currentGroundLiftHeightInMeters;
_adjustmentRequest = ObjectStartPlacementRequest.CreateRotationCorrection(currentRotation, currentGroundLiftHeightInMeters);
DataContext = this;
Loaded += (sender, args) => ZAxisTextBox.Focus();
}
@ -145,14 +171,24 @@ namespace NavisworksTransport.UI.WPF.Views
private void OnConfirmClick(object sender, RoutedEventArgs e)
{
_adjustmentRequest = ObjectStartPlacementRequest.CreateRotationCorrection(RotationCorrection);
if (!ValidateGroundLiftHeight())
{
return;
}
_adjustmentRequest = ObjectStartPlacementRequest.CreateRotationCorrection(RotationCorrection, GroundPathLiftHeightInMeters);
DialogResult = true;
Close();
}
private void OnTranslateClick(object sender, RoutedEventArgs e)
{
_adjustmentRequest = ObjectStartPlacementRequest.TranslationOnly;
if (!ValidateGroundLiftHeight())
{
return;
}
_adjustmentRequest = ObjectStartPlacementRequest.CreateTranslationOnly(GroundPathLiftHeightInMeters);
DialogResult = true;
Close();
}
@ -186,5 +222,17 @@ namespace NavisworksTransport.UI.WPF.Views
break;
}
}
private bool ValidateGroundLiftHeight()
{
if (GroundPathLiftHeightInMeters < 0.0)
{
MessageBox.Show("提升高度必须大于或等于 0。", "输入错误", MessageBoxButton.OK, MessageBoxImage.Warning);
GroundLiftTextBox.Focus();
return false;
}
return true;
}
}
}

View File

@ -11,31 +11,43 @@ namespace NavisworksTransport.Utils.CoordinateSystem
public struct ObjectStartPlacementRequest : IEquatable<ObjectStartPlacementRequest>
{
public static readonly ObjectStartPlacementRequest TranslationOnly =
new ObjectStartPlacementRequest(LocalEulerRotationCorrection.Zero, ObjectStartPlacementMode.PreserveInitialPose);
new ObjectStartPlacementRequest(LocalEulerRotationCorrection.Zero, ObjectStartPlacementMode.PreserveInitialPose, 0.0);
public ObjectStartPlacementRequest(
LocalEulerRotationCorrection rotationCorrection,
ObjectStartPlacementMode placementMode)
ObjectStartPlacementMode placementMode,
double verticalLiftInMeters)
{
RotationCorrection = rotationCorrection;
PlacementMode = placementMode;
VerticalLiftInMeters = verticalLiftInMeters;
}
public LocalEulerRotationCorrection RotationCorrection { get; }
public ObjectStartPlacementMode PlacementMode { get; }
public double VerticalLiftInMeters { get; }
public bool PreserveInitialPose => PlacementMode == ObjectStartPlacementMode.PreserveInitialPose;
public static ObjectStartPlacementRequest CreateRotationCorrection(LocalEulerRotationCorrection rotationCorrection)
public static ObjectStartPlacementRequest CreateRotationCorrection(
LocalEulerRotationCorrection rotationCorrection,
double verticalLiftInMeters = 0.0)
{
return new ObjectStartPlacementRequest(rotationCorrection, ObjectStartPlacementMode.AlignToPathPose);
return new ObjectStartPlacementRequest(rotationCorrection, ObjectStartPlacementMode.AlignToPathPose, verticalLiftInMeters);
}
public static ObjectStartPlacementRequest CreateTranslationOnly(double verticalLiftInMeters = 0.0)
{
return new ObjectStartPlacementRequest(LocalEulerRotationCorrection.Zero, ObjectStartPlacementMode.PreserveInitialPose, verticalLiftInMeters);
}
public bool Equals(ObjectStartPlacementRequest other)
{
return RotationCorrection.Equals(other.RotationCorrection) &&
PlacementMode == other.PlacementMode;
PlacementMode == other.PlacementMode &&
VerticalLiftInMeters.Equals(other.VerticalLiftInMeters);
}
public override bool Equals(object obj)
@ -47,13 +59,16 @@ namespace NavisworksTransport.Utils.CoordinateSystem
{
unchecked
{
return (RotationCorrection.GetHashCode() * 397) ^ (int)PlacementMode;
int hashCode = RotationCorrection.GetHashCode();
hashCode = (hashCode * 397) ^ (int)PlacementMode;
hashCode = (hashCode * 397) ^ VerticalLiftInMeters.GetHashCode();
return hashCode;
}
}
public override string ToString()
{
return $"PlacementMode={PlacementMode}, Rotation={RotationCorrection}";
return $"PlacementMode={PlacementMode}, Rotation={RotationCorrection}, VerticalLiftInMeters={VerticalLiftInMeters:F3}";
}
}
}