NavisworksTransport/AGENTS.md

17 KiB
Raw Blame History

AGENTS.md

本文件面向后续会话中的 AI 编码助手。目标不是写一份“大而全”的历史说明,而是让新会话能快速理解:

  • 项目现在在做什么
  • 哪些架构已经稳定
  • 哪些开发原则不能再破坏
  • 遇到问题时优先看哪里

如果本文件与更细的专项文档冲突,优先参考:

  1. doc/working/current-engineering-state.md
  2. doc/design/2026/coordinate-system-canonical-space-design.md
  3. doc/design/2026/NavisworksAPI使用方法.md

1. 项目现状

NavisworksTransport 是一个面向 Autodesk Navisworks Manage 2026 的物流路径规划与动画仿真插件。

当前已经不只是“自动寻路”项目,而是一套同时覆盖以下能力的工程:

  • 物流属性与对象分类
  • 地面路径、吊装路径、Rail 路径编辑与可视化
  • 终端安装仿真
  • 动画播放、起点落位、终点诊断
  • ClashDetective 碰撞检测与恢复
  • 路径、检测记录、批处理相关数据存储

当前重点功能

  • Ground / Hoisting / Rail 三类路径
  • 真实物体与虚拟物体的起点摆放、动画姿态、通行空间
  • YUp / ZUp 两类宿主模型坐标系支持
  • 终端安装仿真中的:
    • 端面三点分析
    • 光轴辅助线
    • 安装面双点确定
    • 安装点与 Rail 法向联动

2. 技术栈与构建

  • 平台Navisworks Manage 2026
  • 框架:.NET Framework 4.8
  • 语言C# 7.3
  • 架构x64
  • UIWPF + Navisworks DockPane
  • 测试MSTest

关键脚本

  • compile.bat
  • run-unit-tests.bat
  • deploy-plugin.bat

极重要的执行顺序

构建和部署必须严格按顺序执行:

  1. ./run-unit-tests.bat(需要时)
  2. ./compile.bat
  3. 等待编译完整结束并确认成功
  4. ./deploy-plugin.bat

不要并行执行编译和部署。否则很容易把旧 DLL 部署到插件目录。

并行执行边界

后续会话中的 AI 助手必须把命令分成两类:

  • 允许并行的纯读取操作
    • rg
    • Get-Content
    • ls / Get-ChildItem
    • 读取日志
    • 查询状态
  • 禁止并行的产出型/宿主相关操作
    • run-unit-tests.bat
    • compile.bat
    • deploy-plugin.bat
    • 启动/关闭 Navisworks
    • 会占用 DLL、修改 bin/obj、写插件部署目录、依赖上一步产物的任何命令

硬约束:

  • 只有“纯读取、无副作用、且互不依赖”的命令才允许并行
  • 只要命令会生成、覆盖、部署、锁定文件、启动宿主进程,必须串行执行
  • 对本仓库,默认把 run-unit-tests -> compile -> deploy -> start Navisworks 视为单通道流水线
  • 不允许把这条流水线放进任何并行工具里,即使只是为了节省时间

插件部署目录

  • C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\

日志目录:

  • C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\logs\debug.log

3. 目录与职责

核心目录

  • src/Core/
    • 插件主入口、路径管理、动画、碰撞、渲染、配置
  • src/UI/WPF/
    • 视图、ViewModel、交互命令
  • src/Utils/
    • 单位、几何、坐标、变换、日志等公共工具
  • src/PathPlanning/
    • 网格、A*、路径几何与优化
  • UnitTests/
    • 数学层、工具层、姿态层的回归测试

当前最关键的文件

  • src/Core/Animation/PathAnimationManager.cs
  • src/Core/VirtualObjectManager.cs
  • src/Core/PathPointRenderPlugin.cs
  • src/UI/WPF/ViewModels/AnimationControlViewModel.cs
  • src/UI/WPF/ViewModels/PathEditingViewModel.cs
  • src/Utils/CoordinateSystem/HostCoordinateAdapter.cs
  • src/Utils/CoordinateSystem/CanonicalPlanarPoseBuilder.cs
  • src/Utils/CoordinateSystem/CanonicalRailPoseBuilder.cs
  • src/Utils/CoordinateSystem/CanonicalTrackedPositionResolver.cs
  • src/Utils/CoordinateSystem/RotatedObjectExtentHelper.cs
  • src/Utils/RailPathPoseHelper.cs
  • src/Utils/ModelItemTransformHelper.cs

4. 当前稳定架构

4.1 坐标系三层语义

