NavisworksTransport/doc/working/coordinate-system-canonical-space-implementation-plan.md

13 KiB
Raw Permalink Blame History

坐标系统一架构实施清单

1. 文档目的

本文档基于 coordinate-system-canonical-space-design.md 中的方案,拆解出一份可执行的实施清单。

目标不是一次性全项目重构,而是:

  • 先建立“外部坐标 -> 内部统一坐标 -> 业务基准坐标”的边界
  • 再优先改造当前最重要的非自动路径规划功能
  • 逐步把历史 Z-up 假设收口

2. 总体原则

2.1 本轮范围

当前优先范围:

  • 终端安装仿真
  • Rail 三维姿态
  • 动画播放
  • 碰撞检测与碰撞恢复
  • 辅助线、通行空间、碰撞点相关渲染

当前明确不优先处理:

  • 自动路径规划
  • 高度检测
  • 坡度分析
  • 旧网格高度/通道高度相关算法

2.2 内部统一坐标

当前实施目标固定为:

  • 内部统一坐标 = Canonical Space = Z-up

2.3 外部坐标定义

当前实施中,统一定义:

  • Navisworks API 返回的世界坐标 = 外部坐标

即:

  • Point3D
  • Vector3D
  • BoundingBox3D
  • Transform3D
  • Document.UpVector
  • ModelItem.BoundingBox()
  • 鼠标点击拾取点

都先视为外部输入。

3. 里程碑划分

M1. 建立坐标边界层

目标:

  • 引入统一的宿主坐标适配器
  • 不再在业务代码里直接解释 Navisworks 坐标

M2. 接入终端安装仿真

目标:

  • 终端安装仿真不再直接依赖世界原点和世界 Z
  • 球心与项目 up 都走统一边界层/业务基准层

M3. 接入 Rail 三维姿态

目标:

  • Rail 姿态和动画只认内部统一坐标
  • 不再在姿态 helper 中写死 (0,0,1)

M4. 接入碰撞恢复和可视化

目标:

  • 碰撞报告、碰撞点恢复、自动截图、辅助线渲染统一使用同一套内部语义

4. 任务清单

4.1 M1 建立坐标边界层

Task 1. 新增 HostCoordinateAdapter

目标:

  • 建立 Navisworks 外部坐标与内部统一坐标之间的唯一适配入口

建议职责:

  • ToCanonicalPoint(...)
  • ToCanonicalVector(...)
  • ToCanonicalBounds(...)
  • ToCanonicalTransform(...)
  • FromCanonicalPoint(...)
  • FromCanonicalVector(...)
  • FromCanonicalBounds(...)
  • FromCanonicalTransform(...)

建议要求:

  • 统一使用完整三维变换语义
  • 不再停留在 GetElevation()/GetHorizontalCoords() 这种偏二维接口
  • 点、向量、包围盒、旋转、变换都必须有明确变换规则
  • 坐标定义中必须显式暴露:
    • UpAxis
    • ElevationAxis
    • HorizontalPlane

验收:

  • 对同一组 Navisworks 输入,适配结果在 Y-up 和 Z-up 项目中都能稳定输出 Canonical Space 数据

Task 2. 新增 ProjectReferenceFrame

目标:

  • 承载业务基准点,不再把业务基准混进坐标系层

建议职责:

  • SphereCenterInCanonical
  • ProjectUpInCanonical
  • 终端安装参考方向
  • 轨道参考面

验收:

  • 程序内不再把世界原点直接当球心使用

Task 3. 约束边界:禁止业务代码直接解释宿主坐标

目标:

  • 收口“谁可以直接碰 Navisworks 坐标”

需要收口的入口:

  • 鼠标点击取点
  • ModelItem.BoundingBox()
  • Transform3D
  • Document.UpVector
  • 3D 渲染输入
  • 动画对象位姿输出

验收:

  • 新功能主链路中,业务代码不再直接从 BoundingBox().Center 开始做业务推导

4.2 M2 接入终端安装仿真

Task 4. 改造 PathEditingViewModel

文件:

目标:

  • 终端安装辅助线全部改为基于 Canonical Space + ProjectReferenceFrame

