17 KiB
AGENTS.md
本文件面向后续会话中的 AI 编码助手。目标不是写一份“大而全”的历史说明,而是让新会话能快速理解:
- 项目现在在做什么
- 哪些架构已经稳定
- 哪些开发原则不能再破坏
- 遇到问题时优先看哪里
如果本文件与更细的专项文档冲突,优先参考:
doc/working/current-engineering-state.mddoc/design/2026/coordinate-system-canonical-space-design.mddoc/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
- UI:WPF + Navisworks DockPane
- 测试:MSTest
关键脚本
compile.batrun-unit-tests.batdeploy-plugin.bat
极重要的执行顺序
构建和部署必须严格按顺序执行:
./run-unit-tests.bat(需要时)./compile.bat- 等待编译完整结束并确认成功
./deploy-plugin.bat
不要并行执行编译和部署。否则很容易把旧 DLL 部署到插件目录。
并行执行边界
后续会话中的 AI 助手必须把命令分成两类:
- 允许并行的纯读取操作
rgGet-Contentls / Get-ChildItem- 读取日志
- 查询状态
- 禁止并行的产出型/宿主相关操作
run-unit-tests.batcompile.batdeploy-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.cssrc/Core/VirtualObjectManager.cssrc/Core/PathPointRenderPlugin.cssrc/UI/WPF/ViewModels/AnimationControlViewModel.cssrc/UI/WPF/ViewModels/PathEditingViewModel.cssrc/Utils/CoordinateSystem/HostCoordinateAdapter.cssrc/Utils/CoordinateSystem/CanonicalPlanarPoseBuilder.cssrc/Utils/CoordinateSystem/CanonicalRailPoseBuilder.cssrc/Utils/CoordinateSystem/CanonicalTrackedPositionResolver.cssrc/Utils/CoordinateSystem/RotatedObjectExtentHelper.cssrc/Utils/RailPathPoseHelper.cssrc/Utils/ModelItemTransformHelper.cs
4. 当前稳定架构
4.1 坐标系三层语义
以后统一只使用这三种说法:
-
宿主坐标系
- Navisworks 文档坐标系
YUp或ZUp- UI 输入输出、日志、拾取结果都按这一层解释
-
内部坐标系
- 项目内部统一使用的
Canonical Space - 固定
ZUp - 纯数学姿态和几何计算优先在这里完成
- 项目内部统一使用的
-
资产坐标系
- 只属于插件自带资源
- 当前主要是:
- 虚拟物体
unit_cube.nwc - 参考杆
unit_cylinder.nwc
- 虚拟物体
禁止再使用“本地坐标系”这种含糊说法。
4.1.2 坐标命名规则
以后凡是变量名、字段名、日志名里出现 X/Y/Z、正负轴、forward/up/side 等方向语义,必须在名字上直接带出所属坐标系,避免只看名字时无法判断语义层。
允许的前缀示例:
Host...- 宿主坐标系
Canonical...- 内部坐标系
Asset...- 资产坐标系
Local...- 仅当这里明确表示“对象自身局部轴”时才允许使用
正负轴命名示例:
LocalPositiveXLocalNegativeYHostPositiveZCanonicalPositiveXAssetPositiveY
方向/向量命名示例:
hostForwardhostUpcanonicalForwardassetUplocalXAxislocalZAxis
禁止继续使用这类脱离坐标系语义的名字:
PositiveXNegativeZxAxisupAxisforwardAxis
除非变量名里已经明确出现了所属坐标系前缀。
目标是做到:只看名字,就能知道这个方向、轴、向量到底属于宿主、内部、资产,还是对象自身局部轴。
4.1.3 对象局部轴业务映射
以后关于 Local...、前进轴、up 轴、side 轴,统一优先使用这个说法:
- 对象局部轴业务映射
- 它不是第四套全局坐标系
- 也不是几何天然自带的“真理”
- 它表示:在当前业务链路里,我们准备把对象自身哪根局部轴解释成:
forwardupside
这个概念的边界必须非常明确:
- 它是业务解释层
- 不是宿主坐标系
- 不是内部
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 = xB = yC = zD = 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 / Hoistingforward = 路径方向up = 宿主 up
Railforward = rail 切向up = rail 法向 / preferred normal
- 统一的是“对象参考姿态来源与解释方式”,不是把三类路径都强行改成同一个
up
4.4 通行空间与物体姿态的关系
通行空间、起点落位、逐帧位置、终点诊断,必须尽量共用同一套尺寸/法线语义。
典型错误信号:
- 通行空间正确,但物体陷入地面
- 物体姿态正确,但通行空间轴搞反
YUp下Y/Z表现互换
遇到这类问题,优先检查:
- 是否一条链用了“原始高度”
- 另一条链用了“旋转后法线尺寸”
Rail真实物体尤其要检查:- 起点/逐帧中心偏移是否仍在用原始
objectHeight - 通行空间是否仍在用旧
RailAssetConvention - 通行空间、路径偏移、最终姿态是否共享同一套“最终姿态尺寸语义”
- 起点/逐帧中心偏移是否仍在用原始
4.5 终端安装仿真
当前稳定链路是:
- 捕获终点箱体
- 分析端面(3点)
- 选择安装点(当前已是 2 点确定安装面)
- 生成辅助线 / 安装面 / 安装点
- 取起点并生成路径
当前 UI 上:
- 终端安装仿真是独立区块
- 不再夹在路径编辑中间
- 安装方式选择只保留一处
5. 开发原则
5.1 彻底禁止 fallback
这是当前项目的第一编码原则,优先级高于其他“先跑起来”的考虑。
不允许出现以下行为:
- 新姿态链失败时,静默退回旧姿态链
- 新变换链失败时,静默退回旧变换链
- 正确姿势/正确位置/正确尺寸语义拿不到时,用“差不多”的旧值、缓存值、默认值顶上
- 只打印一条 warning,然后继续使用错误语义把流程跑完
尤其禁止这类做法:
- 偷偷退回旧
yaw - 偷偷用硬编码
Z-up - 偷偷在错误时给默认值掩盖问题
- 偷偷在新链失败时自动掉回旧链
- 读不到当前实际几何旋转时,回退到
_trackedRotation - 读不到当前真实姿态时,回退到
referenceRotation - 读不到当前显示姿态时,回退到
ModelItem.Transform
正确做法只有两种:
- 在进入新链前把前置条件补齐
- 直接暴露失败并修根因
不允许把“旧链兜底”当成正式实现的一部分。
5.2 不向后兼容
项目只针对 Navisworks 2026。不要写旧版本兼容代码。
5.3 临时补丁不是正式实现
为定位问题临时加入的:
- 强制刷新
- 额外同步
- 再调一次方法
- UI 和稀泥补丁
如果最后证明它不是真正根因,修完后必须删掉,不能残留在正式代码里。
5.4 优先复用现有工具
尤其优先看:
UnitsConverterGeometryHelperLogManagerHostCoordinateAdapterCanonical*姿态工具ModelItemTransformHelperRailPathPoseHelper
不要在业务层手搓一套新的矩阵、坐标变换或尺寸投影公式。
5.5 测试优先于猜测
对几何/旋转/坐标问题,优先顺序应是:
- 看日志
- 日志不够就补日志
- 先补单元测试
- 再改代码
不要在没有锁住语义之前反复试错改实现。
6. 单位原则
所有路径计算、网格计算、包络尺寸、位移偏移,内部一律使用模型单位。
命名规则:
- 米单位:变量名以
InMeters结尾 - 模型单位:变量名不加后缀
不要混用。
优先使用:
UnitsConverter.GetMetersToUnitsConversionFactor()UnitsConverter.GetUnitsToMetersConversionFactor()UnitsConverter.ConvertToMeters(...)UnitsConverter.ConvertFromMeters(...)
7. 常见问题的排查入口
7.1 虚拟物体固定偏差
先查:
- 部署目录下的
resources\\unit_cube.nwc - 原点处
BoundingBox.Center是否是(0,0,0) - 再查起点/归位代码
7.2 真实物体旋转轴不对
先区分:
- 目标姿态算错
- 还是 Navisworks 应用姿态错
优先看:
[动画姿态入口][模型增量姿态]
7.3 吊装路径不显示
优先检查渲染链里是否有退化段/零长度段导致整条渲染失败。
7.4 “设为终点直接结束”后列表还是空
优先看 UIStateManager 队列消费是否吃掉了后续 UI 事件,不要先怀疑坐标系。
8. 资源与部署注意事项
8.1 虚拟物体资源
当前部署脚本会部署:
resources\\unit_cube.nwcresources\\unit_cylinder.nwc
虚拟物体和参考杆问题,必须同时检查:
- 仓库里的资源
bin\\x64\\Release\\resources- 插件部署目录下的
resources
8.2 deploy-plugin.bat 当前规则
- 走白名单部署
- 不部署测试 DLL
- 不部署 Navisworks 自带 API DLL
不要把它改回“复制所有 dll”。
9. 推荐阅读顺序
新会话接手本项目时,推荐顺序:
- 本文件
AGENTS.md doc/working/current-engineering-state.mddoc/design/2026/coordinate-system-canonical-space-design.mddoc/design/2026/NavisworksAPI使用方法.md- 相关专项 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. 最后的硬约束
- 不要混淆宿主坐标系、内部坐标系、资产坐标系
- 不要在宿主空间随意补旋转,先判断是否应并入现有姿态链
- 不要让虚拟物体和真实物体共享含糊的状态分支
- 不要让通行空间和真实物体使用两套不同的尺寸语义
- 不要把临时补丁留在正式实现里
- 不要绕过测试直接改几何核心逻辑
如果你要改动:
PathAnimationManagerVirtualObjectManagerPathPointRenderPluginAnimationControlViewModelHostCoordinateAdapterCanonical*PoseBuilderModelItemTransformHelper
请默认这是高风险改动,先补测试,再动实现。