以后统一只使用这三种说法:

  • 宿主坐标系

    • Navisworks 文档坐标系
    • YUpZUp
    • UI 输入输出、日志、拾取结果都按这一层解释
  • 内部坐标系

    • 项目内部统一使用的 Canonical Space
    • 固定 ZUp
    • 纯数学姿态和几何计算优先在这里完成
  • 资产坐标系

    • 只属于插件自带资源
    • 当前主要是:
      • 虚拟物体 unit_cube.nwc
      • 参考杆 unit_cylinder.nwc

禁止再使用“本地坐标系”这种含糊说法。

4.1.2 坐标命名规则

以后凡是变量名、字段名、日志名里出现 X/Y/Z、正负轴、forward/up/side 等方向语义,必须在名字上直接带出所属坐标系,避免只看名字时无法判断语义层。

允许的前缀示例:

  • Host...
    • 宿主坐标系
  • Canonical...
    • 内部坐标系
  • Asset...
    • 资产坐标系
  • Local...
    • 仅当这里明确表示“对象自身局部轴”时才允许使用

正负轴命名示例:

  • LocalPositiveX
  • LocalNegativeY
  • HostPositiveZ
  • CanonicalPositiveX
  • AssetPositiveY

方向/向量命名示例:

  • hostForward
  • hostUp
  • canonicalForward
  • assetUp
  • localXAxis
  • localZAxis

禁止继续使用这类脱离坐标系语义的名字:

  • PositiveX
  • NegativeZ
  • xAxis
  • upAxis
  • forwardAxis

除非变量名里已经明确出现了所属坐标系前缀。

目标是做到:只看名字,就能知道这个方向、轴、向量到底属于宿主、内部、资产,还是对象自身局部轴。

4.1.3 对象局部轴业务映射

以后关于 Local...、前进轴、up 轴、side 轴,统一优先使用这个说法:

  • 对象局部轴业务映射
    • 它不是第四套全局坐标系
    • 也不是几何天然自带的“真理”
    • 它表示:在当前业务链路里,我们准备把对象自身哪根局部轴解释成:
      • forward
      • up
      • side

这个概念的边界必须非常明确:

  • 它是业务解释层
    • 不是宿主坐标系
    • 不是内部 Canonical Space
    • 不是插件资源资产坐标系
  • 它不能脱离上下文单独存在
    • up 往往要结合宿主 up 语义来解释
    • forward 往往取决于:
      • fragment 代表姿态解释
      • 资源默认轴约定
      • 用户选择
      • 当前路径类型

为什么必须保留这层概念:

  • 路径姿态求解必须回答:
    • 对象哪根局部轴去对齐路径 forward
    • 对象哪根局部轴去对齐目标 up
  • 如果没有这层映射,下面这些都无法稳定定义:
    • Ground / Hoisting / Rail 起点姿态
    • 逐帧姿态
    • Rail 角度修正
    • 通行空间尺寸投影
    • 终点原始姿态保持
    • Rail 平移模式的终点原位搬运

当前项目里的硬约束:

  • 不要把“对象局部轴业务映射”写成“对象自身天然就有 forward/up 定义”
  • 对真实物体:
    • 不能简单把 ModelItem.Transform 当成可靠的局部轴真值
    • 应优先通过 fragment 代表姿态 + Fragment默认Up 去解释
  • 对虚拟物体:
    • 对象局部轴业务映射通常来自明确的资产轴约定
  • 如果只是讨论对象自身局部轴语义,允许继续使用 Local... 命名
    • 但文档、日志、设计讨论里优先说“对象局部轴业务映射”

4.1.1 Quaternion / Rotation3D 固定定义

这是项目级硬约束,不允许在任何修复中重新猜测、重新验证或临时改口:

  • Navisworks Rotation3D(double, double, double, double) 的参数顺序固定为:
    • x, y, z, w
  • Rotation3D.A/B/C/D 与 quaternion 分量的对应关系固定为:
    • A = x
    • B = y
    • C = z
    • D = w
  • 当代码里已经拿到 quaternion (qx, qy, qz, qw) 时,唯一允许的构造方式是:
var rotation = new Rotation3D(qx, qy, qz, qw);
  • 严禁再写成:
var rotation = new Rotation3D(qw, qx, qy, qz); // 错误
  • 以后遇到姿态问题,禁止再把故障归因到 “Navisworks 四元数分量顺序可能又不一样了”。
  • 如果问题涉及真实物体或 fragment 参考姿态的轴语义,优先检查:
    • fragment 三轴的业务解释是否正确
    • 参考姿态是否应该用显式三轴而不是只传 quaternion
    • 宿主坐标系 / 内部坐标系 / 资产坐标系 是否被混用

4.2 真实物体 vs 虚拟物体

这是当前架构里最容易被改坏的地方。

