恢复地面路径为3月25号版本

This commit is contained in:
tian 2026-04-05 01:36:24 +08:00
parent e21e934705
commit fb9dac9953
3 changed files with 201 additions and 140 deletions

2
.gitignore vendored
View File

@ -15,3 +15,5 @@ navisworks_api/
*.exe *.exe
*.db *.db
.codex-temp

View File

@ -813,6 +813,7 @@ namespace NavisworksTransport.Core.Animation
$"[路径起点诊断] 起点应用后实际trackedPoint=({startAppliedPoint.X:F3},{startAppliedPoint.Y:F3},{startAppliedPoint.Z:F3}), " + $"[路径起点诊断] 起点应用后实际trackedPoint=({startAppliedPoint.X:F3},{startAppliedPoint.Y:F3},{startAppliedPoint.Z:F3}), " +
$"相对目标偏差=({startAppliedPoint.X - startPosition.X:F3},{startAppliedPoint.Y - startPosition.Y:F3},{startAppliedPoint.Z - startPosition.Z:F3})"); $"相对目标偏差=({startAppliedPoint.X - startPosition.X:F3},{startAppliedPoint.Y - startPosition.Y:F3},{startAppliedPoint.Z - startPosition.Z:F3})");
// 🔥 起点不再进行二次补偿,旋转偏移由 MoveItemIncrementallyToTrackedPositionAndRotation 内部处理
if (IsRealObjectMode && _route.PathType == PathType.Ground) if (IsRealObjectMode && _route.PathType == PathType.Ground)
{ {
var startOffset = new Vector3D( var startOffset = new Vector3D(
@ -825,36 +826,20 @@ namespace NavisworksTransport.Core.Animation
startOffset.Z * startOffset.Z); startOffset.Z * startOffset.Z);
LogManager.Info( LogManager.Info(
$"[路径起点补偿] 首次落位偏差=({startOffset.X:F3},{startOffset.Y:F3},{startOffset.Z:F3}), 长度={startOffsetLength:F3}"); $"[路径起点诊断] 落位偏差=({startOffset.X:F3},{startOffset.Y:F3},{startOffset.Z:F3}), 长度={startOffsetLength:F3} (仅记录,不二次补偿)");
if (startOffsetLength > 1e-3) // 不再设置 _groundRealObjectStartCompensation也不再调用二次 UpdateObjectPosition
{
_groundRealObjectStartCompensation = startOffset;
_hasGroundRealObjectStartCompensation = true;
UpdateObjectPosition(startPosition, planarRotation);
var correctedAppliedPoint = GetTrackedObjectPosition(CurrentControlledObject ?? _animatedObject);
LogManager.Info(
$"[路径起点补偿] 补偿后实际trackedPoint=({correctedAppliedPoint.X:F3},{correctedAppliedPoint.Y:F3},{correctedAppliedPoint.Z:F3}), " +
$"相对目标偏差=({correctedAppliedPoint.X - startPosition.X:F3},{correctedAppliedPoint.Y - startPosition.Y:F3},{correctedAppliedPoint.Z - startPosition.Z:F3})");
}
else
{
_groundRealObjectStartCompensation = new Vector3D(0, 0, 0); _groundRealObjectStartCompensation = new Vector3D(0, 0, 0);
_hasGroundRealObjectStartCompensation = false; _hasGroundRealObjectStartCompensation = false;
} }
}
if (IsRealObjectMode && _route.PathType == PathType.Ground) if (IsRealObjectMode && _route.PathType == PathType.Ground)
{ {
_groundRealObjectBaseRotation = planarRotation; _groundRealObjectBaseRotation = planarRotation;
_hasGroundRealObjectBasePose = TryResolvePlanarRealObjectBaseYaw(PathType.Ground, out _groundRealObjectBaseYaw); _hasGroundRealObjectBasePose = TryResolveGroundRealObjectBaseYaw(out _groundRealObjectBaseYaw);
LogManager.Info( LogManager.Info(
$"[Ground真实物体基姿态] {animatedObject.DisplayName} BaseYaw={_groundRealObjectBaseYaw * 180.0 / Math.PI:F2}°, " + $"[Ground真实物体基姿态] {animatedObject.DisplayName} BaseYaw={_groundRealObjectBaseYaw * 180.0 / Math.PI:F2}°, " +
$"已记录基姿态={_hasGroundRealObjectBasePose}, " + $"已记录基姿态={_hasGroundRealObjectBasePose} (旋转偏移由逐帧方法内部处理)");
$"起点补偿=({_groundRealObjectStartCompensation.X:F3},{_groundRealObjectStartCompensation.Y:F3},{_groundRealObjectStartCompensation.Z:F3}), " +
$"已启用补偿={_hasGroundRealObjectStartCompensation}");
} }
else if (IsRealObjectMode && _route.PathType == PathType.Hoisting) else if (IsRealObjectMode && _route.PathType == PathType.Hoisting)
{ {
@ -2758,7 +2743,7 @@ namespace NavisworksTransport.Core.Animation
try try
{ {
ModelItem controlledObject = CurrentControlledObject; ModelItem controlledObject = CurrentControlledObject;
bool usesRealObjectOverrideRotation = ShouldUseRealObjectOverrideRotation(IsRealObjectMode) && controlledObject != null; bool isRailRealObject = _route?.PathType == PathType.Rail && IsRealObjectMode && controlledObject != null;
if (controlledObject == null) if (controlledObject == null)
{ {
return; return;
@ -2782,67 +2767,43 @@ namespace NavisworksTransport.Core.Animation
Point3D currentPositionForTransform = _trackedPosition; Point3D currentPositionForTransform = _trackedPosition;
Rotation3D currentRotation; Rotation3D currentRotation;
Rotation3D currentRotationForTransform;
Rotation3D actualGeometryRotation = Rotation3D.Identity;
bool hasActualGeometryRotation = false;
Rotation3D appliedTargetRotation = newRotation; Rotation3D appliedTargetRotation = newRotation;
Rotation3D targetRotationForTransform = newRotation;
Point3D appliedTargetPosition = newPosition; Point3D appliedTargetPosition = newPosition;
Rotation3D referenceRotation = IsRealObjectMode && _hasRealObjectReferenceRotation if (_hasTrackedRotation)
? CoordinateSystemManager.Instance.CreateHostAdapter().FromHostQuaternionDirect(_realObjectReferenceRotation) {
: Rotation3D.Identity; currentRotation = _trackedRotation;
Rotation3D transformRotation = controlledObject.Transform.Factor().Rotation; }
PathType currentPathType = _route?.PathType ?? PathType.Ground; else if (IsRealObjectMode && _hasRealObjectReferenceRotation)
currentRotation = ResolveCurrentRotationBaseline( {
currentPathType, currentRotation = CoordinateSystemManager.Instance
IsRealObjectMode, .CreateHostAdapter()
_hasTrackedRotation, .FromHostQuaternionDirect(_realObjectReferenceRotation);
_trackedRotation, }
_hasRealObjectReferenceRotation, else
referenceRotation, {
transformRotation, currentRotation = controlledObject.Transform.Factor().Rotation;
hasActualGeometryRotation: false, }
actualGeometryRotation: Rotation3D.Identity);
try try
{ {
var actualHostPosition = GetTrackedObjectPosition(controlledObject); var actualHostPosition = GetTrackedObjectPosition(controlledObject);
currentPositionForTransform = actualHostPosition; currentPositionForTransform = actualHostPosition;
LogManager.Debug( LogManager.Info(
$"[动画姿态入口] {controlledObject.DisplayName} 宿主即时读回点=({actualHostPosition.X:F3},{actualHostPosition.Y:F3},{actualHostPosition.Z:F3})"); $"[动画姿态入口] {controlledObject.DisplayName} 宿主即时读回点=({actualHostPosition.X:F3},{actualHostPosition.Y:F3},{actualHostPosition.Z:F3})");
if (IsRealObjectMode && if (IsRealObjectMode &&
(_route?.PathType == PathType.Ground || (_route?.PathType == PathType.Ground || _route?.PathType == PathType.Hoisting) &&
_route?.PathType == PathType.Hoisting || ModelItemTransformHelper.TryGetCurrentGeometryRotation(controlledObject, out var actualGeometryRotation))
_route?.PathType == PathType.Rail) &&
ModelItemTransformHelper.TryGetCurrentGeometryRotation(controlledObject, out actualGeometryRotation))
{ {
hasActualGeometryRotation = true;
currentRotation = ResolveCurrentRotationBaseline(
currentPathType,
IsRealObjectMode,
_hasTrackedRotation,
_trackedRotation,
_hasRealObjectReferenceRotation,
referenceRotation,
transformRotation,
hasActualGeometryRotation,
actualGeometryRotation);
var trackedLinear = new Transform3D(currentRotation).Linear; var trackedLinear = new Transform3D(currentRotation).Linear;
var actualLinear = new Transform3D(actualGeometryRotation).Linear; var actualLinear = new Transform3D(actualGeometryRotation).Linear;
string poseTag = _route?.PathType == PathType.Rail LogManager.Info(
? "[Rail姿态基线诊断]" $"[平面姿态基线诊断] {controlledObject.DisplayName} 跟踪旋转: " +
: "[平面姿态基线诊断]";
string baselineLabel = usesRealObjectOverrideRotation
? "当前姿态基线"
: "当前跟踪姿态";
LogManager.Debug(
$"{poseTag} {controlledObject.DisplayName} {baselineLabel}: " +
$"X=({trackedLinear.Get(0, 0):F4},{trackedLinear.Get(1, 0):F4},{trackedLinear.Get(2, 0):F4}), " + $"X=({trackedLinear.Get(0, 0):F4},{trackedLinear.Get(1, 0):F4},{trackedLinear.Get(2, 0):F4}), " +
$"Y=({trackedLinear.Get(0, 1):F4},{trackedLinear.Get(1, 1):F4},{trackedLinear.Get(2, 1):F4}), " + $"Y=({trackedLinear.Get(0, 1):F4},{trackedLinear.Get(1, 1):F4},{trackedLinear.Get(2, 1):F4}), " +
$"Z=({trackedLinear.Get(0, 2):F4},{trackedLinear.Get(1, 2):F4},{trackedLinear.Get(2, 2):F4})"); $"Z=({trackedLinear.Get(0, 2):F4},{trackedLinear.Get(1, 2):F4},{trackedLinear.Get(2, 2):F4})");
LogManager.Debug( LogManager.Info(
$"{poseTag} {controlledObject.DisplayName} 实际几何旋转: " + $"[平面姿态基线诊断] {controlledObject.DisplayName} 实际几何旋转: " +
$"X=({actualLinear.Get(0, 0):F4},{actualLinear.Get(1, 0):F4},{actualLinear.Get(2, 0):F4}), " + $"X=({actualLinear.Get(0, 0):F4},{actualLinear.Get(1, 0):F4},{actualLinear.Get(2, 0):F4}), " +
$"Y=({actualLinear.Get(0, 1):F4},{actualLinear.Get(1, 1):F4},{actualLinear.Get(2, 1):F4}), " + $"Y=({actualLinear.Get(0, 1):F4},{actualLinear.Get(1, 1):F4},{actualLinear.Get(2, 1):F4}), " +
$"Z=({actualLinear.Get(0, 2):F4},{actualLinear.Get(1, 2):F4},{actualLinear.Get(2, 2):F4})"); $"Z=({actualLinear.Get(0, 2):F4},{actualLinear.Get(1, 2):F4},{actualLinear.Get(2, 2):F4})");
@ -2852,93 +2813,54 @@ namespace NavisworksTransport.Core.Animation
{ {
LogManager.Warning($"[动画姿态入口] 读取宿主实际状态失败: {ex.Message}"); LogManager.Warning($"[动画姿态入口] 读取宿主实际状态失败: {ex.Message}");
} }
currentRotationForTransform = currentRotation;
if (usesRealObjectOverrideRotation) var currentLinear = new Transform3D(currentRotation).Linear;
var targetLinear = new Transform3D(appliedTargetRotation).Linear;
LogManager.Info(
$"[动画姿态入口] {controlledObject.DisplayName} 跟踪点=({_trackedPosition.X:F3},{_trackedPosition.Y:F3},{_trackedPosition.Z:F3}), " +
$"目标点=({appliedTargetPosition.X:F3},{appliedTargetPosition.Y:F3},{appliedTargetPosition.Z:F3})");
LogManager.Info(
$"[动画姿态入口] {controlledObject.DisplayName} 跟踪姿态: " +
$"X=({currentLinear.Get(0, 0):F4},{currentLinear.Get(1, 0):F4},{currentLinear.Get(2, 0):F4}), " +
$"Y=({currentLinear.Get(0, 1):F4},{currentLinear.Get(1, 1):F4},{currentLinear.Get(2, 1):F4}), " +
$"Z=({currentLinear.Get(0, 2):F4},{currentLinear.Get(1, 2):F4},{currentLinear.Get(2, 2):F4})");
LogManager.Info(
$"[动画姿态入口] {controlledObject.DisplayName} 目标姿态: " +
$"X=({targetLinear.Get(0, 0):F4},{targetLinear.Get(1, 0):F4},{targetLinear.Get(2, 0):F4}), " +
$"Y=({targetLinear.Get(0, 1):F4},{targetLinear.Get(1, 1):F4},{targetLinear.Get(2, 1):F4}), " +
$"Z=({targetLinear.Get(0, 2):F4},{targetLinear.Get(1, 2):F4},{targetLinear.Get(2, 2):F4})");
// 🔥 Ground 路径使用带旋转偏移补偿的新方法
// Rail/Hoisting 保持原行为
if (_route?.PathType == PathType.Ground && IsRealObjectMode)
{ {
if (ModelItemTransformHelper.TryGetCurrentOverrideRotation(controlledObject, out var currentOverrideRotation)) ModelItemTransformHelper.MoveItemIncrementallyToTrackedPositionAndRotation(
{ controlledObject,
currentRotationForTransform = currentOverrideRotation; currentPositionForTransform,
currentRotation,
appliedTargetPosition,
appliedTargetRotation);
} }
else else
{ {
currentRotationForTransform = Rotation3D.Identity;
}
if (!ModelItemTransformHelper.TryResolveOverrideRotationForFinalTarget(
controlledObject,
appliedTargetRotation,
out targetRotationForTransform))
{
targetRotationForTransform = appliedTargetRotation;
}
}
if (IsRealObjectMode &&
_route?.PathType == PathType.Ground &&
!_suppressGroundRealObjectCompensation &&
_hasGroundRealObjectStartCompensation &&
_hasGroundRealObjectBasePose &&
TryRotateGroundRealObjectCompensation(appliedTargetRotation, out var rotatedCompensation))
{
appliedTargetPosition = new Point3D(
newPosition.X - rotatedCompensation.X,
newPosition.Y - rotatedCompensation.Y,
newPosition.Z - rotatedCompensation.Z);
LogManager.Debug(
$"[Ground路径补偿] {controlledObject.DisplayName} 原目标点=({newPosition.X:F3},{newPosition.Y:F3},{newPosition.Z:F3}), " +
$"起点补偿=({_groundRealObjectStartCompensation.X:F3},{_groundRealObjectStartCompensation.Y:F3},{_groundRealObjectStartCompensation.Z:F3}), " +
$"旋转后补偿=({rotatedCompensation.X:F3},{rotatedCompensation.Y:F3},{rotatedCompensation.Z:F3}), " +
$"应用目标点=({appliedTargetPosition.X:F3},{appliedTargetPosition.Y:F3},{appliedTargetPosition.Z:F3})");
}
var hostCurrentPoseLocalAxesLinear = new Transform3D(currentRotationForTransform).Linear;
var hostTargetDisplayPoseLocalAxesLinear = new Transform3D(appliedTargetRotation).Linear;
LogManager.Debug(
$"[动画姿态入口] {controlledObject.DisplayName} 跟踪点=({_trackedPosition.X:F3},{_trackedPosition.Y:F3},{_trackedPosition.Z:F3}), " +
$"目标点=({appliedTargetPosition.X:F3},{appliedTargetPosition.Y:F3},{appliedTargetPosition.Z:F3})");
string currentRotationLabel = usesRealObjectOverrideRotation
? "宿主覆盖姿态基线局部轴"
: "宿主当前跟踪姿态局部轴";
LogManager.Debug(
$"[动画姿态入口] {controlledObject.DisplayName} {currentRotationLabel}: " +
$"hostCurrentLocalXAxis=({hostCurrentPoseLocalAxesLinear.Get(0, 0):F4},{hostCurrentPoseLocalAxesLinear.Get(1, 0):F4},{hostCurrentPoseLocalAxesLinear.Get(2, 0):F4}), " +
$"hostCurrentLocalYAxis=({hostCurrentPoseLocalAxesLinear.Get(0, 1):F4},{hostCurrentPoseLocalAxesLinear.Get(1, 1):F4},{hostCurrentPoseLocalAxesLinear.Get(2, 1):F4}), " +
$"hostCurrentLocalZAxis=({hostCurrentPoseLocalAxesLinear.Get(0, 2):F4},{hostCurrentPoseLocalAxesLinear.Get(1, 2):F4},{hostCurrentPoseLocalAxesLinear.Get(2, 2):F4})");
LogManager.Debug(
$"[动画姿态入口] {controlledObject.DisplayName} 宿主目标显示姿态局部轴: " +
$"hostTargetDisplayLocalXAxis=({hostTargetDisplayPoseLocalAxesLinear.Get(0, 0):F4},{hostTargetDisplayPoseLocalAxesLinear.Get(1, 0):F4},{hostTargetDisplayPoseLocalAxesLinear.Get(2, 0):F4}), " +
$"hostTargetDisplayLocalYAxis=({hostTargetDisplayPoseLocalAxesLinear.Get(0, 1):F4},{hostTargetDisplayPoseLocalAxesLinear.Get(1, 1):F4},{hostTargetDisplayPoseLocalAxesLinear.Get(2, 1):F4}), " +
$"hostTargetDisplayLocalZAxis=({hostTargetDisplayPoseLocalAxesLinear.Get(0, 2):F4},{hostTargetDisplayPoseLocalAxesLinear.Get(1, 2):F4},{hostTargetDisplayPoseLocalAxesLinear.Get(2, 2):F4})");
if (usesRealObjectOverrideRotation)
{
var hostTargetOverridePoseLocalAxesLinear = new Transform3D(targetRotationForTransform).Linear;
LogManager.Debug(
$"[真实物体覆盖姿态] {controlledObject.DisplayName} 宿主目标覆盖姿态局部轴: " +
$"hostTargetOverrideLocalXAxis=({hostTargetOverridePoseLocalAxesLinear.Get(0, 0):F4},{hostTargetOverridePoseLocalAxesLinear.Get(1, 0):F4},{hostTargetOverridePoseLocalAxesLinear.Get(2, 0):F4}), " +
$"hostTargetOverrideLocalYAxis=({hostTargetOverridePoseLocalAxesLinear.Get(0, 1):F4},{hostTargetOverridePoseLocalAxesLinear.Get(1, 1):F4},{hostTargetOverridePoseLocalAxesLinear.Get(2, 1):F4}), " +
$"hostTargetOverrideLocalZAxis=({hostTargetOverridePoseLocalAxesLinear.Get(0, 2):F4},{hostTargetOverridePoseLocalAxesLinear.Get(1, 2):F4},{hostTargetOverridePoseLocalAxesLinear.Get(2, 2):F4})");
}
ModelItemTransformHelper.MoveItemIncrementallyToPositionAndRotation( ModelItemTransformHelper.MoveItemIncrementallyToPositionAndRotation(
controlledObject, controlledObject,
currentPositionForTransform, currentPositionForTransform,
currentRotationForTransform, currentRotation,
appliedTargetPosition, appliedTargetPosition,
targetRotationForTransform); appliedTargetRotation);
}
_trackedPosition = appliedTargetPosition; _trackedPosition = appliedTargetPosition;
_trackedRotation = appliedTargetRotation; _trackedRotation = appliedTargetRotation;
_hasTrackedRotation = true; _hasTrackedRotation = true;
_currentYaw = ModelItemTransformHelper.GetYawFromRotation(appliedTargetRotation); _currentYaw = ModelItemTransformHelper.GetYawFromRotation(appliedTargetRotation);
if (usesRealObjectOverrideRotation) if (isRailRealObject)
{ {
Point3D hostActualAfter = GetTrackedObjectPosition(controlledObject); Point3D hostActualAfter = GetTrackedObjectPosition(controlledObject);
LogManager.Debug( LogManager.Debug(
$"[真实物体姿态应用] 宿主最终跟踪中心=({hostActualAfter.X:F3},{hostActualAfter.Y:F3},{hostActualAfter.Z:F3}), " + $"[Rail姿态应用] 宿主最终跟踪中心=({hostActualAfter.X:F3},{hostActualAfter.Y:F3},{hostActualAfter.Z:F3}), " +
$"目标跟踪中心=({newPosition.X:F3},{newPosition.Y:F3},{newPosition.Z:F3}), " + $"目标跟踪中心=({newPosition.X:F3},{newPosition.Y:F3},{newPosition.Z:F3}), " +
$"偏差=({hostActualAfter.X - newPosition.X:F3},{hostActualAfter.Y - newPosition.Y:F3},{hostActualAfter.Z - newPosition.Z:F3})"); $"偏差=({hostActualAfter.X - newPosition.X:F3},{hostActualAfter.Y - newPosition.Y:F3},{hostActualAfter.Z - newPosition.Z:F3})");
} }
@ -4355,6 +4277,27 @@ namespace NavisworksTransport.Core.Animation
return true; return true;
} }
private bool TryResolveGroundRealObjectBaseYaw(out double yawRadians)
{
yawRadians = 0.0;
if (_route?.PathType != PathType.Ground ||
!IsRealObjectMode ||
_pathPoints == null ||
_pathPoints.Count < 2)
{
return false;
}
var hostType = CoordinateSystemManager.Instance.ResolvedType;
var hostPoints = new List<Vector3>(_pathPoints.Count);
for (int i = 0; i < _pathPoints.Count; i++)
{
hostPoints.Add(new Vector3((float)_pathPoints[i].X, (float)_pathPoints[i].Y, (float)_pathPoints[i].Z));
}
return PathTargetFrameResolver.TryResolvePlanarStartHostYaw(_route.PathType, hostPoints, hostType, out yawRadians);
}
private static double NormalizeRadians(double angle) private static double NormalizeRadians(double angle)
{ {
while (angle > Math.PI) while (angle > Math.PI)

View File

@ -591,6 +591,122 @@ namespace NavisworksTransport.Utils
LogIncrementalTransformActual(item, targetPosition, targetRotation); LogIncrementalTransformActual(item, targetPosition, targetRotation);
} }
public static void MoveItemIncrementallyToTrackedPositionAndRotation(
ModelItem item,
Point3D currentTrackedPosition,
Rotation3D currentRotation,
Point3D targetTrackedPosition,
Rotation3D targetRotation)
{
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
var doc = Application.ActiveDocument;
var modelItems = new ModelItemCollection { item };
Rotation3D deltaRotation = BuildDeltaRotation(currentRotation, targetRotation);
var currentLinear = new Transform3D(currentRotation).Linear;
var targetLinear = new Transform3D(targetRotation).Linear;
LogManager.Info(
$"[模型增量补偿] {item.DisplayName} 当前trackedPoint=({currentTrackedPosition.X:F3},{currentTrackedPosition.Y:F3},{currentTrackedPosition.Z:F3}), " +
$"目标trackedPoint=({targetTrackedPosition.X:F3},{targetTrackedPosition.Y:F3},{targetTrackedPosition.Z:F3})");
// LogManager.Debug(
// $"[模型增量补偿] {item.DisplayName} 当前旋转: " +
// $"X=({currentLinear.Get(0, 0):F4},{currentLinear.Get(1, 0):F4},{currentLinear.Get(2, 0):F4}), " +
// $"Y=({currentLinear.Get(0, 1):F4},{currentLinear.Get(1, 1):F4},{currentLinear.Get(2, 1):F4}), " +
// $"Z=({currentLinear.Get(0, 2):F4},{currentLinear.Get(1, 2):F4},{currentLinear.Get(2, 2):F4})");
// LogManager.Debug(
// $"[模型增量补偿] {item.DisplayName} 目标旋转: " +
// $"X=({targetLinear.Get(0, 0):F4},{targetLinear.Get(1, 0):F4},{targetLinear.Get(2, 0):F4}), " +
// $"Y=({targetLinear.Get(0, 1):F4},{targetLinear.Get(1, 1):F4},{targetLinear.Get(2, 1):F4}), " +
// $"Z=({targetLinear.Get(0, 2):F4},{targetLinear.Get(1, 2):F4},{targetLinear.Get(2, 2):F4})");
// LogGeometryLevelTransforms(item, "[模型增量补偿应用前][GeometryAPI]");
// 第1步将物体中心移到原点此时几何中心在原点
var toOrigin = Transform3D.CreateTranslation(new Vector3D(
-currentTrackedPosition.X,
-currentTrackedPosition.Y,
-currentTrackedPosition.Z));
doc.Models.OverridePermanentTransform(modelItems, toOrigin, false);
// 第2步在原点旋转
var rotationOnlyComponents = Transform3D.CreateTranslation(new Vector3D(0, 0, 0)).Factor();
rotationOnlyComponents.Rotation = deltaRotation;
var rotationOnly = rotationOnlyComponents.Combine();
doc.Models.OverridePermanentTransform(modelItems, rotationOnly, false);
// 🔥 关键:读取旋转后、平移前的包围盒中心(相对于几何中心的偏移)
Point3D centerAfterRotation = item.BoundingBox()?.Center ?? new Point3D(0, 0, 0);
// 这就是目标旋转下BoundingBox中心相对于几何中心的偏移
var rotationOffset = new Vector3D(
centerAfterRotation.X,
centerAfterRotation.Y,
centerAfterRotation.Z);
LogManager.Info(
$"[模型增量补偿] {item.DisplayName} 旋转后包围盒中心=({centerAfterRotation.X:F3},{centerAfterRotation.Y:F3},{centerAfterRotation.Z:F3}), " +
$"旋转偏移量=({rotationOffset.X:F3},{rotationOffset.Y:F3},{rotationOffset.Z:F3})");
// 🔥 关键修正:我们要几何中心对齐目标,而不是 BoundingBox 中心对齐目标
// rotationOffset = 旋转后 BoundingBox 中心相对于原点的位置
// 几何中心在原点,相对于 BoundingBox 中心的偏移 = -rotationOffset
// 所以 BoundingBox 中心应该位于 target + rotationOffset才能让几何中心对齐 target
var adjustedTargetPosition = new Point3D(
targetTrackedPosition.X + rotationOffset.X,
targetTrackedPosition.Y + rotationOffset.Y,
targetTrackedPosition.Z + rotationOffset.Z);
LogManager.Info(
$"[模型增量补偿] {item.DisplayName} 调整后目标位置=({adjustedTargetPosition.X:F3},{adjustedTargetPosition.Y:F3},{adjustedTargetPosition.Z:F3}), " +
$"补偿量=(+{rotationOffset.X:F3},+{rotationOffset.Y:F3},+{rotationOffset.Z:F3})");
// 第3步预落位到调整后的目标位置
var provisionalToTarget = Transform3D.CreateTranslation(new Vector3D(
adjustedTargetPosition.X,
adjustedTargetPosition.Y,
adjustedTargetPosition.Z));
doc.Models.OverridePermanentTransform(modelItems, provisionalToTarget, false);
Point3D actualTrackedPosition = item.BoundingBox()?.Center ?? new Point3D(0, 0, 0);
var correctionTranslation = new Vector3D(
adjustedTargetPosition.X - actualTrackedPosition.X,
adjustedTargetPosition.Y - actualTrackedPosition.Y,
adjustedTargetPosition.Z - actualTrackedPosition.Z);
LogManager.Info(
$"[模型增量补偿] {item.DisplayName} 预落位后实际trackedPoint=({actualTrackedPosition.X:F3},{actualTrackedPosition.Y:F3},{actualTrackedPosition.Z:F3}), " +
$"纠偏平移=({correctionTranslation.X:F3},{correctionTranslation.Y:F3},{correctionTranslation.Z:F3})");
if (Math.Abs(correctionTranslation.X) > 1e-6 ||
Math.Abs(correctionTranslation.Y) > 1e-6 ||
Math.Abs(correctionTranslation.Z) > 1e-6)
{
var correction = Transform3D.CreateTranslation(correctionTranslation);
doc.Models.OverridePermanentTransform(modelItems, correction, false);
LogManager.Info($"[模型增量补偿] {item.DisplayName} 已应用纠偏平移");
}
else
{
LogManager.Info($"[模型增量补偿] {item.DisplayName} 纠偏平移太小,跳过应用");
}
// 🔥 验证纠偏后的实际位置(包围盒中心应该偏离目标,但几何中心对齐目标)
Point3D finalTrackedPosition = item.BoundingBox()?.Center ?? new Point3D(0, 0, 0);
// 几何中心 = BoundingBox中心 - rotationOffset因为rotationOffset是BoundingBox中心相对于几何中心的偏移
var geometricCenterDeviation = new Vector3D(
targetTrackedPosition.X - (finalTrackedPosition.X - rotationOffset.X),
targetTrackedPosition.Y - (finalTrackedPosition.Y - rotationOffset.Y),
targetTrackedPosition.Z - (finalTrackedPosition.Z - rotationOffset.Z));
LogManager.Info(
$"[模型增量补偿] {item.DisplayName} 最终包围盒中心=({finalTrackedPosition.X:F3},{finalTrackedPosition.Y:F3},{finalTrackedPosition.Z:F3}), " +
$"几何中心偏差=({geometricCenterDeviation.X:F3},{geometricCenterDeviation.Y:F3},{geometricCenterDeviation.Z:F3})");
// LogIncrementalTransformActual(item, targetTrackedPosition, targetRotation);
}
/// <summary> /// <summary>
/// 读取物体当前实际几何姿态。 /// 读取物体当前实际几何姿态。
/// 优先使用 ModelGeometry.ActiveTransform因为 ModelItem.Transform 只反映原始设计变换。 /// 优先使用 ModelGeometry.ActiveTransform因为 ModelItem.Transform 只反映原始设计变换。