重点修改点:

  • BuildAssemblyReferenceLine()
  • GetAssemblyTerminalAnchorPoint()
  • 与辅助线、终点锚点、参考方向相关的计算

必须消除:

  • Vector3D direction = new Vector3D(centerPoint.X, centerPoint.Y, centerPoint.Z);
  • 直接把世界原点当球心

验收:

  • Y-up 项目中,若球心配置正确,辅助线方向与业务预期一致
  • Z-up 项目中,行为保持不退化

Task 5. 明确 UI 和日志的坐标语义

目标:

  • 终端安装相关 UI、日志输出不混淆内部坐标和外部坐标

建议:

  • 内部计算使用 Canonical
  • 对用户显示时,明确是否转回 Navisworks 外部坐标

验收:

  • 日志中坐标语义一致,不再出现“内部算的是一种,打印的是另一种”

4.3 M3 接入 Rail 三维姿态

Task 6. 改造 RailPathPoseHelper

文件:

目标:

  • Rail 姿态计算统一基于 Canonical Space

必须消除:

  • new Vector3D(0, 0, 1)
  • worldUp = new Vector3D(0, 0, 1)

替换方式:

  • 改用适配层提供的 Canonical up
  • 或由 ProjectReferenceFrame 提供项目参考 up

验收:

  • Y-up 项目与 Z-up 项目中Rail 参考方向一致、俯仰/侧倾逻辑一致

Task 7. 清理 Rail 动画输入边界

涉及文件:

目标:

  • 动画内部只消费 Canonical 姿态
  • 输出到 Navisworks 时再做反向转换

验收:

  • Rail 虚拟物体与真实模型在 Y-up / Z-up 项目中的姿态语义一致
  • 真实物体起点贴合和动画第一帧使用同一份固定物理尺寸语义
  • 不再允许从“已旋转后的当前 AABB”重新推导 Rail 物体高度
  • Rail 动画不再直接在业务层手写 forward/up/offset,而是复用基础工具
  • ClashDetective 三维候选验证必须直接复用 PathAnimationManager 主链路恢复,不允许先 ResetPermanentTransform 再复用 PAM

Task 7.2 新增 RailLocalFrame

目标:

  • Rail 局部坐标系正式提升为基础框架对象

最低要求:

  • Forward
  • Normal
  • Lateral

实施要求:

  • 先在纯数学层构建并测试
  • 再由 RailPathPoseHelper、动画、通行空间复用

验收:

  • 不再由业务代码自己拼切向/法向/侧向
  • Rail 的姿态、法向偏移、通行空间统一使用同一套局部坐标系

Task 7.3 新增“参考点 -> 跟踪中心点”偏移解析器

目标:

  • 将路径参考点到动画跟踪中心点的偏移,从业务代码中抽离成基础工具

实施要求:

  • 先以几何中心为统一动画跟踪点
  • 地面/吊装路径使用宿主 up 语义
  • Rail 路径使用 RailLocalFrame.Normal
  • 先补单测再接业务

验收:

  • PathAnimationManager 不再直接散落手写半高偏移
  • AnimatedObjectTrackedPosition 明确表示动画跟踪中心点

Task 7.1 明确模型局部轴约定

目标:

  • 将“模型本地哪个轴代表 forward/up”从隐含假设提升为显式定义

需要覆盖:

  • 虚拟物体资源
  • 终端安装辅助杆资源
  • 真实模型在 Y-up / Z-up 项目中的默认局部轴约定

最低要求:

  • 至少明确 LocalForwardAxis
  • 至少明确 LocalUpAxis

验收:

  • 不再出现“路径方向和通行空间都正确,但真实模型仍按错误本地 up 站立”的现象
  • Y-up 真实模型与 Z-up 真实模型都能通过显式局部轴约定接入 Rail 姿态链路

4.4 M4 接入碰撞恢复和渲染

Task 8. 改造碰撞恢复链路

涉及文件:

目标:

  • 碰撞点恢复、报告截图、碰撞点回看全部使用统一的内部姿态语义

