NavisworksTransport/doc/design/2026/auto-object-rotation-min-passage-projection-design.md
tian 7187bcf622 自动最优朝向: 黑盒实测模式
- 新增 ObjectPassageProjectionOptimizer(SO(3)粗搜索+Nelder-Mead)
- EditRotationWindow 加入"自动调整"按钮
- AnimationControlViewModel 实现黑盒实测评估(临时摆位→读BoundingBox→恢复)
- 设计文档和实现计划
2026-05-27 12:24:01 +08:00

7.9 KiB
Raw Permalink Blame History

自动调整物体姿态以最小化通行截面投影面积

更新时间2026-05-27

1. 背景

动画检测中的“调整物体”窗口目前支持手工输入 X/Y/Z 三轴角度修正。用户希望增加一个“自动调整”按钮:对任意动画物体,在路径起点处自动寻找一个合适姿态,让物体经过路径上的门洞、狭窄通道时具有最大通过性。

Navisworks 当前主要提供 AABB 包围盒,真实物体的 fragment 代表姿态只能大概判断方向,不足以作为自动调整的精确依据。因此本功能不能依赖 fragment 推断“物体真实方向”,也不能只做绕宿主 up 轴的单轴旋转。单轴 yaw 调整手工即可完成,不满足目标。

2. 目标

在“调整物体”窗口增加自动调整能力:

  • 支持三轴联动搜索,允许任意三维旋转。
  • 允许物体横放、倒放、斜放,不施加运输姿态限制。
  • 以路径起点方向为基准,最小化物体在门洞截面上的投影面积。
  • 在投影面积相同或接近时,优先选择投影高度更小的姿态,让物体尽量平放。
  • 结果写回现有 X/Y/Z 三个角度输入框,用户可继续手工微调。
  • 不依赖 fragment 方向作为优化真值。
  • 遵守宿主坐标系 / 内部坐标系 / 资产坐标系语义,不硬编码世界 Z 为 up。

3. 非目标

  • 不在本阶段判断真实门洞尺寸,也不保证某条路径一定可通过。
  • 不修改路径规划算法。
  • 不重建物体 mesh 或 OBB。
  • 不引入姿态限制,例如“保持底面朝下”或“禁止倒置”。
  • 不用静默 fallback 掩盖优化失败;失败应明确提示。

4. 坐标系语义

UI 输入、日志、用户看到的 X/Y/Z 角度仍按宿主坐标系解释。

路径起点方向使用宿主坐标系点计算:

  1. 取路径起点到下一个有效路径点的方向。
  2. 剔除宿主 up 分量,得到水平路径前进方向 HostPathForward
  3. 通过 HostCoordinateAdapter 获取宿主 upHostUp
  4. 截面横向方向为 HostSide = normalize(cross(HostPathForward, HostUp))

如果路径起始段过短或剔除 up 后方向退化,应继续查找后续有效路径段;若仍无法得到方向,则自动调整失败并提示用户。

5. 目标函数

自动调整的主目标函数是门洞截面投影面积:

Score(rotation) = ProjectedWidthAcrossPath(rotation) * ProjectedHeightAlongHostUp(rotation)

其中:

  • ProjectedWidthAcrossPath:物体在 HostSide 方向上的投影宽度。
  • ProjectedHeightAlongHostUp:物体在 HostUp 方向上的投影高度。
  • 路径前进方向上的长度不参与目标函数。

该目标符合“穿门”语义:门洞主要限制的是横向净宽和竖向净高,而不是物体沿路径方向占多长。

在工程现场中,门洞通常“宽度大于高度”,因此仅比较面积不够。两个姿态可能具有相同或非常接近的面积,但一个姿态更高、更窄,另一个姿态更低、更宽;实际通行时应优先选择更低、更平放的姿态。

因此最终排序应采用词典序或近似平局策略:

  1. 先最小化 ProjectedArea
  2. 当面积差异小于容差时,选择 ProjectedHeightAlongHostUp 更小的姿态。
  3. 当面积和高度都接近时,再选择 ProjectedWidthAcrossPath 更小的姿态。

面积容差建议使用相对容差,例如 1%,避免因为 AABB 或浮点误差导致高度明显更优的姿态被面积微小差异淘汰。

6. 推荐算法

采用业界常见的黑盒无导数优化路线:

6.1 全局粗搜索

在完整三维旋转空间中生成候选姿态,避免只绕某一轴或只优化 yaw。

候选生成应满足:

  • 覆盖三维姿态空间。
  • 结果确定性,不依赖随机数。
  • 粗搜索粒度可配置,默认优先保证交互速度。

