# AGENTS.md 本文件为AI编码助手提供 NavisworksTransport 项目的完整开发指南。阅读本文件前,请确保你已经了解项目的基本结构和目标。 ## 项目概述 **NavisworksTransport** 是专为 Autodesk Navisworks Manage 2026 开发的物流路径规划插件,用于BIM模型中的运输冲突检测和路径规划。 ### 核心功能 - **物流属性管理**: 为模型分配类别属性(门、电梯、楼梯、通道、障碍物) - **自动路径规划**: 基于A*算法的2.5D网格路径规划,支持通道优先策略 - **碰撞检测**: 与Navisworks ClashDetective集成,实现动态碰撞检测 - **动画仿真**: TimeLiner集成,支持路径动画播放和仿真 - **吊装路径**: 支持空中吊装路径规划(两次点击模式) - **数据导出**: 支持XML、JSON、CSV格式的路径数据导出,以及DELMIA数据格式 ### 技术栈 | 组件 | 版本/说明 | |------|----------| | 目标平台 | Navisworks Manage 2026 | | 框架 | .NET Framework 4.8 | | 语言 | C# 7.3 | | 架构 | x64 | | UI框架 | WPF (MVVM模式) + Windows Forms集成 | ### 项目文件 | 文件 | 说明 | |------|------| | `TransportPlugin.csproj` | 主插件项目(旧式csproj格式) | | `NavisworksTransport.UnitTests.csproj` | 单元测试项目 | | `TransportPlugin.sln` | Visual Studio 解决方案 | | `packages.config` | NuGet包配置(旧式包管理) | | `default_config.toml` | 默认配置文件模板 | | `compile.bat` | 构建脚本 | | `run-unit-tests.bat` | 测试脚本 | | `deploy-plugin.bat` | 部署脚本 | ## 构建命令 ### 环境要求 - Windows 10 或更高版本 - Visual Studio 2022(Community/Professional) - Navisworks Manage 2026(已安装) - .NET Framework 4.8 Developer Pack ### 主要构建 ```bash ./compile.bat ``` - 自动检测 Visual Studio 2022 的 MSBuild - 构建 Release 配置的 x64 平台 - 输出目录: `bin\x64\Release\` ### 手动构建 ```bash # 设置MSBuild路径 set MSBUILD_PATH="C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" # 构建主项目 %MSBUILD_PATH% "TransportPlugin.csproj" /p:Configuration=Release /p:Platform=x64 # 构建测试项目 %MSBUILD_PATH% "NavisworksTransport.UnitTests.csproj" /p:Configuration=Release /p:Platform=x64 ``` ### 运行测试 ```bash ./run-unit-tests.bat ``` 该脚本将: 1. 构建主项目 2. 构建测试项目 3. 使用 VSTest.Console 运行单元测试 ### 部署插件 ```bash ./deploy-plugin.bat ``` 自动复制插件文件到 Navisworks 插件目录: `C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\` ## 项目架构 ### 目录结构 ``` src/ ├── Core/ # 核心插件和业务逻辑 │ ├── MainPlugin.cs # DockPanePlugin - Ribbon UI + 停靠面板 │ ├── PathClickToolPlugin.cs # ToolPlugin - 3D鼠标交互工具 │ ├── PathPointRenderPlugin.cs # RenderPlugin - 3D可视化渲染 │ ├── PathPlanningManager.cs # 路径规划管理器(与UI解耦) │ ├── PathDataManager.cs # 路径数据管理 │ ├── PathDatabase.cs # SQLite数据库操作 │ ├── PathCurveEngine.cs # 路径曲线化引擎 │ ├── UIStateManager.cs # 线程安全的UI状态管理 │ ├── Animation/ # 动画系统 │ │ ├── PathAnimationManager.cs │ │ └── TimeLinerIntegrationManager.cs │ ├── Collision/ # 碰撞检测 │ │ ├── ClashDetectiveIntegration.cs │ │ └── BatchCollisionProcessor.cs │ ├── Spatial/ # 空间索引 │ │ ├── SpatialHashGrid.cs │ │ └── SpatialIndexManager.cs │ ├── Properties/ # 属性管理 │ │ ├── CategoryAttributeManager.cs │ │ └── NavisworksComPropertyManager.cs │ └── Config/ # 配置管理 │ ├── SystemConfig.cs │ └── ConfigManager.cs ├── Commands/ # 命令模式实现 │ ├── CommandBase.cs │ ├── CommandManager.cs │ ├── AutoPathPlanningCommand.cs │ └── ... ├── PathPlanning/ # A*算法和网格地图 │ ├── GridMap.cs # 网格地图定义 │ ├── GridMapGenerator.cs # 网格生成器 │ ├── AutoPathFinder.cs # A*寻路实现 │ ├── ChannelBasedGridBuilder.cs # 通道优先网格构建 │ ├── VoxelGrid.cs # 3D体素网格(实验性) │ └── PathOptimizer.cs # 路径优化 ├── UI/WPF/ # WPF用户界面 │ ├── Views/ # XAML视图 │ ├── ViewModels/ # MVVM视图模型 │ ├── Models/ # 数据模型 │ ├── Converters/ # 值转换器 │ ├── Commands/ # WPF命令 │ └── Services/ # UI服务 └── Utils/ # 工具类 ├── UnitsConverter.cs # 单位转换(关键!) ├── LogManager.cs # 日志管理 ├── GeometryHelper.cs # 几何计算 └── ... UnitTests/ # 单元测试 ├── Core/ # 核心功能测试 ├── Commands/ # 命令测试 └── Utils/ # 工具类测试 ``` ### 插件类型说明 | 插件类 | 类型 | 功能 | |--------|------|------| | `MainPlugin.cs` | DockPanePlugin | 主UI面板,包含WPF控件宿主 | | `PathClickToolPlugin.cs` | ToolPlugin | 鼠标点击工具,获取精确的3D坐标 | | `PathPointRenderPlugin.cs` | RenderPlugin | 3D渲染,显示路径点和连线 | ### 关键依赖 **Navisworks API(必须安装Navisworks 2026):** - `Autodesk.Navisworks.Api.dll` - `Autodesk.Navisworks.ComApi.dll` - `Autodesk.Navisworks.Interop.ComApi.dll` - `Autodesk.Navisworks.Timeliner.dll` - `Autodesk.Navisworks.Clash.dll` - `Autodesk.Navisworks.Controls.dll` **NuGet包:** - `RoyT.AStar 3.0.2` - A*寻路算法 - `geometry4Sharp 1.0.0` - 3D几何计算(体素路径规划) - `System.Data.SQLite.Core 1.0.118.0` - SQLite数据库 - `Tomlyn 0.19.0` - TOML配置文件解析 - `MSTest.TestFramework 3.0.4` - 单元测试框架 ## 代码规范 ### 导入顺序 ```csharp // 1. System命名空间 using System; using System.Collections.Generic; using System.Linq; // 2. 第三方库 using RoyT.AStar; // 3. Navisworks API using Autodesk.Navisworks.Api; using Autodesk.Navisworks.ComApi; using Autodesk.Navisworks.Api.Plugins; // 4. 项目命名空间(按字母顺序) using NavisworksTransport.Commands; using NavisworksTransport.Core; using NavisworksTransport.PathPlanning; using NavisworksTransport.UI.WPF.ViewModels; using NavisworksTransport.Utils; ``` ### 命名约定 | 类型 | 命名规则 | 示例 | |------|----------|------| | 类 | PascalCase | `PathPlanningManager` | | 接口 | PascalCase + 'I'前缀 | `IPathPlanningCommand` | | 方法 | PascalCase | `GenerateGridMap` | | 属性 | PascalCase | `CellSize` | | 字段 | camelCase + 下划线前缀 | `_uiStateManager` | | 常量 | PascalCase | `MaxHeightDiff` | | 枚举 | PascalCase | `GridGenerationMode` | ### 单位系统 - 极其重要 **所有网格地图和路径规划计算必须使用模型单位,严禁混用米制单位。** ```csharp // ✅ 正确:在函数入口统一转换 public GridMap GenerateFromBIM(BoundingBox3D bounds, double cellSizeMeters, ...) { double factor = UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units); double cellSizeInModelUnits = cellSizeMeters * factor; // 后续所有计算使用 cellSizeInModelUnits } // ❌ 错误:混用单位 private const double MAX_HEIGHT_DIFF = 0.35; // 这是米! if (heightDiff > MAX_HEIGHT_DIFF) // 单位不匹配,严重Bug! ``` `UnitsConverter` 提供以下方法: - `GetUnitsToMetersConversionFactor()` - 文档单位转米 - `GetMetersToUnitsConversionFactor()` - 米转文档单位 - `ConvertToMeters(distance)` - 转换距离为米 - `ConvertFromMeters(distanceInMeters)` - 从米转换距离 ### 错误处理 ```csharp // ✅ 正确:记录并适当处理异常 try { var result = SomeOperation(); return result; } catch (Exception ex) { LogManager.Error($"Operation failed: {ex.Message}"); throw; // 或适当处理 } // ❌ 错误:静默吞掉异常 try { var result = SomeOperation(); return result; } catch { return null; // 隐藏了问题! } ``` ### 线程安全和UI更新 所有UI操作必须编组到主线程: ```csharp // ✅ 正确:使用UIStateManager进行线程安全更新 _uiStateManager.UpdateStatus("正在处理..."); // ✅ 正确:异步事件触发避免死锁 private void OnStatusChanged(string status) { Task.Run(() => { try { StatusChanged?.Invoke(this, status); } catch (Exception ex) { LogManager.Error($"StatusChanged事件失败: {ex.Message}"); } }); } ``` ### WPF UI开发注意事项 #### 必须检查:XAML资源引用有效性 **问题**:使用未在XAML中定义的Converter/Style资源会导致窗口无法显示 ```xml Visibility="{Binding HasItems, Converter={StaticResource InverseBoolToVisibilityConverter}}" Visibility="{Binding HasItems, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=Inverse}" ``` **项目中已定义的资源(AnimationControlView.xaml)**: | 资源名 | 类型 | 说明 | |--------|------|------| | `BoolToVisibilityConverter` | BoolToVisibilityConverter | 布尔转可见性,支持Inverse参数 | **XAML开发工作流程(必须遵守)**: 1. **每添加一个资源引用,立即确认其存在** ``` ❌ 错误做法: - 复制其他文件的XAML代码 - 一次性写大量XAML再测试 ✅ 正确做法: - 每写一行 {StaticResource xxx},立即检查 xxx 是否已定义 - 使用 Ctrl+F 搜索 xxx 确认在当前文件或合并字典中存在 ``` 2. **资源定义位置优先级**: - 本文件 `` 或 `` 内定义 - 引用的外部资源字典(如 `NavisworksStyles.xaml`) - 必须在 XAML 顶部检查 `MergedDictionaries` 是否正确合并 3. **新增XAML文件时必做检查清单**: ``` □ 所有 {StaticResource xxx} 引用都有定义 □ 所有 xmlns:local 命名空间映射正确 □ 所有 ValueConverter 在 xaml.cs 中已实现 □ 合并的资源字典路径正确(pack://application:,,,/...) □ 编译通过后立即运行测试,验证窗口能正常打开 ``` 4. **常见错误模式与修正**: | 错误写法 | 问题 | 正确写法 | |---------|------|---------| | `InverseBoolToVisibilityConverter` | 未定义 | `BoolToVisibilityConverter` + `ConverterParameter=Inverse` | | `VisibilityConverter` | 未定义 | `BoolToVisibilityConverter` | | `BooleanToVisibilityConverter` (键名) | 引用时使用 `BoolToVisibilityConverter` | 键名和引用保持一致 | | 拼写错误的Style名 | 找不到资源 | 检查资源字典中的精确定义 | 5. **调试XAML资源错误**: - 错误信息:`无法在资源字典中找到名为 xxx 的资源` - 定位方法:从堆栈跟踪找到最后加载的XAML元素 - 快速修复:临时注释掉报错元素,添加简化版本测试 - 预防措施:小步增量开发,每步验证窗口可正常显示 #### AI助手强制执行机制(防止再次犯错) **写XAML前,必须大声说出以下承诺:** > "我承诺:本次XAML开发将严格遵守渐进式验证原则,每添加一个资源引用立即验证,绝不一次性写大量代码。" **编写过程中的强制检查点:** | 步骤 | 强制动作 | 验证命令/方法 | |-----|---------|--------------| | 1. 写完XAML结构 | 列出所有 `{StaticResource xxx}` | `grep -n "StaticResource" File.xaml` | | 2. 检查每个引用 | 在文件中搜索资源定义 | 确认 `x:Key="xxx"` 存在 | | 3. 检查Converter | 确认 xaml.cs 中有实现 | `grep "class.*Converter.*:" File.xaml.cs` | | 4. 首次编译 | 必须通过 | `compile.bat` | | 5. 运行时验证 | 窗口能正常打开无异常 | 实际运行测试 | **如果违反规则的后果:** - 必须立即停止当前工作 - 回滚到上一个可运行的版本 - 重新开始,严格按照检查点执行 **自检话术(每次保存前自问):** ``` □ 我是否复制了其他文件的XAML代码而没有检查资源? □ 我是否一次性写了超过50行XAML才测试? □ 我能否确定每个 {StaticResource} 都在当前文件或合并字典中定义? □ 如果现在运行,窗口会崩溃吗? ``` **历史错误记录(警示):** - 2025-02-14: PathAnalysisDialog.xaml 使用了 `BoolToVisibilityConverter` 但定义的是 `BooleanToVisibilityConverter`,导致窗口崩溃 - 根本原因:没有逐条执行检查清单,过度自信 #### UI色彩规范 - Material Design **项目整体使用 Google Material Design 色系**,确保视觉一致性。 **常用颜色定义**(来自 `PathPointRenderPlugin.cs`): | 用途 | 颜色名称 | RGB值 | 十六进制 | |------|---------|-------|---------| | 起点 | Material Green | (76, 175, 80) | #4CAF50 | | 通行空间 | Material Light Green | (129, 199, 132) | #81C784 | | 排除对象 | Material Light Green | (129, 199, 132) | #81C784 | **其他高亮颜色**(来自 `ModelHighlightHelper.cs`): | 类别 | 颜色 | RGB值 | |------|------|-------| | 预计算碰撞 | Material Purple | (156, 39, 176) | | 手工指定对象 | 橙色 | (255, 170, 0) | | 动画物体 | Amber/Yellow | (255, 193, 7) | | ClashDetective结果 | 红色 | Color.Red | | 通道预览 | 绿色 | Color.Green | **使用规范**: 1. 新增UI元素时优先使用上述Material色系 2. 如需新颜色,参考 [Material Design Color Palette](https://material.io/resources/color/) 3. 使用 `Color.FromByteRGB(r, g, b)` 定义颜色(Navisworks API) 4. 保持透明度一致:通行空间类用 0.8-0.9,碰撞类用不透明 ## 配置系统 配置文件使用 TOML 格式,默认配置位于 `default_config.toml`: ```toml [path_editing] cell_size_meters = 0.5 # 网格单元大小(米) max_height_diff_meters = 0.35 # 最大高度差(米) object_length_meters = 1.5 # 物体长度 object_width_meters = 1.0 # 物体宽度 object_height_meters = 2.0 # 物体高度 safety_margin_meters = 0.1 # 安全间隙 default_path_turn_radius = 2.5 # 默认转弯半径 arc_sampling_step = 0.05 # 圆弧采样步长 [visualization] margin_ratio = 0.1 # 地图边距比例 [animation] frame_rate = 30 # 动画帧率 duration_seconds = 10.0 # 动画持续时间 detection_tolerance_meters = 0.05 # 检测容差 spatial_index_cell_size = 1.0 # 空间索引格子大小 [logistics] traversable = true # 默认可通行性 priority = 5 # 优先级(1-5) height_limit_meters = 3.0 # 高度限制 speed_limit_meters_per_second = 0.8 # 速度限制 width_limit_meters = 3.0 # 宽度限制 ``` 运行时通过 `ConfigManager.Instance.Current` 访问配置。 ## 测试策略 ### 测试项目结构 ``` UnitTests/ ├── Core/ │ ├── PathCurveEngineTests.cs │ └── UIStateManagerBasicTests.cs ├── Commands/ │ └── CommandBaseTests.cs ├── Collections/ │ └── ThreadSafeObservableCollectionBasicTests.cs └── Utils/ └── UnitsConverterTests.cs ``` ### 测试框架 - **框架**: MSTest 3.0.4 - **运行器**: VSTest.Console.exe - **目标框架**: .NET Framework 4.8 ### 编写测试 ```csharp using Microsoft.VisualStudio.TestTools.UnitTesting; namespace NavisworksTransport.UnitTests { [TestClass] public class ExampleTests { [TestMethod] public void TestMethod_ShouldDoSomething() { // Arrange var input = "test"; // Act var result = SomeMethod(input); // Assert Assert.AreEqual("expected", result); } } } ``` ### 注意事项 - 独立测试:不依赖Navisworks环境,测试核心算法逻辑 - 集成测试:需要完整的Navisworks 2026环境 - 日志位置: `C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\logs\debug.log` ## 开发工作流 ### 添加新功能的标准流程 1. **定义接口**(如果需要) - 在 `src/Commands/` 或 `src/Core/` 中定义接口 2. **实现核心逻辑** - 业务逻辑放在 `src/Core/` 或 `src/PathPlanning/` - 确保单位转换正确 3. **添加命令封装**(如果需要) - 在 `src/Commands/` 中实现命令类 - 继承 `CommandBase` 或实现 `IPathPlanningCommand` 4. **更新UI** - ViewModel 在 `src/UI/WPF/ViewModels/` - View 在 `src/UI/WPF/Views/` 5. **注册到主插件** - 在 `MainPlugin.cs` 或相关管理器中集成 6. **添加测试** - 在 `UnitTests/` 对应目录添加测试 ### 调试技巧 1. **查看日志**: 日志文件位于 `C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\logs\` 2. **使用 LogManager**: 所有重要操作都应记录日志 3. **Navisworks插件调试**: - 附加到 `Roamer.exe` 进程 - 使用 `LogManager.Debug()` 输出调试信息 ## 常见问题 ### 构建失败 - **错误**: "MSBuild not found" - **解决**: 安装 Visual Studio 2022 或 Build Tools - **错误**: "无法找到 Autodesk.Navisworks.Api" - **解决**: 安装 Navisworks Manage 2026 ### 运行时错误 - **错误**: "单位不匹配导致的计算错误" - **解决**: 检查 `UnitsConverter` 使用是否正确 - **错误**: "跨线程UI操作异常" - **解决**: 使用 `UIStateManager` 或 `Dispatcher.Invoke` - **错误**: "插件未加载" - **解决**: 检查插件是否部署到正确目录,检查依赖项是否存在 ## 文档资源 - **API文档**: `doc/navisworks_api/NET/documentation/NET API.chm` - **COM API文档**: `doc/navisworks_api/COM/documentation/NavisWorksCOM.chm` - **设计文档**: `doc/design/2026/` - **架构设计**: `doc/architecture/` - **迁移指南**: `doc/migration/`(2017到2026的API变更) ## 版本信息 - **当前版本**: 2.0.0.0 - **程序集**: TransportPlugin - **作者**: Tian - **版权**: Copyright © 2024 --- **注意**: 本插件专门针对 Navisworks 2026 开发,不考虑向后兼容。