fix: 贴地后用实际旋转物体到X轴方向测AABB获取准确通行空间尺寸

路径斜向时世界AABB投影偏大,纯数学旋转AABB也会膨胀。
改为用Navisworks API实际旋转物体到X轴方向测量AABB,再转回来:
- 算路径方向相对X轴的夹角 angleToX
- 绕hostUp旋转物体 -angleToX 使路径对齐X轴
- 测AABB:X=沿路径长度,up轴=高度,非up轴=宽度
- 转回来恢复姿态

清理STEP1-STEP6诊断日志,保留STEP7为正式日志。
This commit is contained in:
tian 2026-06-25 08:53:14 +08:00
parent 5308552b40
commit 3cb5d8d423

View File

@ -2293,15 +2293,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
var localN = Vector3.Normalize(Vector3.Transform(Vector3.Normalize(faceNormal), Quaternion.Inverse(psQ)));
var cadWorldN = Vector3.Normalize(Vector3.Transform(localN, cadQ));
// 诊断CAD复位后姿态和AABB
{
BoundingBox3D cadBb = item.BoundingBox();
LogManager.Info(
$"[贴合地面诊断-STEP1] CAD复位后: cadQ=({cadQ.X:F4},{cadQ.Y:F4},{cadQ.Z:F4},{cadQ.W:F4}), " +
$"AABB=({cadBb.Max.X - cadBb.Min.X:F3},{cadBb.Max.Y - cadBb.Min.Y:F3},{cadBb.Max.Z - cadBb.Min.Z:F3}), " +
$"faceNormal=({faceNormal.X:F4},{faceNormal.Y:F4},{faceNormal.Z:F4}), cadWorldN=({cadWorldN.X:F4},{cadWorldN.Y:F4},{cadWorldN.Z:F4})");
}
var t = -adapter.HostUpVector3;
float d = Vector3.Dot(cadWorldN, t);
Quaternion overrideQ;
@ -2362,18 +2353,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
out searchedWidthAcrossPath, out searchedHeightAlongUp, out searchedForwardExtent);
hasSearchedExtents = true;
// 诊断:搜索结果
double unitsToMetersDiag = UnitsConverter.GetUnitsToMetersConversionFactor();
LogManager.Info(
$"[贴合地面诊断-STEP2] 搜索完成: " +
$"faceDownOnly=({faceDownOnly.X:F4},{faceDownOnly.Y:F4},{faceDownOnly.Z:F4},{faceDownOnly.W:F4}), " +
$"overrideQ=({overrideQ.X:F4},{overrideQ.Y:F4},{overrideQ.Z:F4},{overrideQ.W:F4}), " +
$"搜索返回: 沿路径={searchedForwardExtent * unitsToMetersDiag:F2}m, " +
$"垂直={searchedWidthAcrossPath * unitsToMetersDiag:F2}m, " +
$"高度={searchedHeightAlongUp * unitsToMetersDiag:F2}m, " +
$"pathYaw={pathYawRadians * 180.0 / Math.PI:F2}°, " +
$"sizeX/Y/Z={sizeX:F2}/{sizeY:F2}/{sizeZ:F2}");
// 从结果反算实际 yaw 角度用于日志
Quaternion deltaQ = Quaternion.Normalize(
Quaternion.Inverse(faceDownOnly) * overrideQ);
@ -2392,14 +2371,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
id.Translation = new Vector3D(center.X - rtp.X, center.Y - rtp.Y, center.Z - rtp.Z);
doc.Models.OverridePermanentTransform(modelItems, id.Combine(), true);
// 诊断overrideQ 施加后 AABB
{
BoundingBox3D afterRotBb = item.BoundingBox();
LogManager.Info(
$"[贴合地面诊断-STEP3] overrideQ施加后: " +
$"AABB=({afterRotBb.Max.X - afterRotBb.Min.X:F3},{afterRotBb.Max.Y - afterRotBb.Min.Y:F3},{afterRotBb.Max.Z - afterRotBb.Min.Z:F3})");
}
// 旋转后平移:底边贴地 + 用户上下偏移
var hst = CoordinateSystemManager.Instance.ResolvedType;
var newBounds = item.BoundingBox();
@ -2414,27 +2385,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
hst == CoordinateSystemType.YUp ? ps.Z - newCenter.Z : groundLevel - objectBottom);
doc.Models.OverridePermanentTransform(modelItems, Transform3D.CreateTranslation(delta), false);
// 诊断:贴地平移后 AABB 和几何姿态
{
BoundingBox3D afterGroundBb = item.BoundingBox();
if (ModelItemTransformHelper.TryGetCurrentGeometryRotation(item, out var groundGeomRot))
{
var gl = new Transform3D(groundGeomRot).Linear;
LogManager.Info(
$"[贴合地面诊断-STEP4] 贴地平移后: " +
$"AABB=({afterGroundBb.Max.X - afterGroundBb.Min.X:F3},{afterGroundBb.Max.Y - afterGroundBb.Min.Y:F3},{afterGroundBb.Max.Z - afterGroundBb.Min.Z:F3}), " +
$"几何姿态X=({gl.Get(0,0):F4},{gl.Get(1,0):F4},{gl.Get(2,0):F4}), " +
$"Y=({gl.Get(0,1):F4},{gl.Get(1,1):F4},{gl.Get(2,1):F4}), " +
$"Z=({gl.Get(0,2):F4},{gl.Get(1,2):F4},{gl.Get(2,2):F4})");
}
else
{
LogManager.Info(
$"[贴合地面诊断-STEP4] 贴地平移后: " +
$"AABB=({afterGroundBb.Max.X - afterGroundBb.Min.X:F3},{afterGroundBb.Max.Y - afterGroundBb.Min.Y:F3},{afterGroundBb.Max.Z - afterGroundBb.Min.Z:F3}), 几何姿态读取失败");
}
}
// 把绝对贴地姿态转成"相对于 baseline 的 host 欧拉修正"。
// PathAnimationManager 增量链从 CAD 姿态出发,需要扣除 CAD 自带 yaw + pathYaw。
LocalEulerRotationCorrection resultCorrection;
@ -2456,10 +2406,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
_objectRotationCorrection = resultCorrection;
OnPropertyChanged(nameof(ObjectRotationCorrection));
LogManager.Info(
$"[贴合地面诊断-STEP5] correction={resultCorrection}, pathYaw={pathYawRadians * 180.0 / Math.PI:F2}°, " +
$"hasPathYaw={hasPathYaw}");
// 回写上下偏移:贴地时用实际包围盒贴地,但确认/动画后用 correction 重建姿态,
// 旋转后物体底边位置会变。与自动调整同方法:应用 correction 重建→测量底边→算 lift
// 测量后用新 correction+lift 完整重建,使物体停留在贴地等价姿态。
@ -2471,28 +2417,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
_objectGroundLiftHeightInMeters = computedLift;
_pathAnimationManager.SetObjectStartVerticalLiftDirect(_objectGroundLiftHeightInMeters);
// 诊断ComputeGroundLiftForCorrection 重建后
{
BoundingBox3D afterRebuildBb = item.BoundingBox();
if (ModelItemTransformHelper.TryGetCurrentGeometryRotation(item, out var rebuildGeomRot))
{
var gl = new Transform3D(rebuildGeomRot).Linear;
LogManager.Info(
$"[贴合地面诊断-STEP6] ComputeGroundLift后: " +
$"AABB=({afterRebuildBb.Max.X - afterRebuildBb.Min.X:F3},{afterRebuildBb.Max.Y - afterRebuildBb.Min.Y:F3},{afterRebuildBb.Max.Z - afterRebuildBb.Min.Z:F3}), " +
$"几何姿态X=({gl.Get(0,0):F4},{gl.Get(1,0):F4},{gl.Get(2,0):F4}), " +
$"Y=({gl.Get(0,1):F4},{gl.Get(1,1):F4},{gl.Get(2,1):F4}), " +
$"Z=({gl.Get(0,2):F4},{gl.Get(1,2):F4},{gl.Get(2,2):F4}), " +
$"lift={computedLift:F3}m");
}
else
{
LogManager.Info(
$"[贴合地面诊断-STEP6] ComputeGroundLift后: " +
$"AABB=({afterRebuildBb.Max.X - afterRebuildBb.Min.X:F3},{afterRebuildBb.Max.Y - afterRebuildBb.Min.Y:F3},{afterRebuildBb.Max.Z - afterRebuildBb.Min.Z:F3}), lift={computedLift:F3}m, 几何姿态读取失败");
}
}
// 物体已在最终贴地姿态ComputeGroundLiftForCorrection 重建完成)。
// 路径可能斜向直接测ABB投影偏大。实际旋转物体到X轴方向测AABB
// 再转回来——必须用Navisworks API实际旋转才能获取准确AABB。
@ -2539,8 +2463,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
doc.Models.OverridePermanentTransform(modelItems, rotateBack.Combine(), false);
double unitsToMeters = UnitsConverter.GetUnitsToMetersConversionFactor();
LogManager.Info(
$"[贴合地面诊断-STEP7] X轴对齐AABB(实测): 沿路径={_autoAabbSx * unitsToMeters:F2}m, " +
LogManager.Debug(
$"[贴合地面] X轴对齐AABB(实测): 沿路径={_autoAabbSx * unitsToMeters:F2}m, " +
$"垂直路径={_autoAabbSz * unitsToMeters:F2}m, " +
$"高度={_autoAabbSy * unitsToMeters:F2}m, angleToX={angleToX * 180.0 / Math.PI:F1}°");
}