验收:

  • Rail 碰撞报告恢复位置和动画实际姿态一致
  • 二维路径不被三维逻辑污染

实施提示:

  • 对真实物体,碰撞恢复和动画播放必须共用同一份固定物理尺寸语义
  • 不允许恢复链路偷偷退回“重新读取当前 AABB 再算高度/底面”

Task 9. 改造渲染层

文件:

目标:

  • 辅助线、通行空间、点标记、碰撞点渲染,不再直接写死 Normal = (0,0,1)
  • 渲染层不仅要改“中心点/偏移量”,还要统一渲染几何的局部轴语义

验收:

  • Y-up 项目中,渲染法向和可视化朝向不再依赖世界 Z
  • Y-up 项目中,默认通行空间和 SP 模式通行空间的高度轴与宿主 up 一致
  • 不再出现“中心点位置正确,但长方体/杆体本体仍按 Z-up 构造”的现象

实施提示:

  • 长方体、圆柱体、辅助杆这类几何渲染,必须同时检查:
    • 中心点是否正确
    • right/up/height 局部轴是否正确
    • Normal 是否仍偷用世界 Z
  • 不能只修改 ApplyVerticalOffset(...) 或中心点偏移,而保留旧的 XY + Z 轴构造公式

Task 9.1 通行空间与物体贴合语义统一

涉及文件:

目标:

  • 通行空间显示、起点贴合、动画帧贴合使用统一尺寸语义
  • Rail 轨上/轨下模式下,贴合面与留缝面保持一致

经验约束:

  • 轨下安装:顶面贴路径,底面留单侧间隙
  • 轨上安装:底面贴路径,顶面留单侧间隙
  • 真实物体尺寸必须在选择物体时固定下来,并传入动画管理器

验收:

  • 起点贴合正确后,动画第一帧不再出现固定间隙
  • 通行空间与真实物体的贴合面语义一致

5. 已知问题与注意事项

5.1 当前不应优先展开的模块

以下模块虽然也存在坐标系写死问题,但暂不作为本轮主线:

原因:

  • 它们主要服务于自动路径规划
  • 当前项目主线优先级不在这里

5.2 不能依赖 fallback 掩盖问题

实施过程中禁止:

  • 三维路径恢复失败时偷偷退回 yaw
  • 外部坐标转换失败时偷偷按世界 Z 继续算
  • 业务基准点缺失时默认球心为 (0,0,0)

必须让错误显式暴露。

5.3 不能使用不完整构建产物部署 WPF 插件

实施过程中必须区分:

  • 单元测试所需的程序集产物
  • 可用于 Navisworks 运行的完整 WPF 插件产物

对于本项目:

  • 仅有 TransportPlugin.dll 被复制成功,不代表插件可用
  • 还必须确保 TransportPlugin.g.resources 中包含完整的主视图 .baml

最低要求:

  • 主项目构建成功后再部署
  • 如遇异常,应检查关键资源是否存在:
    • LogisticsControlPanel.baml
    • PathEditingView.baml
    • AnimationControlView.baml
    • LayerManagementView.baml

否则可能出现:

  • 插件布局恢复失败
  • 手工打开插件窗口即崩溃

6. 当前实施优先顺序

建议实际推进顺序如下:

  1. HostCoordinateAdapter
  2. ProjectReferenceFrame
  3. PathEditingViewModel
  4. RailPathPoseHelper
  5. PathAnimationManager
  6. CollisionSceneHelper
  7. PathPointRenderPlugin

7. 完成判定

当以下条件同时满足时,可认为本轮非自动路径规划坐标系统一改造达到阶段目标:

  • 终端安装仿真在 Y-up / Z-up 项目中语义一致
  • Rail 三维姿态在 Y-up / Z-up 项目中语义一致
  • 动画播放与碰撞恢复姿态一致
  • 碰撞报告截图与实际动画姿态一致
  • 主链路业务代码中不再直接写死世界原点和世界 Z

8. 备注

本清单服务于“先稳定非自动路径规划主线”的目标,不代表自动路径规划相关模块不重要。

后续如要继续推进全项目坐标系统一,应单独启动自动路径规划相关的第二阶段清理计划。