diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs index 10dc9a1..efbd2ca 100644 --- a/src/Core/Animation/PathAnimationManager.cs +++ b/src/Core/Animation/PathAnimationManager.cs @@ -975,7 +975,7 @@ namespace NavisworksTransport.Core.Animation startPosition = ApplyGroundPathObjectLiftOffset(startPosition); } - ApplyLegacyYawPoseUpdate(startPosition); + ApplyTrackedTranslationOnly(startPosition); SyncTrackedRotationToDisplayedPose(CurrentControlledObject ?? _animatedObject); _hasGroundRealObjectBasePose = false; @@ -1878,9 +1878,8 @@ namespace NavisworksTransport.Core.Animation _currentFrameIndex = 0; // 重置当前帧索引,确保从第一帧开始 _pausedProgress = 0.0; // 重置暂停进度 - // 初始化动画状态时不再强行覆盖 _currentYaw 为第一帧的 yaw - // 这样在 ApplyLegacyYawPoseUpdate(firstFrame.Position, firstFrame.YawRadians) 时 - // deltaYaw = firstFrame.YawRadians - 物体初始Yaw,从而产生旋转增量让物体转向 + // 初始化动画状态时不再强行覆盖 _currentYaw 为第一帧的 yaw, + // 由记录姿态应用链自行解释第一帧姿态。 if (_animationFrames != null && _animationFrames.Count > 0) { @@ -2119,7 +2118,7 @@ namespace NavisworksTransport.Core.Animation if (_currentFrameIndex != lastFrameIndex) { _currentFrameIndex = lastFrameIndex; - ApplyAnimationFramePose(_animationFrames[_currentFrameIndex], _currentFrameIndex); + ApplyRecordedPose(_animationFrames[_currentFrameIndex], _currentFrameIndex); LogManager.Info("[动画结束] 当前尚未到最后一帧,已补落最终姿态"); } else @@ -2683,9 +2682,10 @@ namespace NavisworksTransport.Core.Animation } /// - /// 更新对象位置和朝向(支持绕物体中心旋转) + /// 仅按业务跟踪点执行平移,不改变当前姿态语义。 + /// PreserveInitialPose 起点搬运等链路应显式使用此入口,而不是借用旧 yaw 链。 /// - private void ApplyLegacyYawPoseUpdate(Point3D newPosition, double newYaw = double.NaN) + private void ApplyTrackedTranslationOnly(Point3D newPosition) { try { @@ -2699,50 +2699,8 @@ namespace NavisworksTransport.Core.Animation newPosition.Z - _trackedPosition.Z ); - Transform3D incrementalTransform; - - if (!double.IsNaN(newYaw)) - { - // 有旋转:需要实现"绕物体当前位置自转" - // 由于Transform3DComponents.Rotation总是绕世界原点旋转 - // 我们需要手动计算旋转导致的位置偏移,并补偿 - - double deltaYaw = newYaw - _currentYaw; - //LogManager.Debug($"[UpdateObjectPosition] 当前yaw={_currentYaw * 180 / Math.PI:F2}度, 目标yaw={newYaw * 180 / Math.PI:F2}度, 旋转增量deltaYaw={deltaYaw * 180 / Math.PI:F2}度"); - - // 计算绕当前位置旋转的等效变换: - // 1. 如果绕原点旋转deltaYaw,当前位置_trackedPosition会移动到哪里? - double cos = Math.Cos(deltaYaw); - double sin = Math.Sin(deltaYaw); - double rotatedX = _trackedPosition.X * cos - _trackedPosition.Y * sin; - double rotatedY = _trackedPosition.X * sin + _trackedPosition.Y * cos; - - // 2. 但我们希望物体绕自己旋转,位置移动到newPosition - // 所以需要的平移 = newPosition - (旋转后的位置) - var compensatedTranslation = new Vector3D( - newPosition.X - rotatedX, - newPosition.Y - rotatedY, - newPosition.Z - _trackedPosition.Z // Z保持deltaPos - ); - - // 3. 组合:先旋转(绕原点),再平移(补偿+目标位置) - var identity = Transform3D.CreateTranslation(new Vector3D(0, 0, 0)); - var components = identity.Factor(); - components.Rotation = new Rotation3D(new UnitVector3D(0, 0, 1), deltaYaw); - components.Translation = compensatedTranslation; - - incrementalTransform = components.Combine(); - - _currentYaw = newYaw; - _trackedRotation = Rotation3D.Identity; - _hasTrackedRotation = false; - } - else - { - // 纯平移 - incrementalTransform = Transform3D.CreateTranslation(deltaPos); - LogManager.Debug($"[LegacyYawPose] 纯平移: ({deltaPos.X:F2},{deltaPos.Y:F2},{deltaPos.Z:F2})"); - } + Transform3D incrementalTransform = Transform3D.CreateTranslation(deltaPos); + LogManager.Debug($"[TrackedTranslation] 纯平移: ({deltaPos.X:F2},{deltaPos.Y:F2},{deltaPos.Z:F2})"); // 应用增量变换(false = 增量模式) doc.Models.OverridePermanentTransform(modelItems, incrementalTransform, false); @@ -3056,10 +3014,9 @@ namespace NavisworksTransport.Core.Animation ApplyResolvedObjectPose( _savedObjectPosition, - _savedObjectYaw, _savedObjectRotation, _savedObjectHasCustomRotation, - frameIndex: -1, + -1, planarHostYawRadians: _savedObjectYaw); LogHostActualPoseAxes(obj, "[PAM恢复后宿主姿态]", false); @@ -3128,10 +3085,9 @@ namespace NavisworksTransport.Core.Animation ApplyResolvedObjectPose( targetPosition, - targetYawRadians, targetRotation, hasCustomRotation, - frameIndex: -1, + -1, planarHostYawRadians: targetYawRadians); LogHostActualPoseAxes(obj, "[动画姿态复用后宿主姿态]", false); @@ -3246,7 +3202,7 @@ namespace NavisworksTransport.Core.Animation // 更新对象位置和朝向,复用动画主播放与恢复使用的同一入口。 var frameData = _animationFrames[_currentFrameIndex]; - ApplyAnimationFramePose(frameData, _currentFrameIndex); + ApplyRecordedPose(frameData, _currentFrameIndex); // 更新碰撞高亮 UpdateCollisionHighlightFromFrame(); @@ -5488,11 +5444,11 @@ namespace NavisworksTransport.Core.Animation } /// - /// 保留给旧单轴调用方:按当前宿主 up 轴映射成三轴角度修正。 + /// 单轴兼容入口:按当前宿主 up 轴映射成三轴角度修正。 /// public void SetObjectRotationCorrection(double rotationCorrection) { - SetObjectRotationCorrection(CreateLegacyUpAxisCorrection(rotationCorrection)); + SetObjectRotationCorrection(CreateSingleAxisUpCorrection(rotationCorrection)); } /// @@ -5529,14 +5485,14 @@ namespace NavisworksTransport.Core.Animation } /// - /// 保留给旧单轴调用方:按当前宿主 up 轴映射成三轴角度修正。 + /// 单轴兼容入口:按当前宿主 up 轴映射成三轴角度修正。 /// public void SetObjectRotationCorrectionDirect(double rotationCorrection) { - SetObjectRotationCorrectionDirect(CreateLegacyUpAxisCorrection(rotationCorrection)); + SetObjectRotationCorrectionDirect(CreateSingleAxisUpCorrection(rotationCorrection)); } - private LocalEulerRotationCorrection CreateLegacyUpAxisCorrection(double rotationCorrection) + private LocalEulerRotationCorrection CreateSingleAxisUpCorrection(double rotationCorrection) { var adapter = CoordinateSystemManager.Instance.CreateHostAdapter(); return adapter.HostType == CoordinateSystemType.YUp @@ -5692,7 +5648,7 @@ namespace NavisworksTransport.Core.Animation if (_currentFrameIndex < _animationFrames.Count) { var frameData = _animationFrames[_currentFrameIndex]; - ApplyAnimationFramePose(frameData, _currentFrameIndex); + ApplyRecordedPose(frameData, _currentFrameIndex); // 更新碰撞高亮(基于预计算结果) UpdateCollisionHighlightFromFrame(); @@ -5719,7 +5675,7 @@ namespace NavisworksTransport.Core.Animation UpdateFPSCounterAndCheckSwitch(); } - private void ApplyAnimationFramePose(AnimationFrame frameData, int frameIndex) + private void ApplyRecordedPose(AnimationFrame frameData, int frameIndex) { if (frameData == null) { @@ -5728,16 +5684,16 @@ namespace NavisworksTransport.Core.Animation ApplyResolvedObjectPose( frameData.Position, - ResolveAnimationFramePlaybackYawRadians(frameData), frameData.Rotation, frameData.HasCustomRotation, frameIndex, - frameData.PlanarHostYawRadians); + frameData.PlanarHostYawRadians.HasValue + ? (double?)ResolveAnimationFramePlaybackYawRadians(frameData) + : null); } private void ApplyResolvedObjectPose( Point3D targetPosition, - double resolvedYawRadians, Rotation3D targetRotation, bool hasCustomRotation, int frameIndex, @@ -5746,7 +5702,7 @@ namespace NavisworksTransport.Core.Animation if (ShouldUsePlanarRealObjectPureIncrementFrames(_route?.PathType ?? PathType.Ground, IsRealObjectMode) && planarHostYawRadians.HasValue) { - ApplyPlanarAnimationFrame(targetPosition, planarHostYawRadians.Value); + ApplyPlanarTrackedPose(targetPosition, planarHostYawRadians.Value); return; } @@ -5756,13 +5712,9 @@ namespace NavisworksTransport.Core.Animation return; } - if (_route?.PathType == PathType.Ground || _route?.PathType == PathType.Hoisting) - { - throw new InvalidOperationException( - $"平面路径播放帧 {frameIndex} 缺少完整姿态,禁止退回旧 yaw 链路。"); - } - - ApplyLegacyYawPoseUpdate(targetPosition, resolvedYawRadians); + string pathTypeName = (_route?.PathType ?? PathType.Ground).GetDisplayName(); + throw new InvalidOperationException( + $"{pathTypeName}记录姿态 {frameIndex} 缺少完整姿态,禁止退回旧 yaw 链路。"); } private double ResolveAnimationFramePlaybackYawRadians(AnimationFrame frameData) @@ -5802,9 +5754,9 @@ namespace NavisworksTransport.Core.Animation } /// - /// 专门用于Ground路径动画帧播放。使用业务跟踪点 _trackedPosition 作为当前位置,不读取实时包围盒中心回写主链。 + /// 应用平面路径的已记录姿态。使用业务跟踪点 _trackedPosition 作为当前位置,不读取实时包围盒中心回写主链。 /// - private void ApplyPlanarAnimationFrame(Point3D targetPosition, double targetYawRadians) + private void ApplyPlanarTrackedPose(Point3D targetPosition, double targetYawRadians) { var controlledObject = CurrentControlledObject; if (controlledObject == null) return; diff --git a/src/Core/Collision/ClashDetectiveIntegration.cs b/src/Core/Collision/ClashDetectiveIntegration.cs index ebf343a..3211e45 100644 --- a/src/Core/Collision/ClashDetectiveIntegration.cs +++ b/src/Core/Collision/ClashDetectiveIntegration.cs @@ -826,50 +826,10 @@ namespace NavisworksTransport } else { - // 旧二维候选验证仍沿用“回到 CAD 原始位置再应用增量”的成熟语义。 - doc.Models.ResetPermanentTransform(modelItems); - - var originalBounds = testAnimatedObject.BoundingBox(); - var originalPos = new Point3D( - (originalBounds.Min.X + originalBounds.Max.X) / 2, - (originalBounds.Min.Y + originalBounds.Max.Y) / 2, - (originalBounds.Min.Z + originalBounds.Max.Z) / 2 - ); - var originalYaw = ModelItemTransformHelper.GetYawFromTransform(testAnimatedObject.Transform); - - var deltaPos = new Vector3D( - targetPosition.X - originalPos.X, - targetPosition.Y - originalPos.Y, - targetPosition.Z - originalPos.Z - ); - double deltaYaw = targetYaw - originalYaw; - - Transform3D transform; - if (Math.Abs(deltaYaw) > 0.001) - { - double cos = Math.Cos(deltaYaw); - double sin = Math.Sin(deltaYaw); - double rotatedX = originalPos.X * cos - originalPos.Y * sin; - double rotatedY = originalPos.X * sin + originalPos.Y * cos; - - var compensatedTranslation = new Vector3D( - targetPosition.X - rotatedX, - targetPosition.Y - rotatedY, - deltaPos.Z - ); - - var identity = Transform3D.CreateTranslation(new Vector3D(0, 0, 0)); - var components = identity.Factor(); - components.Rotation = new Rotation3D(new UnitVector3D(0, 0, 1), deltaYaw); - components.Translation = compensatedTranslation; - transform = components.Combine(); - } - else - { - transform = Transform3D.CreateTranslation(deltaPos); - } - - doc.Models.OverridePermanentTransform(modelItems, transform, false); + throw new InvalidOperationException( + $"ClashDetective候选恢复缺少完整姿态:对象 {testAnimatedObject.DisplayName}," + + $"目标跟踪点=({targetPosition.X:F3},{targetPosition.Y:F3},{targetPosition.Z:F3})," + + $"TrackedYaw={targetYaw:F6}rad。"); } var tempTestName = $"临时验证_{confirmedCount + 1}_{i}_{DateTime.Now:HHmmss_fff}"; diff --git a/src/Utils/CollisionSceneHelper.cs b/src/Utils/CollisionSceneHelper.cs index 39a49c2..3a34371 100644 --- a/src/Utils/CollisionSceneHelper.cs +++ b/src/Utils/CollisionSceneHelper.cs @@ -98,49 +98,47 @@ namespace NavisworksTransport.Utils { if (animatedObject == null) return null; - try + var pam = PathAnimationManager.GetInstance(); + if (pam == null || !pam.ControlsAnimatedObject(animatedObject)) { - // 从PathAnimationManager获取当前实际朝向 - var pam = PathAnimationManager.GetInstance(); - var currentYaw = pam.CurrentYaw; - var currentRotation = pam.TrackedRotation; - var hasCustomRotation = pam.HasTrackedRotation; - var currentState = pam.GetObjectCurrentPosition(animatedObject); - pam.SaveObjectState(animatedObject); + throw new InvalidOperationException( + $"保存碰撞场景前的动画物体状态必须复用 PathAnimationManager:对象 {animatedObject.DisplayName} 不受当前动画管理器控制。"); + } - var state = ModelItemTransformHelper.SaveObjectState( - animatedObject, - currentYaw, - currentState.Position, - currentRotation, - hasCustomRotation); - - LogManager.Info(string.Format("已保存动画物体状态: {0}, 位置=({1:F2},{2:F2},{3:F2}), 朝向={4:F2}°, customRotation={5}", - animatedObject.DisplayName, state.Position.X, state.Position.Y, state.Position.Z, - currentYaw * 180 / Math.PI, state.HasCustomRotation)); - if (state.HasCustomRotation && state.Rotation != null) - { - var linear = new Transform3D(state.Rotation).Linear; - LogManager.Info(string.Format( - "[报告姿态保存] {0} 保存姿态: " + - "位置=({1:F3},{2:F3},{3:F3}), " + - "X=({4:F4},{5:F4},{6:F4}), " + - "Y=({7:F4},{8:F4},{9:F4}), " + - "Z=({10:F4},{11:F4},{12:F4})", - animatedObject.DisplayName, - state.Position.X, state.Position.Y, state.Position.Z, - linear.Get(0, 0), linear.Get(1, 0), linear.Get(2, 0), - linear.Get(0, 1), linear.Get(1, 1), linear.Get(2, 1), - linear.Get(0, 2), linear.Get(1, 2), linear.Get(2, 2))); - } - - return state; - } - catch (Exception ex) + // 从 PathAnimationManager 获取当前实际姿态,不再退回工具层旧 yaw 快照语义。 + var currentYaw = pam.CurrentYaw; + var currentRotation = pam.TrackedRotation; + var hasCustomRotation = pam.HasTrackedRotation; + var currentState = pam.GetObjectCurrentPosition(animatedObject); + pam.SaveObjectState(animatedObject); + + var state = new ModelItemTransformHelper.ObjectStateSnapshot { - LogManager.Error(string.Format("保存动画物体状态失败: {0}", ex.Message), ex); - return null; + Position = currentState.Position, + Rotation = currentRotation, + HasCustomRotation = hasCustomRotation + }; + + LogManager.Info(string.Format("已保存动画物体状态: {0}, 位置=({1:F2},{2:F2},{3:F2}), 朝向={4:F2}°, customRotation={5}", + animatedObject.DisplayName, state.Position.X, state.Position.Y, state.Position.Z, + currentYaw * 180 / Math.PI, state.HasCustomRotation)); + if (state.HasCustomRotation && state.Rotation != null) + { + var linear = new Transform3D(state.Rotation).Linear; + LogManager.Info(string.Format( + "[报告姿态保存] {0} 保存姿态: " + + "位置=({1:F3},{2:F3},{3:F3}), " + + "X=({4:F4},{5:F4},{6:F4}), " + + "Y=({7:F4},{8:F4},{9:F4}), " + + "Z=({10:F4},{11:F4},{12:F4})", + animatedObject.DisplayName, + state.Position.X, state.Position.Y, state.Position.Z, + linear.Get(0, 0), linear.Get(1, 0), linear.Get(2, 0), + linear.Get(0, 1), linear.Get(1, 1), linear.Get(2, 1), + linear.Get(0, 2), linear.Get(1, 2), linear.Get(2, 2))); } + + return state; } /// @@ -152,76 +150,34 @@ namespace NavisworksTransport.Utils { if (animatedObject == null || state == null) return; - try + if (state.HasCustomRotation && state.Rotation != null) { - if (state.HasCustomRotation && state.Rotation != null) - { - var linear = new Transform3D(state.Rotation).Linear; - LogManager.Info(string.Format( - "[报告姿态恢复] {0} 恢复目标姿态: " + - "位置=({1:F3},{2:F3},{3:F3}), " + - "X=({4:F4},{5:F4},{6:F4}), " + - "Y=({7:F4},{8:F4},{9:F4}), " + - "Z=({10:F4},{11:F4},{12:F4})", - animatedObject.DisplayName, - state.Position.X, state.Position.Y, state.Position.Z, - linear.Get(0, 0), linear.Get(1, 0), linear.Get(2, 0), - linear.Get(0, 1), linear.Get(1, 1), linear.Get(2, 1), - linear.Get(0, 2), linear.Get(1, 2), linear.Get(2, 2))); - } - - var pam = PathAnimationManager.GetInstance(); - if (pam != null && pam.ControlsAnimatedObject(animatedObject)) - { - pam.RestoreAnimatedObjectState(animatedObject); - LogManager.Info(string.Format( - "动画物体已通过PathAnimationManager恢复状态: {0}, customRotation={1}", - animatedObject.DisplayName, - state.HasCustomRotation)); - return; - } - - if (state.HasCustomRotation) - { - bool isVirtualWithCustomRotation = VirtualObjectManager.Instance.IsVirtualObjectActive && - VirtualObjectManager.Instance.CurrentVirtualObject == animatedObject; - if (isVirtualWithCustomRotation) - { - ModelItemTransformHelper.RestoreObjectStateWithScale(animatedObject, state); - } - else - { - ModelItemTransformHelper.RestoreObjectState(animatedObject, state); - } - - LogManager.Info(string.Format("动画物体已通过状态快照恢复三维姿态: {0}", animatedObject.DisplayName)); - return; - } - - // 检查是否是虚拟物体 - bool isVirtual = VirtualObjectManager.Instance.IsVirtualObjectActive && - VirtualObjectManager.Instance.CurrentVirtualObject == animatedObject; - - if (isVirtual) - { - // 虚拟物体:使用带当前缩放的移动方法 - ModelItemTransformHelper.MoveItemToPositionAndYawWithCurrentScale( - animatedObject, state.Position, state.YawRadians); - LogManager.Info(string.Format("虚拟物体已恢复到原始状态: {0}, 位置=({1:F2},{2:F2},{3:F2}), 朝向={4:F2}°", - animatedObject.DisplayName, state.Position.X, state.Position.Y, state.Position.Z, - state.YawRadians * 180 / Math.PI)); - } - else - { - // 普通物体:使用标准恢复 - ModelItemTransformHelper.RestoreObjectState(animatedObject, state); - LogManager.Info(string.Format("动画物体已恢复到原始状态: {0}", animatedObject.DisplayName)); - } + var linear = new Transform3D(state.Rotation).Linear; + LogManager.Info(string.Format( + "[报告姿态恢复] {0} 恢复目标姿态: " + + "位置=({1:F3},{2:F3},{3:F3}), " + + "X=({4:F4},{5:F4},{6:F4}), " + + "Y=({7:F4},{8:F4},{9:F4}), " + + "Z=({10:F4},{11:F4},{12:F4})", + animatedObject.DisplayName, + state.Position.X, state.Position.Y, state.Position.Z, + linear.Get(0, 0), linear.Get(1, 0), linear.Get(2, 0), + linear.Get(0, 1), linear.Get(1, 1), linear.Get(2, 1), + linear.Get(0, 2), linear.Get(1, 2), linear.Get(2, 2))); } - catch (Exception ex) + + var pam = PathAnimationManager.GetInstance(); + if (pam == null || !pam.ControlsAnimatedObject(animatedObject)) { - LogManager.Error(string.Format("恢复动画物体状态失败: {0}", ex.Message), ex); + throw new InvalidOperationException( + $"恢复碰撞场景前的动画物体状态必须复用 PathAnimationManager:对象 {animatedObject.DisplayName} 不受当前动画管理器控制。"); } + + pam.RestoreAnimatedObjectState(animatedObject); + LogManager.Info(string.Format( + "动画物体已通过PathAnimationManager恢复状态: {0}, customRotation={1}", + animatedObject.DisplayName, + state.HasCustomRotation)); } } } diff --git a/src/Utils/ModelItemTransformHelper.cs b/src/Utils/ModelItemTransformHelper.cs index eb2f8d6..20e76ee 100644 --- a/src/Utils/ModelItemTransformHelper.cs +++ b/src/Utils/ModelItemTransformHelper.cs @@ -1237,197 +1237,8 @@ namespace NavisworksTransport.Utils public class ObjectStateSnapshot { public Point3D Position { get; set; } - public double YawRadians { get; set; } public Rotation3D Rotation { get; set; } public bool HasCustomRotation { get; set; } - public Transform3D Transform { get; set; } - } - - /// - /// 保存物体当前状态 - /// 注意:YawRadians 通过当前位置计算,因为 Transform 返回的是CAD原始值 - /// - public static ObjectStateSnapshot SaveObjectState( - ModelItem item, - double? currentYaw = null, - Point3D currentPosition = null, - Rotation3D currentRotation = null, - bool hasCustomRotation = false) - { - if (item == null) return null; - - var bounds = item.BoundingBox(); - - // 🔥 关键:如果提供了当前朝向(如 PathAnimationManager._currentYaw),使用它 - // 否则从 Transform 获取(但这可能不是实际朝向) - double yaw; - if (currentYaw.HasValue) - { - yaw = currentYaw.Value; - } - else - { - // 尝试通过包围盒方向计算(如果物体有几何特征) - yaw = GetYawFromTransform(item.Transform); - LogManager.Debug($"[SaveObjectState] 未提供当前朝向,使用Transform: {yaw * 180 / Math.PI:F2}°"); - } - - return new ObjectStateSnapshot - { - Position = currentPosition ?? new Point3D(bounds.Center.X, bounds.Center.Y, bounds.Min.Z), - YawRadians = yaw, - Rotation = currentRotation ?? Rotation3D.Identity, - HasCustomRotation = hasCustomRotation, - Transform = item.Transform - }; - } - - /// - /// 从状态快照恢复物体位置和朝向(标准版本,会重置缩放) - /// - public static void RestoreObjectState(ModelItem item, ObjectStateSnapshot state) - { - RestoreObjectStateInternal(item, state, preserveScale: false); - } - - /// - /// 从状态快照恢复物体位置和朝向(保留缩放版本,用于虚拟物体) - /// - public static void RestoreObjectStateWithScale(ModelItem item, ObjectStateSnapshot state) - { - RestoreObjectStateInternal(item, state, preserveScale: true); - } - - /// - /// 从状态快照恢复物体位置的内部实现 - /// - private static void RestoreObjectStateInternal(ModelItem item, ObjectStateSnapshot state, bool preserveScale) - { - if (item == null || state == null) return; - - if (state.HasCustomRotation) - { - if (preserveScale) - { - MoveItemToPositionAndRotationWithCurrentScale(item, state.Position, state.Rotation); - } - else - { - MoveItemToPositionAndRotation(item, state.Position, state.Rotation); - } - return; - } - - var doc = Application.ActiveDocument; - var modelItems = new ModelItemCollection { item }; - - // 1. 先回到CAD原始位置 - doc.Models.ResetPermanentTransform(modelItems); - - // 2. 从CAD原始位置移动到保存的位置 - // 获取CAD原始状态 - var originalBounds = item.BoundingBox(); - var originalCenterPos = originalBounds.Center; - var originalYaw = GetYawFromTransform(item.Transform); - - // 计算到保存位置的增量 - var deltaPos = new Vector3D( - state.Position.X - originalCenterPos.X, - state.Position.Y - originalCenterPos.Y, - state.Position.Z - originalCenterPos.Z - ); - double deltaYaw = state.YawRadians - originalYaw; - - // 应用增量变换 - Transform3D transform; - if (Math.Abs(deltaYaw) > 0.001) - { - double cos = Math.Cos(deltaYaw); - double sin = Math.Sin(deltaYaw); - double rotatedX = originalCenterPos.X * cos - originalCenterPos.Y * sin; - double rotatedY = originalCenterPos.X * sin + originalCenterPos.Y * cos; - - var compensatedTranslation = new Vector3D( - state.Position.X - rotatedX, - state.Position.Y - rotatedY, - state.Position.Z - originalCenterPos.Z - ); - - var identity = Transform3D.CreateTranslation(new Vector3D(0, 0, 0)); - var components = identity.Factor(); - components.Rotation = new Rotation3D(new UnitVector3D(0, 0, 1), deltaYaw); - components.Translation = compensatedTranslation; - transform = components.Combine(); - } - else - { - transform = Transform3D.CreateTranslation(deltaPos); - } - - doc.Models.OverridePermanentTransform(modelItems, transform, false); - } - - /// - /// 将物体移动到指定位置和朝向,同时保持当前缩放(专为虚拟物体设计) - /// - public static void MoveItemToPositionAndYawWithCurrentScale(ModelItem item, Point3D targetPosition, double targetYaw) - { - var doc = Application.ActiveDocument; - var modelItems = new ModelItemCollection { item }; - - // 获取当前变换中的缩放 - var currentTransform = item.Transform; - var currentComponents = currentTransform.Factor(); - var currentScale = currentComponents.Scale; - - // 重置到CAD原始状态 - doc.Models.ResetPermanentTransform(modelItems); - - // 获取CAD原始状态 - var originalBounds = item.BoundingBox(); - var originalCenterPos = originalBounds.Center; - var originalYaw = GetYawFromTransform(item.Transform); - - // 计算从CAD原始位置到目标位置的增量 - var deltaPos = new Vector3D( - targetPosition.X - originalCenterPos.X, - targetPosition.Y - originalCenterPos.Y, - targetPosition.Z - originalCenterPos.Z - ); - double deltaYaw = targetYaw - originalYaw; - - // 构建变换组件,保留原有缩放 - var identity = Transform3D.CreateTranslation(new Vector3D(0, 0, 0)); - var components = identity.Factor(); - components.Scale = currentScale; // 保留当前缩放 - - if (Math.Abs(deltaYaw) > 0.001) - { - components.Rotation = new Rotation3D(new UnitVector3D(0, 0, 1), deltaYaw); - } - - // 计算平移(考虑旋转带来的位置偏移) - if (Math.Abs(deltaYaw) > 0.001) - { - double cos = Math.Cos(deltaYaw); - double sin = Math.Sin(deltaYaw); - double rotatedX = originalCenterPos.X * cos - originalCenterPos.Y * sin; - double rotatedY = originalCenterPos.X * sin + originalCenterPos.Y * cos; - - components.Translation = new Vector3D( - targetPosition.X - rotatedX, - targetPosition.Y - rotatedY, - targetPosition.Z - originalCenterPos.Z - ); - } - else - { - components.Translation = deltaPos; - } - - // 应用组合变换 - Transform3D transform = components.Combine(); - doc.Models.OverridePermanentTransform(modelItems, transform, false); } } }