真实物体

  • 没有独立资产坐标系
  • 可以视为直接生活在宿主坐标系里
  • 角度调整对话框里的 X/Y/Z,对真实物体应按宿主坐标系消费

真实物体参考姿态

  • 真实物体不要再直接依赖 ModelItem.Transform.Factor().Rotation
    • 对很多 Revit 导入件,这个值是单位旋转,不代表真实显示姿态
  • 真实物体参考姿态应优先来自 fragment 代表姿态
  • Fragment默认Up 的用途是:
    • 把 fragment 参考框架解释成当前宿主坐标语义下的真实姿态
    • 不是仅仅挑一个“竖直候选轴”
  • 在真实物体链路里必须先完成“fragment 姿态解释”,再谈:
    • 前进方向
    • 路径对齐
    • 角度调整
  • _trackedRotation 对真实物体必须优先跟踪“解释后的真实参考姿态”,不能回退成 Transform 的单位旋转

虚拟物体

  • 有明确资产坐标系
  • 当前依赖 unit_cube.nwc 资源
  • 资源必须满足:
    • 几何中心在原点
    • 原点处 BoundingBox.Center == (0,0,0)
  • 如果生产环境里虚拟物体固定偏移,先检查部署的 unit_cube.nwc 是否为最新资源,不要先怀疑代码

4.3 路径姿态链

Ground / Hoisting

  • 走平面姿态链
  • 已禁止偷偷退回旧 yaw 方案
  • 起点、逐帧、终点、通行空间,必须共享同一套尺寸语义
  • Ground + 真实物体 的业务跟踪点固定为原始包围盒中心
  • 旋转后的实时 BoundingBox.Center 只允许用于:
    • 诊断旋转后漂移
    • 计算当帧补偿
    • 校验补偿结果
  • 不允许把实时 BoundingBox.Center 直接当成:
    • 起点目标跟踪点
    • 逐帧业务跟踪点
    • 碰撞记录主语义跟踪点
  • 如果 Ground 出现“起点正确但越走越偏”或“起点偏了但拐弯后偏差反而减小”,优先检查是否把实时包围盒中心误当成了业务跟踪点

Rail

  • 不能像平面路径那样在宿主空间随意补旋转
  • 必须并入 canonical -> rail pose
  • Rail 0° 基线必须稳定,不能被角度修正逻辑污染
  • Rail 真实物体不应再退回默认 PositiveX / PositiveY
  • 三类路径都必须先复用同一个“对象姿态解释层”:
    • Ground / Hoisting
      • forward = 路径方向
      • up = 宿主 up
    • Rail
      • forward = rail 切向
      • up = rail 法向 / preferred normal
  • 统一的是“对象参考姿态来源与解释方式”,不是把三类路径都强行改成同一个 up

4.4 通行空间与物体姿态的关系

通行空间、起点落位、逐帧位置、终点诊断,必须尽量共用同一套尺寸/法线语义。

典型错误信号:

  • 通行空间正确,但物体陷入地面
  • 物体姿态正确,但通行空间轴搞反
  • YUpY/Z 表现互换

遇到这类问题,优先检查:

  • 是否一条链用了“原始高度”
  • 另一条链用了“旋转后法线尺寸”
  • Rail 真实物体尤其要检查:
    • 起点/逐帧中心偏移是否仍在用原始 objectHeight
    • 通行空间是否仍在用旧 RailAssetConvention
    • 通行空间、路径偏移、最终姿态是否共享同一套“最终姿态尺寸语义”

4.5 终端安装仿真

当前稳定链路是:

  1. 捕获终点箱体
  2. 分析端面3点
  3. 选择安装点(当前已是 2 点确定安装面)
  4. 生成辅助线 / 安装面 / 安装点
  5. 取起点并生成路径

当前 UI 上:

  • 终端安装仿真是独立区块
  • 不再夹在路径编辑中间
  • 安装方式选择只保留一处

5. 开发原则

5.1 彻底禁止 fallback

这是当前项目的第一编码原则,优先级高于其他“先跑起来”的考虑。

不允许出现以下行为:

  • 新姿态链失败时,静默退回旧姿态链
  • 新变换链失败时,静默退回旧变换链
  • 正确姿势/正确位置/正确尺寸语义拿不到时,用“差不多”的旧值、缓存值、默认值顶上
  • 只打印一条 warning然后继续使用错误语义把流程跑完

尤其禁止这类做法:

  • 偷偷退回旧 yaw
  • 偷偷用硬编码 Z-up
  • 偷偷在错误时给默认值掩盖问题
  • 偷偷在新链失败时自动掉回旧链
  • 读不到当前实际几何旋转时,回退到 _trackedRotation
  • 读不到当前真实姿态时,回退到 referenceRotation
  • 读不到当前显示姿态时,回退到 ModelItem.Transform

