# 坐标系统一架构实施清单 ## 1. 文档目的 本文档基于 [coordinate-system-canonical-space-design.md](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/doc/design/2026/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` 文件: - [PathEditingViewModel.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/UI/WPF/ViewModels/PathEditingViewModel.cs) 目标: - 终端安装辅助线全部改为基于 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` 文件: - [RailPathPoseHelper.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/Utils/RailPathPoseHelper.cs) 目标: - 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 动画输入边界 涉及文件: - [PathAnimationManager.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/Core/Animation/PathAnimationManager.cs) - [VirtualObjectManager.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/Core/VirtualObjectManager.cs) - [ModelItemTransformHelper.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/Utils/ModelItemTransformHelper.cs) 目标: - 动画内部只消费 Canonical 姿态 - 输出到 Navisworks 时再做反向转换 验收: - Rail 虚拟物体与真实模型在 Y-up / Z-up 项目中的姿态语义一致 ### Task 7.1 明确模型局部轴约定 目标: - 将“模型本地哪个轴代表 forward/up”从隐含假设提升为显式定义 需要覆盖: - 虚拟物体资源 - 终端安装辅助杆资源 - 真实模型在 `Y-up` / `Z-up` 项目中的默认局部轴约定 最低要求: - 至少明确 `LocalForwardAxis` - 至少明确 `LocalUpAxis` 验收: - 不再出现“路径方向和通行空间都正确,但真实模型仍按错误本地 up 站立”的现象 - `Y-up` 真实模型与 `Z-up` 真实模型都能通过显式局部轴约定接入 Rail 姿态链路 ## 4.4 M4 接入碰撞恢复和渲染 ### Task 8. 改造碰撞恢复链路 涉及文件: - [CollisionSceneHelper.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/Utils/CollisionSceneHelper.cs) - [GenerateCollisionReportCommand.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/Commands/GenerateCollisionReportCommand.cs) - [ClashDetectiveIntegration.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/Core/Collision/ClashDetectiveIntegration.cs) 目标: - 碰撞点恢复、报告截图、碰撞点回看全部使用统一的内部姿态语义 验收: - Rail 碰撞报告恢复位置和动画实际姿态一致 - 二维路径不被三维逻辑污染 ### Task 9. 改造渲染层 文件: - [PathPointRenderPlugin.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/Core/PathPointRenderPlugin.cs) - [AssemblyReferencePathManager.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/Core/AssemblyReferencePathManager.cs) 目标: - 辅助线、通行空间、点标记、碰撞点渲染,不再直接写死 `Normal = (0,0,1)` - 渲染层不仅要改“中心点/偏移量”,还要统一渲染几何的局部轴语义 验收: - Y-up 项目中,渲染法向和可视化朝向不再依赖世界 Z - Y-up 项目中,默认通行空间和 `SP` 模式通行空间的高度轴与宿主 up 一致 - 不再出现“中心点位置正确,但长方体/杆体本体仍按 Z-up 构造”的现象 实施提示: - 长方体、圆柱体、辅助杆这类几何渲染,必须同时检查: - 中心点是否正确 - `right/up/height` 局部轴是否正确 - `Normal` 是否仍偷用世界 `Z` - 不能只修改 `ApplyVerticalOffset(...)` 或中心点偏移,而保留旧的 `XY + Z` 轴构造公式 ## 5. 已知问题与注意事项 ### 5.1 当前不应优先展开的模块 以下模块虽然也存在坐标系写死问题,但暂不作为本轮主线: - [ChannelHeightDetector.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/PathPlanning/ChannelHeightDetector.cs) - [SlopeAnalyzer.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/PathPlanning/SlopeAnalyzer.cs) - [OptimizedHeightCalculator.cs](/C:/Users/Tellme/apps/NavisworksTransport-rail-mount-modes/src/PathPlanning/OptimizedHeightCalculator.cs) 原因: - 它们主要服务于自动路径规划 - 当前项目主线优先级不在这里 ### 5.2 不能依赖 fallback 掩盖问题 实施过程中禁止: - 三维路径恢复失败时偷偷退回 `yaw` - 外部坐标转换失败时偷偷按世界 `Z` 继续算 - 业务基准点缺失时默认球心为 `(0,0,0)` 必须让错误显式暴露。 ## 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. 备注 本清单服务于“先稳定非自动路径规划主线”的目标,不代表自动路径规划相关模块不重要。 后续如要继续推进全项目坐标系统一,应单独启动自动路径规划相关的第二阶段清理计划。