chore: 更新 CHANGELOG 和 VERSION 至 0.15.6
- 记录自动调整评测与姿态对准修正、skipCadRestore 重构 - 记录别名树 DisplayPath 重名修复 - 版本号 0.15.4 → 0.15.6
This commit is contained in:
parent
f5387c8699
commit
51453df037
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,5 +1,17 @@
|
||||
# NavisworksTransport 变更日志
|
||||
|
||||
## [0.15.6] - 2026-06-06
|
||||
|
||||
### 🐛 Bug 修复
|
||||
|
||||
- **自动调整评测与姿态对准修正**:
|
||||
- `GetYawFromRotation` 通过 canonical space 转换计算偏航角,修复 YUp 模式下硬编码 `atan2(Y,X)` 用错水平面的问题
|
||||
- 评测器改为 CAD 原位纯旋转(`ApplyRotationCorrectionInPlace`),以 X 轴为统一参考前向,且旋转分解顺序与增量链一致
|
||||
- 门型约束从评测内硬过滤改为两轮优化:先无约束找最小截面积,不满足约束再带约束重搜
|
||||
- 确认时走 `skipCadRestore` 路径:原地校正后不复位到 CAD,从当前姿态偏航到路径方向,避免读到 CAD 原始 yaw
|
||||
- `MoveObjectToPathStart` 新增 `skipCadRestore` 参数,跳过 CAD 复位步骤
|
||||
- **别名树 DisplayPath 重名修复**:所有层级路径段加 `#N` 后缀去重,移除旧格式兼容代码
|
||||
|
||||
## [0.15.5] - 2026-06-02
|
||||
|
||||
### ✨ 新功能
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
# 版本号
|
||||
|
||||
0.15.4
|
||||
0.15.6
|
||||
|
||||
@ -461,61 +461,18 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动调整确认专用:先原地旋转校正(对齐 X),再偏航到路径方向并移动到起点。
|
||||
/// 不走 MoveObjectToPathStart 的 CAD 恢复→偏航链,避免读到 CAD 的原始 yaw。
|
||||
/// 将当前显示姿态同步为跟踪状态(yaw=0 对应对齐 X 轴)。
|
||||
/// 用于自动调整确认前,替代 RestoreObjectToCADPosition 的复位→设置链路。
|
||||
/// </summary>
|
||||
public void ApplyAutoAdjustedPoseAndMoveToPathStart(LocalEulerRotationCorrection correction)
|
||||
public void SyncTrackedStateToCurrentDisplayPose()
|
||||
{
|
||||
var item = CurrentControlledObject;
|
||||
if (item == null || _pathPoints == null || _pathPoints.Count < 2) return;
|
||||
|
||||
// 1. 原地旋转校正 → 物体对齐 X 轴
|
||||
RestoreObjectToCADPosition();
|
||||
_objectStartPlacementMode = ObjectStartPlacementMode.AlignToPathPose;
|
||||
_hasPathPreservedPoseRotation = false;
|
||||
_objectRotationCorrection = correction;
|
||||
ApplyRotationCorrectionInPlace(correction);
|
||||
|
||||
// 2. 计算路径起点位置(与 MoveObjectToPathStart 一致)
|
||||
Point3D pathStartPoint = _pathPoints[0];
|
||||
Point3D startPosition = ResolveGroundTrackedCenter(pathStartPoint, GetAnimatedObjectGroundContactHeight());
|
||||
startPosition = ApplyGroundPathObjectLiftOffset(startPosition);
|
||||
|
||||
// 3. 解析路径方向 yaw
|
||||
var adapter = CoordinateSystemManager.Instance.CreateHostAdapter();
|
||||
if (!PathTargetFrameResolver.TryResolvePlanarStartHostForward(
|
||||
_route?.PathType ?? PathType.Ground, _pathPoints, out var hostForward))
|
||||
{
|
||||
LogManager.Warning("[自动调整确认] 无法解析路径起始方向");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PathTargetFrameResolver.TryResolvePlanarHostYaw(hostForward, adapter.HostType, out double pathYaw))
|
||||
{
|
||||
LogManager.Warning("[自动调整确认] 无法从路径方向解析 yaw");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 从当前 X 朝向偏航到路径方向 + 平移到起点
|
||||
Point3D currentCenter = GetLiveBoundingBoxCenter(item);
|
||||
var nonUpAxis = adapter.HostType == CoordinateSystemType.YUp ? Vector3.UnitZ : Vector3.UnitY;
|
||||
ModelItemTransformHelper.MoveItemCombinedAxisRotationAndTranslation(
|
||||
item, currentCenter,
|
||||
Vector3.UnitX, 0,
|
||||
nonUpAxis, 0,
|
||||
adapter.HostUpVector3, (float)pathYaw,
|
||||
startPosition);
|
||||
|
||||
// 5. 更新跟踪状态
|
||||
_trackedPosition = startPosition;
|
||||
_currentYaw = pathYaw;
|
||||
// Ground 真实物体基姿态
|
||||
_groundRealObjectBaseYaw = pathYaw;
|
||||
_hasGroundRealObjectBasePose = true;
|
||||
|
||||
LogManager.Debug(
|
||||
$"[自动调整确认] 校正={correction}, 路径Yaw={pathYaw * 180.0 / Math.PI:F2}°, " +
|
||||
$"起点=({startPosition.X:F3},{startPosition.Y:F3},{startPosition.Z:F3})");
|
||||
if (item == null) return;
|
||||
_trackedPosition = GetLiveBoundingBoxCenter(item);
|
||||
_currentYaw = 0.0;
|
||||
_trackedRotation = item.Transform.Factor().Rotation;
|
||||
_hasTrackedRotation = true;
|
||||
_hasGroundRealObjectBasePose = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -739,7 +696,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
/// <param name="animatedObject">动画对象(可选,如果不提供则使用当前的_animatedObject)</param>
|
||||
/// <param name="pathPoints">路径点(可选,如果不提供则使用当前的_pathPoints)</param>
|
||||
/// <returns>是否成功移动</returns>
|
||||
public bool MoveObjectToPathStart(ModelItem animatedObject = null, List<Point3D> pathPoints = null)
|
||||
public bool MoveObjectToPathStart(ModelItem animatedObject = null, List<Point3D> pathPoints = null, bool skipCadRestore = false)
|
||||
{
|
||||
_objectStartPlacementMode = ObjectStartPlacementMode.AlignToPathPose;
|
||||
|
||||
@ -752,47 +709,48 @@ namespace NavisworksTransport.Core.Animation
|
||||
|
||||
try
|
||||
{
|
||||
// 🔥 重要:先恢复物体到原始状态(CAD位置和原始朝向),确保每次计算都从相同的状态开始
|
||||
// 这样可以避免之前旋转导致的包围盒尺寸计算不准确的问题
|
||||
// 注意:也要处理虚拟物体(当前控制对象可能不在 _animatedObject 中)
|
||||
if (CurrentControlledObject != null || IsVirtualObjectMode)
|
||||
if (!skipCadRestore)
|
||||
{
|
||||
RestoreObjectToCADPosition();
|
||||
}
|
||||
|
||||
// 如果提供了参数,更新内部状态
|
||||
if (animatedObject != null)
|
||||
{
|
||||
_animatedObject = animatedObject;
|
||||
bool isVirtualObject =
|
||||
VirtualObjectManager.Instance.IsVirtualObjectActive &&
|
||||
ReferenceEquals(animatedObject, VirtualObjectManager.Instance.CurrentVirtualObject);
|
||||
_animatedObjectMode = isVirtualObject
|
||||
? AnimatedObjectMode.VirtualObject
|
||||
: AnimatedObjectMode.RealObject;
|
||||
ResetRealObjectReferenceRotation();
|
||||
_originalTransform = animatedObject.Transform;
|
||||
_originalCenter = animatedObject.BoundingBox().Center;
|
||||
_trackedPosition = ResolveInitialBusinessTrackedPosition(animatedObject);
|
||||
if (isVirtualObject)
|
||||
if (CurrentControlledObject != null || IsVirtualObjectMode)
|
||||
{
|
||||
_currentYaw = ModelItemTransformHelper.GetYawFromTransform(_originalTransform);
|
||||
_trackedRotation = _originalTransform.Factor().Rotation;
|
||||
_hasTrackedRotation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SyncTrackedRotationToObjectReference(animatedObject, isVirtualObject: false);
|
||||
RestoreObjectToCADPosition();
|
||||
}
|
||||
|
||||
LogManager.Info(
|
||||
$"[移动到起点] 更新动画对象内部状态: 对象={animatedObject.DisplayName}, 虚拟物体={IsVirtualObjectMode}");
|
||||
}
|
||||
// 如果提供了参数,更新内部状态
|
||||
if (animatedObject != null)
|
||||
{
|
||||
_animatedObject = animatedObject;
|
||||
bool isVirtualObject =
|
||||
VirtualObjectManager.Instance.IsVirtualObjectActive &&
|
||||
ReferenceEquals(animatedObject, VirtualObjectManager.Instance.CurrentVirtualObject);
|
||||
_animatedObjectMode = isVirtualObject
|
||||
? AnimatedObjectMode.VirtualObject
|
||||
: AnimatedObjectMode.RealObject;
|
||||
ResetRealObjectReferenceRotation();
|
||||
_originalTransform = animatedObject.Transform;
|
||||
_originalCenter = animatedObject.BoundingBox().Center;
|
||||
_trackedPosition = ResolveInitialBusinessTrackedPosition(animatedObject);
|
||||
if (isVirtualObject)
|
||||
{
|
||||
_currentYaw = ModelItemTransformHelper.GetYawFromTransform(_originalTransform);
|
||||
_trackedRotation = _originalTransform.Factor().Rotation;
|
||||
_hasTrackedRotation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SyncTrackedRotationToObjectReference(animatedObject, isVirtualObject: false);
|
||||
}
|
||||
|
||||
if (pathPoints != null)
|
||||
{
|
||||
_pathPoints = pathPoints;
|
||||
LogManager.Info(
|
||||
$"[移动到起点] 更新动画对象内部状态: 对象={animatedObject.DisplayName}, 虚拟物体={IsVirtualObjectMode}");
|
||||
}
|
||||
|
||||
if (pathPoints != null)
|
||||
{
|
||||
_pathPoints = pathPoints;
|
||||
}
|
||||
}
|
||||
// skipCadRestore: 调用方已设置好 _trackedPosition、_currentYaw、_objectRotationCorrection
|
||||
|
||||
// 检查路径点
|
||||
if (_pathPoints == null || _pathPoints.Count < 2)
|
||||
@ -866,6 +824,13 @@ namespace NavisworksTransport.Core.Animation
|
||||
$"[移动到起点-诊断] _trackedPosition=({_trackedPosition.X:F3},{_trackedPosition.Y:F3},{_trackedPosition.Z:F3}), " +
|
||||
$"startPosition=({startPosition.X:F3},{startPosition.Y:F3},{startPosition.Z:F3})");
|
||||
|
||||
// skipCadRestore 时,校正已原地施加,yaw 增量不应再包含校正的 up 轴分量
|
||||
var savedCorrection = _objectRotationCorrection;
|
||||
if (skipCadRestore)
|
||||
{
|
||||
_objectRotationCorrection = LocalEulerRotationCorrection.Zero;
|
||||
}
|
||||
|
||||
if (shouldUsePlanarPureIncrementStart &&
|
||||
TryApplyPlanarRealObjectStartIncrementalTransform(_route.PathType, startPosition, out double planarTargetYawRadians))
|
||||
{
|
||||
@ -957,6 +922,11 @@ namespace NavisworksTransport.Core.Animation
|
||||
return false;
|
||||
}
|
||||
|
||||
if (skipCadRestore)
|
||||
{
|
||||
_objectRotationCorrection = savedCorrection;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -5551,7 +5521,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyObjectStartPlacementRequest(ObjectStartPlacementRequest request)
|
||||
public void ApplyObjectStartPlacementRequest(ObjectStartPlacementRequest request, bool skipCadRestore = false)
|
||||
{
|
||||
_objectStartPlacementMode = request.PlacementMode;
|
||||
if (_objectStartPlacementMode != ObjectStartPlacementMode.PreserveInitialPose)
|
||||
@ -5570,7 +5540,7 @@ namespace NavisworksTransport.Core.Animation
|
||||
{
|
||||
try
|
||||
{
|
||||
MoveObjectToPathStartUsingCurrentPlacementMode();
|
||||
MoveObjectToPathStartUsingCurrentPlacementMode(skipCadRestore: skipCadRestore);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -5613,11 +5583,11 @@ namespace NavisworksTransport.Core.Animation
|
||||
LogManager.Debug($"[起点摆放] 当前模式已设置为: {_objectStartPlacementMode}");
|
||||
}
|
||||
|
||||
private bool MoveObjectToPathStartUsingCurrentPlacementMode(ModelItem animatedObject = null, List<Point3D> pathPoints = null)
|
||||
private bool MoveObjectToPathStartUsingCurrentPlacementMode(ModelItem animatedObject = null, List<Point3D> pathPoints = null, bool skipCadRestore = false)
|
||||
{
|
||||
return _objectStartPlacementMode == ObjectStartPlacementMode.PreserveInitialPose
|
||||
? MoveObjectToPathStartPreservingInitialPose(animatedObject, pathPoints)
|
||||
: MoveObjectToPathStart(animatedObject, pathPoints);
|
||||
: MoveObjectToPathStart(animatedObject, pathPoints, skipCadRestore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -2191,11 +2191,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
bool isAutoAdjusted = dialog.AutoAdjustAabbSizes.HasValue;
|
||||
if (isAutoAdjusted)
|
||||
{
|
||||
// 自动调整:先原地校正(对齐 X),再偏航到路径方向
|
||||
// 自动调整:先原地校正(对齐 X),再通过 MoveObjectToPathStart(skipCadRestore) 偏航到路径
|
||||
_pathAnimationManager?.SetObjectStartVerticalLiftDirect(
|
||||
placementRequest.VerticalLiftInMeters);
|
||||
_pathAnimationManager?.ApplyAutoAdjustedPoseAndMoveToPathStart(
|
||||
_pathAnimationManager?.ApplyRotationCorrectionInPlace(
|
||||
placementRequest.RotationCorrection);
|
||||
_pathAnimationManager?.SyncTrackedStateToCurrentDisplayPose();
|
||||
_pathAnimationManager?.ApplyObjectStartPlacementRequest(placementRequest, skipCadRestore: true);
|
||||
_pathAnimationManager?.SetObjectRotationCorrectionDirect(
|
||||
placementRequest.RotationCorrection);
|
||||
_objectRotationCorrection = placementRequest.RotationCorrection;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user