正确做法只有两种:

  1. 在进入新链前把前置条件补齐
  2. 直接暴露失败并修根因

不允许把“旧链兜底”当成正式实现的一部分。

5.2 不向后兼容

项目只针对 Navisworks 2026。不要写旧版本兼容代码。

5.3 临时补丁不是正式实现

为定位问题临时加入的:

  • 强制刷新
  • 额外同步
  • 再调一次方法
  • UI 和稀泥补丁

如果最后证明它不是真正根因,修完后必须删掉,不能残留在正式代码里。

5.4 优先复用现有工具

尤其优先看:

  • UnitsConverter
  • GeometryHelper
  • LogManager
  • HostCoordinateAdapter
  • Canonical* 姿态工具
  • ModelItemTransformHelper
  • RailPathPoseHelper

不要在业务层手搓一套新的矩阵、坐标变换或尺寸投影公式。

5.5 测试优先于猜测

对几何/旋转/坐标问题,优先顺序应是:

  1. 看日志
  2. 日志不够就补日志
  3. 先补单元测试
  4. 再改代码

不要在没有锁住语义之前反复试错改实现。


6. 单位原则

所有路径计算、网格计算、包络尺寸、位移偏移,内部一律使用模型单位

命名规则:

  • 米单位:变量名以 InMeters 结尾
  • 模型单位:变量名不加后缀

不要混用。

优先使用:

  • UnitsConverter.GetMetersToUnitsConversionFactor()
  • UnitsConverter.GetUnitsToMetersConversionFactor()
  • UnitsConverter.ConvertToMeters(...)
  • UnitsConverter.ConvertFromMeters(...)

7. 常见问题的排查入口

7.1 虚拟物体固定偏差

先查:

  1. 部署目录下的 resources\\unit_cube.nwc
  2. 原点处 BoundingBox.Center 是否是 (0,0,0)
  3. 再查起点/归位代码

7.2 真实物体旋转轴不对

先区分:

  • 目标姿态算错
  • 还是 Navisworks 应用姿态错

优先看:

  • [动画姿态入口]
  • [模型增量姿态]

7.3 吊装路径不显示

优先检查渲染链里是否有退化段/零长度段导致整条渲染失败。

7.4 “设为终点直接结束”后列表还是空

优先看 UIStateManager 队列消费是否吃掉了后续 UI 事件,不要先怀疑坐标系。


8. 资源与部署注意事项

8.1 虚拟物体资源

当前部署脚本会部署:

  • resources\\unit_cube.nwc
  • resources\\unit_cylinder.nwc

虚拟物体和参考杆问题,必须同时检查:

  • 仓库里的资源
  • bin\\x64\\Release\\resources
  • 插件部署目录下的 resources

8.2 deploy-plugin.bat 当前规则

  • 走白名单部署
  • 不部署测试 DLL
  • 不部署 Navisworks 自带 API DLL

不要把它改回“复制所有 dll”。


9. 推荐阅读顺序

新会话接手本项目时,推荐顺序:

  1. 本文件 AGENTS.md
  2. doc/working/current-engineering-state.md
  3. doc/design/2026/coordinate-system-canonical-space-design.md
  4. doc/design/2026/NavisworksAPI使用方法.md
  5. 相关专项 skill
    • .agents/skills/nw-api/SKILL.md
    • .agents/skills/geometry-transform/SKILL.md

10. 当前对子代理和 skill 的约定

仓库中已经有几何/变换专项 skill

  • .agents/skills/geometry-transform/SKILL.md

它负责沉淀以下内容:

  • 坐标系变换
  • 物体姿态
  • 物体位移与归位
  • 虚拟物体资源定位
  • 通行空间几何
  • Navisworks 变换 API 使用规则

后续凡是几何/旋转/位移问题,优先沿这套 skill 与工具链继续维护,不要重新发明一套术语和流程。


11. 最后的硬约束

  1. 不要混淆宿主坐标系、内部坐标系、资产坐标系
  2. 不要在宿主空间随意补旋转,先判断是否应并入现有姿态链
  3. 不要让虚拟物体和真实物体共享含糊的状态分支
  4. 不要让通行空间和真实物体使用两套不同的尺寸语义
  5. 不要把临时补丁留在正式实现里
  6. 不要绕过测试直接改几何核心逻辑

如果你要改动:

  • PathAnimationManager
  • VirtualObjectManager
  • PathPointRenderPlugin
  • AnimationControlViewModel
  • HostCoordinateAdapter
  • Canonical*PoseBuilder
  • ModelItemTransformHelper

请默认这是高风险改动,先补测试,再动实现。