588 lines
17 KiB
Markdown
588 lines
17 KiB
Markdown
# 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
|
||
- UI:WPF + 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 文档坐标系
|
||
- `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...`
|
||
- 仅当这里明确表示“对象自身局部轴”时才允许使用
|
||
|
||
正负轴命名示例:
|
||
|
||
- `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)` 时,唯一允许的构造方式是:
|
||
|
||
```csharp
|
||
var rotation = new Rotation3D(qx, qy, qz, qw);
|
||
```
|
||
|
||
- 严禁再写成:
|
||
|
||
```csharp
|
||
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 通行空间与物体姿态的关系
|
||
|
||
通行空间、起点落位、逐帧位置、终点诊断,必须尽量共用同一套尺寸/法线语义。
|
||
|
||
典型错误信号:
|
||
|
||
- 通行空间正确,但物体陷入地面
|
||
- 物体姿态正确,但通行空间轴搞反
|
||
- `YUp` 下 `Y/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`
|
||
|
||
请默认这是高风险改动,先补测试,再动实现。
|