可选实现:

  • 均匀方向采样加 roll 角采样。
  • Fibonacci sphere / icosphere 风格方向采样。
  • 固定欧拉角网格作为初始版本,但需要避免只覆盖少量手工角度。

6.2 局部精修

对粗搜索评分最好的若干候选执行无导数局部优化,例如:

  • Powell method。
  • Nelder-Mead simplex。

Navisworks AABB 目标函数不平滑,也不可求导,因此不使用梯度法。局部优化的终止条件应包含:

  • 最大迭代次数。
  • 角度步长阈值。
  • 评分改善阈值。

6.3 输出角度

优化器内部可用四元数表示候选姿态,最终需要转换为当前窗口使用的宿主 X/Y/Z 三轴角度修正,并写回:

  • RotationXDegrees
  • RotationYDegrees
  • RotationZDegrees

角度顺序必须遵守项目当前约束X -> Y -> Z对应 qz * qy * qx

7. 评估方式

第一阶段建议实现为纯几何优化器:

  • 输入物体三轴尺寸。
  • 输入宿主坐标系下的 HostPathForward / HostSide / HostUp
  • 输入候选旋转。
  • 输出截面投影宽度、高度、面积。

这样可以用单元测试充分锁定算法,不需要启动 Navisworks。

真实物体的 fragment 代表姿态不作为优化真值。若后续发现数学预测与 Navisworks 实际 AABB 存在明显偏差,再增加“慢速精确模式”:

  1. 保存当前动画物体状态。
  2. 临时应用候选姿态到路径起点。
  3. 读取 Navisworks 更新后的 AABB。
  4. 计算截面投影面积。
  5. 恢复状态。

慢速模式必须复用 PathAnimationManager / ModelItemTransformHelper 的现有姿态链路,不能绕过主链路直接写入临时补丁。

8. UI 行为

“调整物体”窗口增加一个“自动调整”按钮。

建议行为:

  1. 用户打开“调整物体”窗口。
  2. 点击“自动调整”。
  3. 系统根据当前路径起点方向、当前物体尺寸和宿主坐标系执行优化。
  4. 将最优 X/Y/Z 角度写入输入框。
  5. 用户可继续修改角度。
  6. 点击“确认”后沿用现有 ObjectStartPlacementRequest.CreateRotationCorrection(...) 链路。

自动调整失败时,窗口不关闭,并显示明确错误:

  • 未选择路径。
  • 路径点不足。
  • 起点方向退化。
  • 未选择动画物体。
  • 物体尺寸无效。
  • 优化器未找到有效姿态。

9. 测试计划

新增纯几何单元测试,建议放在 UnitTests/CoordinateSystem/

必须覆盖:

  • 长方体通过三轴旋转得到比初始姿态更小的截面面积。
  • 三轴优化能找到单轴 yaw 无法达到的更小截面面积。
  • YUpZUpHostUp 高度语义正确。
  • 路径横向宽度和宿主 up 高度共同参与目标函数。
  • 面积接近时优先选择投影高度更小的平放姿态。
  • 任意旋转允许倒置,不强制保持原 up 方向。
  • 优化结果确定性:同一输入多次运行输出一致。
  • 退化路径方向会失败而不是回退默认方向。

后续接入 UI 后,补充 ViewModel 或窗口级测试:

  • 点击自动调整后会更新 X/Y/Z 输入值。
  • 自动调整后确认仍走现有角度修正请求。
  • 失败时保留原输入值。

10. 实现落点

候选落点:

  • src/Utils/CoordinateSystem/ObjectPassageProjectionOptimizer.cs
  • UnitTests/CoordinateSystem/ObjectPassageProjectionOptimizerTests.cs
  • src/UI/WPF/Views/EditRotationWindow.xaml
  • src/UI/WPF/Views/EditRotationWindow.xaml.cs
  • src/UI/WPF/ViewModels/AnimationControlViewModel.cs

如果需要从 ViewModel 提供路径和尺寸上下文,可新增一个小的请求对象,避免窗口直接依赖大型 ViewModel。

11. 风险与注意事项

  • Euler 角存在多解和万向节锁风险优化内部应优先用四元数Euler 只作为 UI 输出格式。
  • AABB 只能近似真实几何,通过性结果应理解为基于包围盒的保守估计。
  • 对真实物体fragment 仅可作为现有动画链路的弱参考,不作为自动调整的优化真值。
  • 对 Ground / Hoisting / Rail 的路径姿态链路不得引入旧 yaw fallback。
  • 若候选姿态会改变落位补偿,必须同步更新通行空间尺寸和起点预览。