From 97296085f5544dcdda1888d026fe359262e74dfc Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Fri, 27 Feb 2026 19:41:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E9=AA=8C=E6=94=B6?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E8=AF=B4=E6=98=8E=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/guide/administrator_manual.md | 9 +- .../2.1.1_模型切分功能设计说明.md | 252 ++++++++++++ .../2.1.2_通道选择功能设计说明.md | 246 +++++++++++ .../2.1.3_路径点规划功能设计说明.md | 287 +++++++++++++ .../2.1.4_编辑保存和导入功能设计说明.md | 369 +++++++++++++++++ .../2.1.5_路径点自动贴合功能设计说明.md | 277 +++++++++++++ .../2.2.1_类别设置功能设计说明.md | 213 ++++++++++ .../2.2.2_属性设置功能设计说明.md | 301 ++++++++++++++ .../2.3.1_层级显示功能设计说明.md | 280 +++++++++++++ .../2.3.2_物流元素筛选功能设计说明.md | 299 ++++++++++++++ .../2.3.3_路径时间标签功能设计说明.md | 308 ++++++++++++++ .../2.4.1_交互式导航控件功能设计说明.md | 280 +++++++++++++ .../2.4.2_结果输出功能设计说明.md | 296 +++++++++++++ .../2.4.3_输出格式功能设计说明.md | 311 ++++++++++++++ .../2.5.1_动画生成和播放功能设计说明.md | 374 +++++++++++++++++ .../2.5.2_碰撞检查功能设计说明.md | 338 +++++++++++++++ .../2.5.3_路径规划分析功能设计说明.md | 389 ++++++++++++++++++ doc/introduction/template.md | 14 + .../通道选择及路径点规划功能开发.xlsx | Bin 0 -> 11567 bytes 19 files changed, 4838 insertions(+), 5 deletions(-) create mode 100644 doc/introduction/2.1.1_模型切分功能设计说明.md create mode 100644 doc/introduction/2.1.2_通道选择功能设计说明.md create mode 100644 doc/introduction/2.1.3_路径点规划功能设计说明.md create mode 100644 doc/introduction/2.1.4_编辑保存和导入功能设计说明.md create mode 100644 doc/introduction/2.1.5_路径点自动贴合功能设计说明.md create mode 100644 doc/introduction/2.2.1_类别设置功能设计说明.md create mode 100644 doc/introduction/2.2.2_属性设置功能设计说明.md create mode 100644 doc/introduction/2.3.1_层级显示功能设计说明.md create mode 100644 doc/introduction/2.3.2_物流元素筛选功能设计说明.md create mode 100644 doc/introduction/2.3.3_路径时间标签功能设计说明.md create mode 100644 doc/introduction/2.4.1_交互式导航控件功能设计说明.md create mode 100644 doc/introduction/2.4.2_结果输出功能设计说明.md create mode 100644 doc/introduction/2.4.3_输出格式功能设计说明.md create mode 100644 doc/introduction/2.5.1_动画生成和播放功能设计说明.md create mode 100644 doc/introduction/2.5.2_碰撞检查功能设计说明.md create mode 100644 doc/introduction/2.5.3_路径规划分析功能设计说明.md create mode 100644 doc/introduction/template.md create mode 100644 doc/requirement/通道选择及路径点规划功能开发.xlsx diff --git a/doc/guide/administrator_manual.md b/doc/guide/administrator_manual.md index 8d2b015..55b0ea0 100644 --- a/doc/guide/administrator_manual.md +++ b/doc/guide/administrator_manual.md @@ -237,9 +237,9 @@ C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\logs\ ## 常见问题 -### Q: 如何查看插件版本? +### Q: 如何查看数据库版本? -**A**: 在 **"系统管理"** 选项卡的 **"系统信息"** 区域查看"插件版本"。 +**A**: 在 **"系统管理"** 选项卡的 **"数据管理"** 区域查看"插件版本"(如果没显示,可以点击“恢复数据库”刷新信息)。 ### Q: 可以在多台机器上使用吗? @@ -255,7 +255,7 @@ C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\logs\ ### Q: 升级后数据还能用吗? -**A**: 同主版本升级(如 2.1 → 2.2)完全兼容。跨主版本升级查看版本说明。 +**A**: 要查看数据库版本,主版本相同,升级(如 2.1 → 2.2)完全兼容,跨主版本升级要删除数据库并重建。 ### Q: 如何迁移到新电脑? @@ -276,5 +276,4 @@ C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\logs\ | 插件目录 | `C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\` | | 日志目录 | `C:\ProgramData\Autodesk\Navisworks Manage 2026\plugins\TransportPlugin\logs\` | -**文档版本**: 1.0 -**适用插件版本**: 2.0.0.0 及更高版本 +**文档版本**: 1.0 diff --git a/doc/introduction/2.1.1_模型切分功能设计说明.md b/doc/introduction/2.1.1_模型切分功能设计说明.md new file mode 100644 index 0000000..2880f9f --- /dev/null +++ b/doc/introduction/2.1.1_模型切分功能设计说明.md @@ -0,0 +1,252 @@ +# 2.1.1 模型切分功能设计说明 + +## 2.1.1.1. 模块描述 + +模型切分模块是通道选择及路径点规划功能的基础模块,负责将大型BIM模型按照楼层和区域进行分层切分,以便进行后续的物流路径规划。该模块通过多软件模型轻量化工具箱实现全模型的分层切分,支持忽略编组站区域楼层间上下贯穿模块的特殊处理需求。 + +该模块主要解决以下问题: +- 大型BIM模型数据量大,直接处理效率低下 +- 需要按楼层隔离,便于分层路径规划 +- 编组站等特殊区域存在跨楼层结构,需要特殊处理 + +## 2.1.1.2. 功能 + +### 核心功能 +1. **自动楼层检测**:基于模型几何信息和属性自动识别楼层高度和边界 +2. **分层切分**:将完整模型按楼层切分为独立的逻辑层 +3. **区域识别**:识别编组站等特殊区域的上下贯穿模块 +4. **忽略配置**:支持配置需要忽略的模型元素类型 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.1.1.F1 | 楼层检测 | 自动分析模型,检测楼层高度和边界框 | +| 2.1.1.F2 | 模型分层 | 根据检测结果将模型切分为多层 | +| 2.1.1.F3 | 贯穿模块处理 | 识别并标记跨楼层的贯穿结构 | +| 2.1.1.F4 | 分层预览 | 提供分层的可视化预览功能 | +| 2.1.1.F5 | 切分配置 | 支持手动调整楼层高度和切分参数 | + +## 2.1.1.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 楼层检测时间 | < 5秒 | 对于100MB以下的模型 | +| 切分操作响应 | < 1秒 | 切分配置应用后的响应时间 | +| 内存占用 | < 500MB | 切分过程中的额外内存占用 | +| 支持模型大小 | 无限制 | 依赖Navisworks原生支持 | + +### 性能优化策略 +1. 使用空间索引加速楼层检测 +2. 采用延迟加载策略处理大型模型 +3. 切分结果缓存,避免重复计算 + +## 2.1.1.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| Document | Document | 是 | Navisworks文档对象 | +| FloorHeightTolerance | double | 否 | 楼层高度容差(米),默认0.3米 | +| IgnoreCategories | List | 否 | 需要忽略的类别列表 | +| ManualFloorHeights | List | 否 | 手动指定的楼层高度 | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| FloorInfos | List | 楼层信息列表 | +| SplitModels | Dictionary | 分层后的模型集合 | +| ThroughModules | List | 识别的贯穿模块列表 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 楼层高度参数设置 +- 忽略的模型类别勾选 +- 切分预览确认 + +#### 界面输出 +- 分层预览显示 +- 楼层统计信息 +- 切分进度状态 + +## 2.1.1.5. 算法 + +### 楼层检测算法 +``` +算法:基于高度聚类的楼层检测 +输入:模型所有元素的包围盒集合 +输出:楼层高度列表 + +1. 收集所有水平面元素的高度值 +2. 使用DBSCAN聚类算法对高度值进行聚类 +3. 计算每个聚类的中心高度作为楼层高度 +4. 根据容差合并相近的楼层 +5. 返回排序后的楼层高度列表 +``` + +### 模型分层算法 +``` +算法:基于包围盒的模型分层 +输入:模型元素集合,楼层高度列表 +输出:分层后的模型集合 + +1. 对于每个楼层i: + 2. 计算楼层高度范围 [H_i - T, H_{i+1} + T] + 3. 遍历所有模型元素: + 4. 如果元素包围盒与楼层范围相交: + 5. 将元素加入该楼层集合 +6. 识别贯穿模块(跨越多层的元素) +7. 返回分层结果 +``` + +## 2.1.1.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 加载模型文档 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ 否 +│ 检测楼层高度? │────────► 手动输入楼层高度 +└────────┬────────┘ + │ 是 + ▼ +┌─────────────────┐ +│ 显示楼层预览 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 识别贯穿模块 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 应用切分配置 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 生成分层结果 │ +└────────┬────────┘ + │ + ▼ + 结束 +``` + +## 2.1.1.7. 接口 + +### 公共接口 +```csharp +/// +/// 模型切分管理器 +/// +public class ModelSplitterManager +{ + /// + /// 自动检测楼层 + /// + /// 高度容差(米) + /// 楼层信息列表 + public List AutoDetectFloors(double tolerance = 0.3); + + /// + /// 执行模型切分 + /// + /// 楼层信息 + /// 切分结果 + public SplitResult SplitModel(List floorInfos); + + /// + /// 获取贯穿模块 + /// + /// 贯穿模块列表 + public List GetThroughModules(); +} +``` + +### 事件接口 +```csharp +/// +/// 切分进度事件 +/// +public event EventHandler SplitProgress; + +/// +/// 楼层检测完成事件 +/// +public event EventHandler FloorsDetected; +``` + +## 2.1.1.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 楼层信息类 +/// 存储单个楼层的基本信息 +/// +public class FloorInfo +{ + /// + /// 楼层编号(从1开始) + /// + public int FloorNumber { get; set; } + + /// + /// 楼层高度(模型单位) + /// + public double Height { get; set; } + + /// + /// 楼层高度(米) + /// + public double HeightInMeters => UnitsConverter.ConvertToMeters(Height); +} +``` + +### 配置文件注释 +```toml +# 模型切分配置 +[model_splitter] +# 楼层检测高度容差(米) +floor_height_tolerance_meters = 0.3 +# 是否自动检测楼层 +auto_detect_floors = true +# 忽略的类别列表 +ignore_categories = ["地基", "基础"] +``` + +## 2.1.1.9. 数据结构 + +### FloorInfo 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| FloorNumber | int | 楼层编号 | +| Height | double | 楼层高度(模型单位) | +| Bounds | BoundingBox3D | 楼层包围盒 | +| ElementCount | int | 楼层元素数量 | +| IsThroughFloor | bool | 是否包含贯穿模块 | + +### SplitResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Floors | List | 楼层信息列表 | +| LayerModels | Dictionary | 分层模型字典 | +| ThroughModules | List | 贯穿模块列表 | +| SplitTime | DateTime | 切分时间 | + +### SplitProgressEventArgs 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| CurrentFloor | int | 当前处理楼层 | +| TotalFloors | int | 总楼层数 | +| ProgressPercentage | double | 进度百分比 | +| StatusMessage | string | 状态消息 | diff --git a/doc/introduction/2.1.2_通道选择功能设计说明.md b/doc/introduction/2.1.2_通道选择功能设计说明.md new file mode 100644 index 0000000..33d8849 --- /dev/null +++ b/doc/introduction/2.1.2_通道选择功能设计说明.md @@ -0,0 +1,246 @@ +# 2.1.2 通道选择功能设计说明 + +## 2.1.2.1. 模块描述 + +通道选择模块是物流路径规划系统的核心功能模块,负责支持用户通过选择树或三维视图点选的方式选择通道模型,并将其指定为通道类型。该模块是后续自动路径规划的基础,为A*算法提供可通行的通道区域数据。 + +通道选择模块与CategoryAttributeManager紧密集成,将选中的模型元素标记为物流属性中的"通道"类型,并设置相应的通行属性。 + +## 2.1.2.2. 功能 + +### 核心功能 +1. **选择树选择**:通过Navisworks选择树面板选择模型元素 +2. **三维点选**:在三维视图中直接点击选择模型元素 +3. **通道类型指定**:将选中的模型指定为通道类型 +4. **批量选择**:支持框选和批量选择多个元素 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.1.2.F1 | 选择树集成 | 与Navisworks选择树面板集成,支持树形结构选择 | +| 2.1.2.F2 | 三维点选 | 支持在三维视图中点击选择模型 | +| 2.1.2.F3 | 框选支持 | 支持矩形框选多个模型元素 | +| 2.1.2.F4 | 类型指定 | 将选中的模型指定为通道类型 | +| 2.1.2.F5 | 选择预览 | 高亮显示当前选中的模型元素 | +| 2.1.2.F6 | 选择确认 | 确认选择并应用通道属性 | + +## 2.1.2.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 点选响应时间 | < 100ms | 三维视图中点击选择的响应时间 | +| 批量选择支持 | > 1000个 | 单次批量选择的最大元素数量 | +| 属性应用时间 | < 500ms | 通道属性应用到选中元素的时间 | +| 内存占用 | < 100MB | 选择过程中的额外内存占用 | + +### 性能优化策略 +1. 使用空间索引加速三维点选 +2. 批量属性设置,减少COM API调用次数 +3. 选择结果缓存,避免重复查询 + +## 2.1.2.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| SelectedItems | ModelItemCollection | 是 | 选中的模型元素集合 | +| ChannelType | LogisticsElementType | 否 | 通道类型,默认Channel | +| Priority | int | 否 | 优先级,默认5 | +| IsTraversable | bool | 否 | 是否可通行,默认true | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| AppliedCount | int | 成功应用属性的元素数量 | +| FailedItems | List | 应用失败的元素列表 | +| ChannelItems | List | 当前所有通道元素列表 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 鼠标点击/框选操作 +- 选择树节点勾选 +- 通道属性参数设置 + +#### 界面输出 +- 选中元素高亮显示 +- 选择数量统计 +- 通道类型应用结果提示 + +## 2.1.2.5. 算法 + +### 三维点选算法 +``` +算法:基于射线检测的三维点选 +输入:鼠标屏幕坐标,相机参数 +输出:选中的模型元素 + +1. 将屏幕坐标转换为射线(Ray) +2. 遍历所有可见模型元素: + 3. 计算射线与元素包围盒的交点 + 4. 如果有交点,计算精确交点距离 +5. 返回距离最近的元素 +``` + +### 通道属性应用算法 +``` +算法:批量应用通道属性 +输入:选中的模型元素集合 +输出:应用结果 + +1. 初始化COM API +2. 对于每个选中的元素: + 3. 检查元素是否已有物流属性 + 4. 如果存在且冲突,记录冲突 + 5. 应用通道类型属性 + 6. 应用优先级、可通行性等属性 +7. 批量提交属性更改 +8. 返回应用统计 +``` + +## 2.1.2.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 进入选择模式 │ +└────────┬────────┘ + │ + ┌────┴────┐ + ▼ ▼ +┌────────┐ ┌────────┐ +│选择树 │ │三维点选│ +└───┬────┘ └───┬────┘ + │ │ + └─────┬─────┘ + │ + ▼ +┌─────────────────┐ +│ 显示选中预览 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 确认通道类型 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 应用通道属性 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 显示应用结果 │ +└────────┬────────┘ + │ + ▼ + 结束 +``` + +## 2.1.2.7. 接口 + +### 公共接口 +```csharp +/// +/// 通道选择管理器 +/// +public class ChannelSelectionManager +{ + /// + /// 设置选中元素为通道 + /// + /// 选中的模型元素 + /// 应用结果 + public ChannelSelectionResult SetAsChannel(ModelItemCollection items); + + /// + /// 获取所有通道元素 + /// + /// 通道元素列表 + public List GetAllChannels(); + + /// + /// 清除元素的通道属性 + /// + /// 要清除的元素 + /// 清除的元素数量 + public int ClearChannelAttribute(ModelItemCollection items); +} +``` + +### 事件接口 +```csharp +/// +/// 选择变更事件 +/// +public event EventHandler SelectionChanged; + +/// +/// 通道属性应用完成事件 +/// +public event EventHandler ChannelApplied; +``` + +## 2.1.2.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 通道选择结果 +/// +public class ChannelSelectionResult +{ + /// + /// 成功应用的元素数量 + /// + public int AppliedCount { get; set; } + + /// + /// 应用失败的元素列表 + /// 失败原因可能是元素已被锁定或API调用失败 + /// + public List FailedItems { get; set; } +} +``` + +### 配置文件注释 +```toml +# 通道选择配置 +[channel_selection] +# 默认通道类型 +default_channel_type = "通道" +# 默认优先级(1-10) +default_priority = 5 +# 点选容差(像素) +click_tolerance_pixels = 5 +``` + +## 2.1.2.9. 数据结构 + +### ChannelSelectionResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| AppliedCount | int | 成功应用的元素数量 | +| FailedCount | int | 失败的元素数量 | +| FailedItems | List | 失败的元素列表 | +| ConflictCount | int | 冲突的元素数量 | + +### SelectionChangedEventArgs 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| SelectedItems | ModelItemCollection | 当前选中的元素 | +| SelectionCount | int | 选中元素数量 | +| SelectionBounds | BoundingBox3D | 选中元素的包围盒 | + +### ChannelAppliedEventArgs 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| AppliedCount | int | 成功应用的元素数量 | +| ChannelType | LogisticsElementType | 应用的通道类型 | +| ApplyTime | DateTime | 应用时间 | diff --git a/doc/introduction/2.1.3_路径点规划功能设计说明.md b/doc/introduction/2.1.3_路径点规划功能设计说明.md new file mode 100644 index 0000000..bfb100c --- /dev/null +++ b/doc/introduction/2.1.3_路径点规划功能设计说明.md @@ -0,0 +1,287 @@ +# 2.1.3 路径点规划功能设计说明 + +## 2.1.3.1. 模块描述 + +路径点规划模块是物流路径规划系统的核心功能,针对较为复杂的环境,支持路径点功能。用户可以在三维视图中,在通道上点击指定起点、路径点、终点的位置及方向,并以三维可视化的方式显示路径。该模块支持多条路径的保存、选择和编辑,为物流运输提供精确的路径规划能力。 + +路径点规划模块与PathPlanningManager、PathClickToolPlugin和PathPointRenderPlugin紧密协作,实现从用户交互到路径生成的完整流程。 + +## 2.1.3.2. 功能 + +### 核心功能 +1. **路径点创建**:在三维视图中点击创建起点、路径点、终点 +2. **方向设置**:为每个路径点设置方向向量 +3. **路径生成**:根据路径点自动生成平滑路径 +4. **多路径管理**:支持多条路径的创建、保存和切换 +5. **三维可视化**:实时显示路径点和路径线 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.1.3.F1 | 起点设置 | 在三维视图中指定路径起点 | +| 2.1.3.F2 | 终点设置 | 在三维视图中指定路径终点 | +| 2.1.3.F3 | 中间点设置 | 添加路径中间点进行路径控制 | +| 2.1.3.F4 | 方向调整 | 调整路径点的方向向量 | +| 2.1.3.F5 | 路径预览 | 实时预览生成的路径 | +| 2.1.3.F6 | 路径编辑 | 编辑已有路径的点位置和方向 | +| 2.1.3.F7 | 多路径切换 | 在多条路径之间切换编辑 | +| 2.1.3.F8 | 路径删除 | 删除不需要的路径 | + +## 2.1.3.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 路径点创建响应 | < 200ms | 点击到点显示的响应时间 | +| 路径生成时间 | < 1秒 | 根据路径点生成完整路径的时间 | +| 支持路径点数量 | > 50个 | 单条路径支持的最大路径点数量 | +| 支持路径数量 | > 100条 | 支持保存的最大路径数量 | +| 渲染帧率 | > 30FPS | 路径可视化渲染帧率 | + +### 性能优化策略 +1. 使用缓存避免重复的路径计算 +2. 路径点批量渲染,减少Draw Call +3. 懒加载策略,非活动路径不渲染 + +## 2.1.3.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| PointType | PathPointType | 是 | 路径点类型(起点/中间点/终点) | +| Position | Point3D | 是 | 路径点三维坐标 | +| Direction | Vector3D | 否 | 路径点方向向量 | +| PathName | string | 否 | 路径名称 | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| PathRoute | PathRoute | 生成的路径对象 | +| PathLength | double | 路径总长度 | +| EstimatedTime | double | 预估通行时间 | +| PathPoints | List | 路径点列表 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 鼠标点击选择路径点位置 +- 方向调整操作 +- 路径参数设置 + +#### 界面输出 +- 三维路径点标记显示 +- 路径连线显示 +- 路径信息面板显示 + +## 2.1.3.5. 算法 + +### 路径点插值算法 +``` +算法:基于Catmull-Rom样条的路径平滑 +输入:路径点列表 +输出:平滑路径点列表 + +1. 对于每对相邻路径点: + 2. 计算控制点(使用前后点作为切线参考) + 3. 使用Catmull-Rom样条插值生成中间点 + 4. 将插值点加入结果列表 +5. 返回平滑后的路径点列表 +``` + +### 路径生成算法 +``` +算法:路径点驱动的路径生成 +输入:起点、中间点列表、终点 +输出:完整路径 + +1. 创建PathRoute对象 +2. 添加起点到路径 +3. 对于每个中间点: + 4. 计算与前一点的方向向量 + 5. 添加中间点到路径 +6. 添加终点到路径 +7. 计算路径长度和预估时间 +8. 触发路径生成事件 +``` + +## 2.1.3.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 进入路径编辑模式 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 设置起点 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 添加中间点? │────否────┐ +└────────┬────────┘ │ + │是 │ + ▼ │ +┌─────────────────┐ │ +│ 点击添加中间点 │ │ +└────────┬────────┘ │ + │ │ + └─────────┬─────────┘ + │ + ▼ +┌─────────────────┐ +│ 设置终点 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 生成路径预览 │ +└────────┬────────┘ + │ + ┌────┴────┐ + ▼ ▼ +┌────────┐ ┌────────┐ +│调整点 │ │确认保存│ +└───┬────┘ └───┬────┘ + │ │ + └─────┬─────┘ + │ + ▼ + 结束 +``` + +## 2.1.3.7. 接口 + +### 公共接口 +```csharp +/// +/// 路径规划管理器 +/// +public class PathPlanningManager +{ + /// + /// 添加路径点 + /// + /// 点位置 + /// 点类型 + /// 创建的路径点 + public PathPoint AddPathPoint(Point3D position, PathPointType type); + + /// + /// 生成路径 + /// + /// 生成的路径 + public PathRoute GeneratePath(); + + /// + /// 获取当前路径 + /// + /// 当前路径 + public PathRoute GetCurrentRoute(); + + /// + /// 切换当前路径 + /// + /// 路径名称 + public void SwitchRoute(string routeName); +} +``` + +### 事件接口 +```csharp +/// +/// 路径点添加事件 +/// +public event EventHandler PathPointAdded; + +/// +/// 路径生成完成事件 +/// +public event EventHandler PathGenerated; + +/// +/// 当前路径变更事件 +/// +public event EventHandler CurrentRouteChanged; +``` + +## 2.1.3.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 路径点类型 +/// +public enum PathPointType +{ + /// + /// 起点 + /// + Start, + + /// + /// 中间点(路径点) + /// + WayPoint, + + /// + /// 终点 + /// + End +} + +/// +/// 路径点类 +/// 表示路径上的一个关键节点 +/// +public class PathPoint +{ + /// + /// 点唯一标识 + /// + public string Id { get; set; } + + /// + /// 点位置(模型单位) + /// + public Point3D Position { get; set; } + + /// + /// 点方向(用于控制路径走向) + /// + public Vector3D Direction { get; set; } +} +``` + +## 2.1.3.9. 数据结构 + +### PathPoint 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Id | string | 点唯一标识符 | +| Position | Point3D | 三维坐标位置 | +| Direction | Vector3D | 方向向量 | +| Type | PathPointType | 点类型 | +| Index | int | 在路径中的索引 | + +### PathRoute 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Id | string | 路径唯一标识符 | +| Name | string | 路径名称 | +| Points | List | 路径点列表 | +| TotalLength | double | 路径总长度(米) | +| EstimatedTime | double | 预估通行时间(秒) | +| CreateTime | DateTime | 创建时间 | + +### PathPointAddedEventArgs 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Point | PathPoint | 添加的路径点 | +| PointIndex | int | 点索引 | +| TotalPoints | int | 当前总点数 | diff --git a/doc/introduction/2.1.4_编辑保存和导入功能设计说明.md b/doc/introduction/2.1.4_编辑保存和导入功能设计说明.md new file mode 100644 index 0000000..0820323 --- /dev/null +++ b/doc/introduction/2.1.4_编辑保存和导入功能设计说明.md @@ -0,0 +1,369 @@ +# 2.1.4 编辑保存和导入功能设计说明 + +## 2.1.4.1. 模块描述 + +编辑保存和导入模块负责路径数据的管理功能,支持对路径上的各点进行坐标编辑,保存当前路径点集合为路径规划文件,以及从文件导入路径并在当前通道表面重绘路径。该模块还支持记录并查看路径文件操作的历史记录,为用户提供完整的路径数据生命周期管理。 + +该模块与PathDatabase、PathDataManager和各类导出器(XML/JSON/CSV)紧密集成,实现路径数据的持久化和交换。 + +## 2.1.4.2. 功能 + +### 核心功能 +1. **坐标编辑**:支持对路径点的坐标进行精确编辑 +2. **路径保存**:将路径保存为XML、JSON、CSV格式文件 +3. **路径导入**:从文件导入路径并在当前场景重绘 +4. **历史记录**:记录路径文件操作历史,支持查看和回溯 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.1.4.F1 | 坐标编辑 | 编辑路径点的X/Y/Z坐标 | +| 2.1.4.F2 | 批量编辑 | 批量修改多个路径点坐标 | +| 2.1.4.F3 | XML导出 | 导出路径为XML格式 | +| 2.1.4.F4 | JSON导出 | 导出路径为JSON格式 | +| 2.1.4.F5 | CSV导出 | 导出路径为CSV格式 | +| 2.1.4.F6 | XML导入 | 从XML文件导入路径 | +| 2.1.4.F7 | JSON导入 | 从JSON文件导入路径 | +| 2.1.4.F8 | CSV导入 | 从CSV文件导入路径 | +| 2.1.4.F9 | 路径重绘 | 导入后在当前场景重绘路径 | +| 2.1.4.F10 | 历史记录 | 记录和查看文件操作历史 | + +## 2.1.4.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 保存响应时间 | < 500ms | 保存路径到文件的时间 | +| 导入响应时间 | < 1秒 | 从文件导入路径的时间 | +| 支持文件大小 | > 10MB | 支持导入的最大文件大小 | +| 历史记录数量 | > 1000条 | 支持保存的最大历史记录数 | +| 批量编辑响应 | < 200ms | 批量编辑操作的响应时间 | + +### 性能优化策略 +1. 使用流式读写处理大文件 +2. 数据库批量操作优化历史记录写入 +3. 异步文件操作避免阻塞UI + +## 2.1.4.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段(保存) +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| Route | PathRoute | 是 | 要保存的路径对象 | +| FilePath | string | 是 | 目标文件路径 | +| Format | ExportFormat | 是 | 导出格式 | + +#### 输入字段(导入) +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| FilePath | string | 是 | 源文件路径 | +| Format | ImportFormat | 否 | 导入格式(自动检测) | + +#### 输入字段(编辑) +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| PointId | string | 是 | 要编辑的点ID | +| NewPosition | Point3D | 是 | 新坐标位置 | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Success | bool | 操作是否成功 | +| Message | string | 操作结果消息 | +| ImportedRoute | PathRoute | 导入的路径对象 | +| HistoryRecords | List | 历史记录列表 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 文件选择对话框操作 +- 坐标编辑表单输入 +- 导入格式选择 + +#### 界面输出 +- 文件保存/导入进度 +- 操作结果提示 +- 历史记录列表显示 + +## 2.1.4.5. 算法 + +### 坐标编辑算法 +``` +算法:路径点坐标编辑 +输入:点ID,新坐标 +输出:编辑结果 + +1. 根据ID查找路径点 +2. 验证新坐标的有效性 +3. 更新路径点坐标 +4. 重新计算路径长度 +5. 更新路径显示 +6. 记录编辑历史 +``` + +### 路径导出算法 +``` +算法:路径数据导出 +输入:路径对象,目标格式 +输出:文件内容 + +1. 根据格式选择对应的导出器 +2. 序列化路径数据 +3. 应用格式特定的转换 +4. 写入文件 +5. 记录导出历史 +``` + +### 路径导入算法 +``` +算法:路径数据导入 +输入:文件路径 +输出:路径对象 + +1. 检测文件格式 +2. 选择对应的导入器 +3. 解析文件内容 +4. 验证数据完整性 +5. 创建路径对象 +6. 在当前场景重绘路径 +7. 记录导入历史 +``` + +## 2.1.4.6. 流程逻辑 + +``` +开始 + │ + ├──┬── 保存路径 ──┐ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││选择保存格式 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││选择文件路径 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││执行导出操作 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││记录保存历史 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││显示保存结果 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │ 结束 ◄─────┘ + │ + ├──┬── 导入路径 ──┐ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││选择导入文件 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││检测文件格式 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││解析文件内容 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││验证数据 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││重绘路径 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │┌─────────────┐ │ + ││记录导入历史 │ │ + │└──────┬──────┘ │ + │ │ │ + │ ▼ │ + │ 结束 ◄─────┘ + │ + └──┬── 编辑坐标 ──┐ + │ │ + ▼ │ + ┌─────────────┐ │ + │选择编辑的点 │ │ + └──────┬──────┘ │ + │ │ + ▼ │ + ┌─────────────┐ │ + │输入新坐标 │ │ + └──────┬──────┘ │ + │ │ + ▼ │ + ┌─────────────┐ │ + │验证坐标 │ │ + └──────┬──────┘ │ + │ │ + ▼ │ + ┌─────────────┐ │ + │更新路径显示 │ │ + └──────┬──────┘ │ + │ │ + ▼ │ + 结束 ◄─────┘ +``` + +## 2.1.4.7. 接口 + +### 公共接口 +```csharp +/// +/// 路径数据管理器 +/// +public class PathDataManager +{ + /// + /// 保存路径到文件 + /// + /// 路径对象 + /// 文件路径 + /// 导出格式 + /// 保存结果 + public SaveResult SavePath(PathRoute route, string filePath, ExportFormat format); + + /// + /// 从文件导入路径 + /// + /// 文件路径 + /// 导入的路径对象 + public ImportResult ImportPath(string filePath); + + /// + /// 编辑路径点坐标 + /// + /// 点ID + /// 新坐标 + /// 编辑结果 + public EditResult EditPointCoordinate(string pointId, Point3D newPosition); + + /// + /// 获取历史记录 + /// + /// 历史记录列表 + public List GetHistoryRecords(); +} +``` + +### 事件接口 +```csharp +/// +/// 路径保存完成事件 +/// +public event EventHandler PathSaved; + +/// +/// 路径导入完成事件 +/// +public event EventHandler PathImported; + +/// +/// 坐标编辑完成事件 +/// +public event EventHandler CoordinateEdited; +``` + +## 2.1.4.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 导出格式枚举 +/// +public enum ExportFormat +{ + /// + /// XML格式 + /// + XML, + + /// + /// JSON格式 + /// + JSON, + + /// + /// CSV格式 + /// + CSV +} + +/// +/// 保存结果 +/// +public class SaveResult +{ + /// + /// 是否保存成功 + /// + public bool Success { get; set; } + + /// + /// 结果消息 + /// + public string Message { get; set; } + + /// + /// 保存的文件路径 + /// + public string FilePath { get; set; } +} +``` + +## 2.1.4.9. 数据结构 + +### ExportFormat 枚举 +| 值 | 说明 | +|---|------| +| XML | XML格式导出 | +| JSON | JSON格式导出 | +| CSV | CSV格式导出 | + +### SaveResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Success | bool | 保存是否成功 | +| Message | string | 结果消息 | +| FilePath | string | 保存的文件路径 | +| FileSize | long | 文件大小(字节) | + +### ImportResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Success | bool | 导入是否成功 | +| Message | string | 结果消息 | +| ImportedRoute | PathRoute | 导入的路径对象 | +| Format | ImportFormat | 检测到的格式 | + +### HistoryRecord 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Id | string | 记录ID | +| OperationType | string | 操作类型(保存/导入/编辑) | +| FilePath | string | 相关文件路径 | +| OperationTime | DateTime | 操作时间 | +| UserName | string | 操作用户 | +| Details | string | 操作详情 | diff --git a/doc/introduction/2.1.5_路径点自动贴合功能设计说明.md b/doc/introduction/2.1.5_路径点自动贴合功能设计说明.md new file mode 100644 index 0000000..b6e42ab --- /dev/null +++ b/doc/introduction/2.1.5_路径点自动贴合功能设计说明.md @@ -0,0 +1,277 @@ +# 2.1.5 路径点自动贴合功能设计说明 + +## 2.1.5.1. 模块描述 + +路径点自动贴合模块是路径规划系统的重要功能,负责确保路径点自动贴合通道模型表面,并使路径点之间通过直线进行联通。该模块解决了用户手动选择路径点时可能无法精确贴合模型表面的问题,确保生成的路径在物理上可行。 + +该模块使用射线投射和几何计算算法,自动计算路径点与通道表面的最近点,并生成直线路径连接各点。 + +## 2.1.5.2. 功能 + +### 核心功能 +1. **表面贴合**:自动将路径点投影到通道模型表面 +2. **高度调整**:根据通道表面高度调整路径点Z坐标 +3. **直线联通**:在路径点之间生成直线连接 +4. **碰撞避免**:确保路径点不会位于障碍物内部 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.1.5.F1 | 射线投射贴合 | 使用射线投射找到模型表面交点 | +| 2.1.5.F2 | 最近点计算 | 计算点到模型表面的最近点 | +| 2.1.5.F3 | 高度自适应 | 根据表面高度自动调整路径点 | +| 2.1.5.F4 | 直线生成 | 在路径点之间生成直线路径 | +| 2.1.5.F5 | 碰撞检测 | 检测路径点是否与障碍物碰撞 | +| 2.1.5.F6 | 智能修正 | 自动修正位于障碍物内的点 | + +## 2.1.5.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 贴合计算时间 | < 100ms | 单个路径点的贴合计算时间 | +| 批量贴合时间 | < 500ms | 10个路径点的批量贴合时间 | +| 射线检测精度 | 1mm | 射线投射检测的精度 | +| 支持模型复杂度 | 无限制 | 支持的大型模型复杂度 | + +### 性能优化策略 +1. 使用空间索引加速射线投射 +2. 缓存通道表面几何信息 +3. 批量处理路径点贴合 + +## 2.1.5.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| OriginalPoint | Point3D | 是 | 原始路径点坐标 | +| ChannelItems | List | 是 | 通道模型元素列表 | +| SearchRadius | double | 否 | 搜索半径(米),默认1.0米 | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| SnappedPoint | Point3D | 贴合后的路径点坐标 | +| SurfaceNormal | Vector3D | 表面法向量 | +| Distance | double | 贴合距离 | +| Success | bool | 贴合是否成功 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 启用/禁用自动贴合选项 +- 贴合精度参数设置 +- 手动触发贴合操作 + +#### 界面输出 +- 贴合结果可视化 +- 贴合距离显示 +- 贴合失败提示 + +## 2.1.5.5. 算法 + +### 表面贴合算法 +``` +算法:基于射线投射的表面贴合 +输入:原始点,通道模型集合 +输出:贴合后的点 + +1. 从原始点向上发射射线 +2. 遍历所有通道模型: + 3. 计算射线与模型三角面的交点 + 4. 记录最近的交点 +5. 如果没有交点: + 6. 从原始点向下发射射线 + 7. 重复步骤2-4 +8. 返回最近的交点作为贴合点 +``` + +### 最近点计算算法 +``` +算法:点到模型表面的最近点 +输入:点,模型集合 +输出:最近点 + +1. 初始化最小距离为无穷大 +2. 初始化最近点为原始点 +3. 对于每个模型的每个三角面: + 4. 计算点到三角面的最近点 + 5. 计算距离 + 6. 如果距离小于最小距离: + 7. 更新最小距离和最近点 +8. 返回最近点 +``` + +### 直线联通算法 +``` +算法:路径点直线连接 +输入:路径点列表 +输出:直线路径 + +1. 对于每对相邻的路径点: + 2. 计算起点和终点 + 3. 在两点之间进行线性插值 + 4. 生成中间路径点 + 5. 将中间点加入路径 +6. 返回完整路径 +``` + +## 2.1.5.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 创建路径点 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ 否 +│ 启用自动贴合? │────────────────┐ +└────────┬────────┘ │ + │是 │ + ▼ │ +┌─────────────────┐ │ +│ 发射射线检测 │ │ +└────────┬────────┘ │ + │ │ + ▼ │ +┌─────────────────┐ 否 │ +│ 找到表面交点? │───────────────┤ +└────────┬────────┘ │ + │是 │ + ▼ │ +┌─────────────────┐ │ +│ 计算贴合点坐标 │ │ +└────────┬────────┘ │ + │ │ + ▼ │ +┌─────────────────┐ │ +│ 更新路径点位置 │ │ +└────────┬────────┘ │ + │ │ + ┌────┴───────────────────────┘ + │ + ▼ +┌─────────────────┐ +│ 连接相邻点 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 显示路径 │ +└────────┬────────┘ + │ + ▼ + 结束 +``` + +## 2.1.5.7. 接口 + +### 公共接口 +```csharp +/// +/// 路径点贴合器 +/// +public class PathPointSnapper +{ + /// + /// 将路径点贴合到通道表面 + /// + /// 原始路径点 + /// 通道模型集合 + /// 贴合结果 + public SnapResult SnapToSurface(Point3D point, List channelItems); + + /// + /// 批量贴合路径点 + /// + /// 路径点列表 + /// 通道模型集合 + /// 贴合结果列表 + public List SnapPointsToSurface(List points, List channelItems); + + /// + /// 计算点到模型表面的最近点 + /// + /// 原始点 + /// 模型元素 + /// 最近点 + public Point3D GetNearestPointOnSurface(Point3D point, ModelItem modelItem); +} +``` + +### 事件接口 +```csharp +/// +/// 路径点贴合完成事件 +/// +public event EventHandler PointSnapped; + +/// +/// 批量贴合完成事件 +/// +public event EventHandler BatchSnapCompleted; +``` + +## 2.1.5.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 贴合结果 +/// +public class SnapResult +{ + /// + /// 原始点坐标 + /// + public Point3D OriginalPoint { get; set; } + + /// + /// 贴合后的点坐标 + /// 如果贴合失败,与OriginalPoint相同 + /// + public Point3D SnappedPoint { get; set; } + + /// + /// 表面法向量 + /// 用于确定表面的朝向 + /// + public Vector3D SurfaceNormal { get; set; } + + /// + /// 贴合是否成功 + /// + public bool Success { get; set; } +} +``` + +## 2.1.5.9. 数据结构 + +### SnapResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| OriginalPoint | Point3D | 原始点坐标 | +| SnappedPoint | Point3D | 贴合后的点坐标 | +| SurfaceNormal | Vector3D | 表面法向量 | +| Distance | double | 贴合距离 | +| Success | bool | 贴合是否成功 | +| ErrorMessage | string | 错误消息(如果失败) | + +### PointSnappedEventArgs 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| OriginalPoint | Point3D | 原始点 | +| SnappedPoint | Point3D | 贴合后的点 | +| Success | bool | 是否成功 | + +### BatchSnapCompletedEventArgs 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Results | List | 所有贴合结果 | +| SuccessCount | int | 成功数量 | +| FailCount | int | 失败数量 | diff --git a/doc/introduction/2.2.1_类别设置功能设计说明.md b/doc/introduction/2.2.1_类别设置功能设计说明.md new file mode 100644 index 0000000..327f76a --- /dev/null +++ b/doc/introduction/2.2.1_类别设置功能设计说明.md @@ -0,0 +1,213 @@ +# 2.2.1 类别设置功能设计说明 + +## 2.2.1.1. 模块描述 + +类别设置模块是物流"类别"设置功能的核心模块,负责在模型属性页面新增"物流属性"类别。该模块为后续的物流元素分类和属性管理提供基础支持,通过扩展Navisworks的属性系统,为模型元素添加物流相关的分类信息。 + +该模块与CategoryAttributeManager和NavisworksComPropertyManager紧密集成,使用COM API在模型元素上创建自定义的"物流属性"类别。 + +## 2.2.1.2. 功能 + +### 核心功能 +1. **类别创建**:在模型属性页面创建"物流属性"类别 +2. **类别管理**:管理物流属性的类别定义和结构 +3. **属性扩展**:为类别添加自定义属性字段 +4. **持久化存储**:将类别信息持久化存储在模型中 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.2.1.F1 | 类别初始化 | 初始化物流属性类别结构 | +| 2.2.1.F2 | 类别检查 | 检查元素是否已有物流属性 | +| 2.2.1.F3 | 类别添加 | 为元素添加物流属性类别 | +| 2.2.1.F4 | 类别移除 | 从元素移除物流属性类别 | +| 2.2.1.F5 | 类别查询 | 查询具有特定类别的元素 | + +## 2.2.1.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 类别添加时间 | < 100ms | 为单个元素添加类别的时间 | +| 批量添加时间 | < 1秒 | 为100个元素批量添加类别 | +| 类别查询时间 | < 500ms | 查询特定类别元素的时间 | +| 内存占用 | < 50MB | 类别管理的额外内存占用 | + +### 性能优化策略 +1. 批量COM API调用减少开销 +2. 类别缓存避免重复查询 +3. 延迟加载策略 + +## 2.2.1.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| Items | ModelItemCollection | 是 | 要添加类别的模型元素 | +| CategoryName | string | 否 | 类别名称,默认"物流属性" | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| SuccessCount | int | 成功添加类别的元素数量 | +| HasCategory | bool | 元素是否已有物流属性 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 类别名称设置 +- 元素选择确认 +- 类别添加/移除操作 + +#### 界面输出 +- 类别添加结果提示 +- 元素属性面板更新 +- 类别统计信息 + +## 2.2.1.5. 算法 + +### 类别添加算法 +``` +算法:为元素添加物流属性类别 +输入:模型元素集合 +输出:添加结果 + +1. 初始化COM API +2. 对于每个元素: + 3. 检查元素是否已有物流属性 + 4. 如果已有,跳过 + 5. 创建"物流属性"类别 + 6. 添加类别到元素的属性集合 +7. 提交更改 +8. 返回统计结果 +``` + +### 类别查询算法 +``` +算法:查询具有物流属性的元素 +输入:搜索范围 +输出:元素列表 + +1. 创建搜索条件 +2. 设置搜索条件:PropertyCategory = "物流属性" +3. 执行搜索 +4. 返回匹配的元素集合 +``` + +## 2.2.1.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 选择模型元素 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ 是 +│ 已有物流属性? │──────────┐ +└────────┬────────┘ │ + │否 │ + ▼ │ +┌─────────────────┐ │ +│ 创建物流属性类别 │ │ +└────────┬────────┘ │ + │ │ + ▼ │ +┌─────────────────┐ │ +│ 添加类别到元素 │ │ +└────────┬────────┘ │ + │ │ + ┌────┴───────────────────┘ + │ + ▼ +┌─────────────────┐ +│ 更新属性面板 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 显示操作结果 │ +└────────┬────────┘ + │ + ▼ + 结束 +``` + +## 2.2.1.7. 接口 + +### 公共接口 +```csharp +/// +/// 类别属性管理器 +/// +public class CategoryAttributeManager +{ + /// + /// 添加物流属性类别 + /// + /// 模型元素集合 + /// 成功添加的数量 + public int AddLogisticsCategory(ModelItemCollection items); + + /// + /// 检查元素是否有物流属性 + /// + /// 模型元素 + /// 是否有物流属性 + public bool HasLogisticsCategory(ModelItem item); + + /// + /// 移除物流属性类别 + /// + /// 模型元素集合 + /// 成功移除的数量 + public int RemoveLogisticsCategory(ModelItemCollection items); + + /// + /// 获取所有具有物流属性的元素 + /// + /// 元素列表 + public List GetAllLogisticsItems(); +} +``` + +## 2.2.1.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 物流类别定义 +/// +public static class LogisticsCategories +{ + /// + /// 物流属性类别显示名称 + /// + public const string LOGISTICS = "物流属性"; + + /// + /// 物流属性类别内部名称 + /// 用于COM API操作 + /// + public const string CATEGORY_INTERNAL_NAME = "物流属性_Internal"; +} +``` + +## 2.2.1.9. 数据结构 + +### LogisticsCategories 常量 +| 常量名 | 值 | 说明 | +|-------|---|------| +| LOGISTICS | "物流属性" | 类别显示名称 | +| CATEGORY_INTERNAL_NAME | "物流属性_Internal" | 类别内部名称 | + +### CategoryResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| SuccessCount | int | 成功数量 | +| FailCount | int | 失败数量 | +| ProcessedItems | List | 处理的元素 | diff --git a/doc/introduction/2.2.2_属性设置功能设计说明.md b/doc/introduction/2.2.2_属性设置功能设计说明.md new file mode 100644 index 0000000..2771a96 --- /dev/null +++ b/doc/introduction/2.2.2_属性设置功能设计说明.md @@ -0,0 +1,301 @@ +# 2.2.2 属性设置功能设计说明 + +## 2.2.2.1. 模块描述 + +属性设置模块是物流"类别"设置功能的核心模块,负责支持通过选择树和三维视图选择的方式,选择物流路径相关的元素(如门、电梯、楼梯、通道等),设置为特定的物流分类,并支持类型、可通行性、速度限制、宽度限制、优先级等属性的设置。同时支持在工具箱中进行识别和筛选,支持物流分类属性的添加、编辑和清除。 + +该模块与CategoryAttributeManager、LogisticsControlPanel和ConfigManager紧密集成,实现完整的物流属性管理功能。 + +## 2.2.2.2. 功能 + +### 核心功能 +1. **元素选择**:通过选择树或三维视图选择物流元素 +2. **分类设置**:设置元素的物流分类(门、电梯、楼梯、通道等) +3. **属性配置**:配置类型、可通行性、速度限制、宽度限制、优先级等属性 +4. **工具箱集成**:在工具箱中进行识别和筛选 +5. **属性编辑**:支持物流分类属性的添加、编辑和清除 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.2.2.F1 | 选择树选择 | 通过选择树面板选择元素 | +| 2.2.2.F2 | 三维视图选择 | 在三维视图中点选元素 | +| 2.2.2.F3 | 分类设置 | 设置元素的物流分类类型 | +| 2.2.2.F4 | 可通行性设置 | 设置元素是否可通行 | +| 2.2.2.F5 | 优先级设置 | 设置元素的优先级(1-10) | +| 2.2.2.F6 | 速度限制设置 | 设置元素的速度限制 | +| 2.2.2.F7 | 宽度限制设置 | 设置元素的宽度限制 | +| 2.2.2.F8 | 高度限制设置 | 设置元素的高度限制 | +| 2.2.2.F9 | 属性清除 | 清除元素的物流属性 | +| 2.2.2.F10 | 工具箱筛选 | 在工具箱中按分类筛选元素 | + +## 2.2.2.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 属性设置响应 | < 200ms | 设置单个元素属性的响应时间 | +| 批量设置时间 | < 2秒 | 批量设置100个元素属性的时间 | +| 筛选查询时间 | < 500ms | 按分类筛选元素的查询时间 | +| 内存占用 | < 100MB | 属性管理的额外内存占用 | + +### 性能优化策略 +1. 批量COM API调用减少开销 +2. 属性缓存机制 +3. 异步处理大批量操作 + +## 2.2.2.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| Items | ModelItemCollection | 是 | 选中的模型元素 | +| ElementType | LogisticsElementType | 是 | 物流元素类型 | +| IsTraversable | bool | 否 | 是否可通行,默认true | +| Priority | int | 否 | 优先级(1-10),默认5 | +| HeightLimit | double | 否 | 高度限制(米),默认3.0 | +| SpeedLimit | double | 否 | 速度限制(米/秒),默认0.8 | +| WidthLimit | double | 否 | 宽度限制(米),默认3.0 | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| AppliedCount | int | 成功应用属性的元素数量 | +| FailedItems | List | 应用失败的元素列表 | +| CurrentAttributes | Dictionary | 当前元素的所有属性 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 元素选择操作 +- 分类类型下拉选择 +- 属性值输入 +- 批量操作确认 + +#### 界面输出 +- 选中元素高亮显示 +- 属性设置结果提示 +- 当前属性值显示 +- 统计信息面板 + +## 2.2.2.5. 算法 + +### 属性设置算法 +``` +算法:设置物流元素属性 +输入:模型元素集合,属性参数 +输出:设置结果 + +1. 准备属性字典 + - 类型:ElementType.ToString() + - 可通行:IsTraversable ? "是" : "否" + - 优先级:Priority.ToString() + - 高度限制:HeightLimit + " m" + - 速度限制:SpeedLimit + " m/s" + - 宽度限制:WidthLimit + " m" + +2. 准备内部名称字典 + +3. 调用COM API批量设置属性 + +4. 如果是空轨类型,预计算基准路径 + +5. 返回应用统计 +``` + +### 分类筛选算法 +``` +算法:按物流分类筛选元素 +输入:分类类型 +输出:匹配的元素列表 + +1. 创建搜索条件 +2. 设置搜索条件: + - PropertyName = "类型" + - Condition = Equal + - Value = 分类类型.ToString() +3. 执行搜索 +4. 返回匹配的元素集合 +``` + +## 2.2.2.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 选择模型元素 │ +└────────┬────────┘ + │ + ┌────┴────┐ + ▼ ▼ +┌────────┐ ┌────────┐ +│选择树 │ │三维视图│ +└───┬────┘ └───┬────┘ + │ │ + └─────┬─────┘ + │ + ▼ +┌─────────────────┐ +│ 显示选中预览 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 设置分类类型 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 配置属性参数 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 应用属性设置 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 显示设置结果 │ +└────────┬────────┘ + │ + ▼ + 结束 +``` + +## 2.2.2.7. 接口 + +### 公共接口 +```csharp +/// +/// 类别属性管理器 +/// +public class CategoryAttributeManager +{ + /// + /// 添加物流属性(使用配置默认值) + /// + public static int AddLogisticsAttributes( + ModelItemCollection items, + LogisticsElementType elementType); + + /// + /// 添加物流属性(指定所有参数) + /// + public static int AddLogisticsAttributes( + ModelItemCollection items, + LogisticsElementType elementType, + bool isTraversable, + int priority, + double heightLimit, + double speedLimit, + double widthLimit); + + /// + /// 清除物流属性 + /// + public static int ClearLogisticsAttributes(ModelItemCollection items); + + /// + /// 按类型获取物流元素 + /// + public static List GetLogisticsItemsByType(string typeName); + + /// + /// 获取所有可通行物流元素 + /// + public static List GetAllTraversableLogisticsItems(); +} +``` + +### 物流元素类型枚举 +```csharp +public enum LogisticsElementType +{ + 空洞 = 0, // 不可通行 + 障碍物 = 1, // 不可通行 + 楼板 = 2, // 基础可通行,权重1.0 + 门 = 3, // 可通行,权重1.2 + 电梯 = 4, // 可通行,权重2.0 + 楼梯 = 5, // 可通行,权重3.0 + 通道 = 6, // 可通行,优先路径,权重0.5 + 走廊 = 7, // 可通行,权重0.6 + 装卸区 = 8, // 可通行,权重0.8 + 停车位 = 9, // 可通行,权重0.9 + 空轨 = 10, // 可通行,权重0.7 + 无关项 = 11 // 不参与网格生成 +} +``` + +## 2.2.2.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 物流属性定义 +/// +public static class LogisticsProperties +{ + /// + /// 物流元素类型 + /// + public const string TYPE = "类型"; + + /// + /// 是否可通行 + /// + public const string TRAVERSABLE = "可通行"; + + /// + /// 优先级(1-10) + /// + public const string PRIORITY = "优先级"; + + /// + /// 高度限制(米) + /// + public const string HEIGHT_LIMIT = "高度限制"; + + /// + /// 速度限制(米/秒) + /// + public const string SPEED_LIMIT = "速度限制"; + + /// + /// 宽度限制(米) + /// + public const string WIDTH_LIMIT = "宽度限制"; +} +``` + +## 2.2.2.9. 数据结构 + +### LogisticsElementType 枚举 +| 值 | 名称 | 说明 | 权重 | +|---|------|------|-----| +| 0 | 空洞 | 没有任何几何覆盖,不可通行 | - | +| 1 | 障碍物 | 墙体、柱子、设备等,不可通行 | - | +| 2 | 楼板 | 基础可通行区域 | 1.0 | +| 3 | 门 | 可通行 | 1.2 | +| 4 | 电梯 | 可通行 | 2.0 | +| 5 | 楼梯 | 可通行 | 3.0 | +| 6 | 通道 | 可通行,优先路径 | 0.5 | +| 7 | 走廊 | 可通行 | 0.6 | +| 8 | 装卸区 | 可通行 | 0.8 | +| 9 | 停车位 | 可通行 | 0.9 | +| 10 | 空轨 | 空中运输路径 | 0.7 | +| 11 | 无关项 | 不参与网格生成 | - | + +### LogisticsAttribute 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| ElementType | LogisticsElementType | 元素类型 | +| IsTraversable | bool | 是否可通行 | +| Priority | int | 优先级 | +| HeightLimitMeters | double | 高度限制(米) | +| SpeedLimitMetersPerSecond | double | 速度限制(米/秒) | +| WidthLimitMeters | double | 宽度限制(米) | diff --git a/doc/introduction/2.3.1_层级显示功能设计说明.md b/doc/introduction/2.3.1_层级显示功能设计说明.md new file mode 100644 index 0000000..b85b1d1 --- /dev/null +++ b/doc/introduction/2.3.1_层级显示功能设计说明.md @@ -0,0 +1,280 @@ +# 2.3.1 层级显示功能设计说明 + +## 2.3.1.1. 模块描述 + +层级显示模块是层级创建功能的核心模块,负责支持自动隐藏或淡化非关键层,以便专注于物流路径相关的层级。该模块通过智能的可见性控制,帮助用户在复杂的BIM模型中聚焦于当前关注的楼层,提高路径规划的可视化效果和工作效率。 + +该模块与LayerManagementViewModel、VisibilityHelper和Navisworks API紧密集成,实现层级的显示、隐藏和淡化控制。 + +## 2.3.1.2. 功能 + +### 核心功能 +1. **层级识别**:自动识别模型的楼层结构 +2. **智能隐藏**:自动隐藏非关键楼层 +3. **淡化显示**:淡化显示相关但非当前关注的楼层 +4. **快速切换**:快速切换当前显示的楼层 +5. **恢复显示**:一键恢复所有楼层的显示 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.3.1.F1 | 楼层检测 | 自动检测模型的楼层结构 | +| 2.3.1.F2 | 关键层标记 | 标记包含物流路径的关键楼层 | +| 2.3.1.F3 | 非关键层隐藏 | 自动隐藏非关键楼层 | +| 2.3.1.F4 | 相邻层淡化 | 淡化显示相邻楼层 | +| 2.3.1.F5 | 楼层切换 | 快速切换到指定楼层 | +| 2.3.1.F6 | 显示恢复 | 恢复所有楼层显示 | +| 2.3.1.F7 | 透明度设置 | 设置淡化层的透明度 | + +## 2.3.1.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 楼层切换响应 | < 500ms | 切换楼层的响应时间 | +| 批量隐藏时间 | < 1秒 | 隐藏多个楼层的处理时间 | +| 渲染帧率 | > 30FPS | 层级操作后的渲染帧率 | +| 内存占用 | < 50MB | 层级管理的额外内存占用 | + +### 性能优化策略 +1. 批量可见性操作减少API调用 +2. 延迟更新策略避免频繁重绘 +3. 可见性状态缓存 + +## 2.3.1.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| TargetFloor | int | 是 | 目标楼层编号 | +| HideNonKeyFloors | bool | 否 | 是否隐藏非关键层,默认true | +| DimAdjacentFloors | bool | 否 | 是否淡化相邻层,默认true | +| DimOpacity | double | 否 | 淡化透明度(0-1),默认0.3 | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| VisibleFloors | List | 当前可见的楼层列表 | +| HiddenFloors | List | 当前隐藏的楼层列表 | +| DimmedFloors | List | 当前淡化的楼层列表 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 楼层选择下拉框 +- 显示/隐藏/淡化选项勾选 +- 透明度滑块调整 + +#### 界面输出 +- 楼层列表显示 +- 当前可见状态指示 +- 操作结果提示 + +## 2.3.1.5. 算法 + +### 楼层检测算法 +``` +算法:检测模型楼层结构 +输入:模型元素集合 +输出:楼层列表 + +1. 遍历所有模型元素 +2. 提取元素的Z坐标范围 +3. 使用聚类算法识别楼层 +4. 为每个楼层分配编号 +5. 返回楼层列表 +``` + +### 层级显示控制算法 +``` +算法:控制楼层显示状态 +输入:目标楼层,显示参数 +输出:应用结果 + +1. 识别关键楼层(包含物流元素的楼层) +2. 对于每个楼层: + 3. 如果是目标楼层: + 4. 设置为完全可见 + 5. 否则如果是相邻楼层且允许淡化: + 6. 设置为淡化显示 + 7. 否则如果允许隐藏非关键层: + 8. 设置为隐藏 + 9. 否则: + 10. 设置为淡化显示 +11. 批量应用可见性设置 +``` + +## 2.3.1.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 检测楼层结构 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 识别关键楼层 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 选择目标楼层 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 配置显示参数 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 应用可见性设置 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 更新视图显示 │ +└────────┬────────┘ + │ + ▼ + 结束 +``` + +## 2.3.1.7. 接口 + +### 公共接口 +```csharp +/// +/// 层级管理视图模型 +/// +public class LayerManagementViewModel +{ + /// + /// 切换到指定楼层 + /// + /// 楼层编号 + public void SwitchToFloor(int floorNumber); + + /// + /// 设置楼层可见性 + /// + /// 楼层编号 + /// 是否可见 + public void SetFloorVisibility(int floorNumber, bool isVisible); + + /// + /// 设置楼层透明度 + /// + /// 楼层编号 + /// 透明度(0-1) + public void SetFloorOpacity(int floorNumber, double opacity); + + /// + /// 恢复所有楼层显示 + /// + public void RestoreAllFloors(); + + /// + /// 自动配置层级显示 + /// + /// 目标楼层 + public void AutoConfigureLayerVisibility(int targetFloor); +} +``` + +### 辅助接口 +```csharp +/// +/// 可见性辅助类 +/// +public static class VisibilityHelper +{ + /// + /// 隐藏元素集合 + /// + public static void HideItems(ModelItemCollection items); + + /// + /// 显示元素集合 + /// + public static void ShowItems(ModelItemCollection items); + + /// + /// 设置元素透明度 + /// + public static void SetItemOpacity(ModelItemCollection items, double opacity); +} +``` + +## 2.3.1.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 楼层信息 +/// +public class FloorLayerInfo +{ + /// + /// 楼层编号 + /// + public int FloorNumber { get; set; } + + /// + /// 楼层高度范围 + /// + public Range HeightRange { get; set; } + + /// + /// 是否为关键楼层(包含物流元素) + /// + public bool IsKeyFloor { get; set; } + + /// + /// 当前可见性状态 + /// + public VisibilityState Visibility { get; set; } +} + +/// +/// 可见性状态 +/// +public enum VisibilityState +{ + Hidden, // 隐藏 + Dimmed, // 淡化 + Visible // 完全可见 +} +``` + +## 2.3.1.9. 数据结构 + +### FloorLayerInfo 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| FloorNumber | int | 楼层编号 | +| HeightRange | Range | 高度范围 | +| IsKeyFloor | bool | 是否关键楼层 | +| Visibility | VisibilityState | 可见性状态 | +| Opacity | double | 透明度(0-1) | +| ElementCount | int | 元素数量 | + +### VisibilityState 枚举 +| 值 | 说明 | +|---|------| +| Hidden | 完全隐藏 | +| Dimmed | 淡化显示 | +| Visible | 完全可见 | + +### LayerConfiguration 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| HideNonKeyFloors | bool | 是否隐藏非关键层 | +| DimAdjacentFloors | bool | 是否淡化相邻层 | +| DimOpacity | double | 淡化透明度 | +| TargetFloor | int | 目标楼层 | diff --git a/doc/introduction/2.3.2_物流元素筛选功能设计说明.md b/doc/introduction/2.3.2_物流元素筛选功能设计说明.md new file mode 100644 index 0000000..e48f330 --- /dev/null +++ b/doc/introduction/2.3.2_物流元素筛选功能设计说明.md @@ -0,0 +1,299 @@ +# 2.3.2 物流元素筛选功能设计说明 + +## 2.3.2.1. 模块描述 + +物流元素筛选模块是层级创建功能的重要模块,负责支持通过预设的物流分类属性筛选出物流路径相关元素。该模块使用户能够快速定位和查看具有特定物流属性的模型元素,便于进行路径规划前的元素检查和管理。 + +该模块与CategoryAttributeManager、NavisworksSelectionHelper和搜索系统紧密集成,实现基于属性的高效元素筛选。 + +## 2.3.2.2. 功能 + +### 核心功能 +1. **按类型筛选**:按物流元素类型筛选(门、电梯、楼梯、通道等) +2. **按属性筛选**:按可通行性、优先级等属性筛选 +3. **组合筛选**:支持多条件组合筛选 +4. **筛选结果高亮**:高亮显示筛选结果 +5. **筛选保存**:保存常用的筛选条件 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.3.2.F1 | 类型筛选 | 按物流元素类型筛选 | +| 2.3.2.F2 | 可通行筛选 | 按是否可通行筛选 | +| 2.3.2.F3 | 优先级筛选 | 按优先级范围筛选 | +| 2.3.2.F4 | 组合筛选 | 多条件组合筛选 | +| 2.3.2.F5 | 结果高亮 | 高亮显示筛选结果 | +| 2.3.2.F6 | 结果选择 | 将筛选结果添加到选择集 | +| 2.3.2.F7 | 筛选保存 | 保存筛选条件 | +| 2.3.2.F8 | 筛选加载 | 加载已保存的筛选条件 | + +## 2.3.2.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 筛选响应时间 | < 1秒 | 执行筛选操作的响应时间 | +| 支持元素数量 | > 10000 | 支持筛选的最大元素数量 | +| 结果高亮时间 | < 500ms | 高亮显示结果的时间 | +| 内存占用 | < 100MB | 筛选过程的额外内存占用 | + +### 性能优化策略 +1. 使用Navisworks搜索API进行高效筛选 +2. 筛选结果缓存 +3. 增量筛选减少重复计算 + +## 2.3.2.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| ElementTypes | List | 否 | 要筛选的类型列表 | +| IsTraversable | bool? | 否 | 可通行性筛选条件 | +| MinPriority | int? | 否 | 最小优先级 | +| MaxPriority | int? | 否 | 最大优先级 | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| FilteredItems | List | 筛选结果的元素列表 | +| FilterCount | int | 筛选结果数量 | +| FilterTime | TimeSpan | 筛选耗时 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 类型多选框选择 +- 可通行性单选/复选 +- 优先级范围滑块 +- 筛选条件保存名称输入 + +#### 界面输出 +- 筛选结果列表 +- 统计信息显示 +- 结果高亮显示 +- 操作提示信息 + +## 2.3.2.5. 算法 + +### 属性筛选算法 +``` +算法:基于属性的元素筛选 +输入:筛选条件 +输出:筛选结果 + +1. 创建搜索对象 +2. 构建搜索条件: + a. 如果指定了类型: + - 添加类型条件 + b. 如果指定了可通行性: + - 添加可通行性条件 + c. 如果指定了优先级范围: + - 添加优先级条件 +3. 执行搜索 +4. 返回匹配的元素集合 +``` + +### 组合筛选算法 +``` +算法:多条件组合筛选 +输入:多个筛选条件 +输出:筛选结果 + +1. 对于每个筛选条件: + 2. 执行单条件筛选 + 3. 获取中间结果 +4. 根据组合逻辑(与/或)合并结果 +5. 返回最终筛选结果 +``` + +## 2.3.2.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 设置筛选条件 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ 是 +│ 多条件组合? │──────────┐ +└────────┬────────┘ │ + │否 │ + ▼ │ +┌─────────────────┐ │ +│ 单条件筛选 │ │ +└────────┬────────┘ │ + │ │ + │ ▼ + │ ┌─────────────────┐ + │ │ 多条件分别筛选 │ + │ └────────┬────────┘ + │ │ + │ ▼ + │ ┌─────────────────┐ + │ │ 合并筛选结果 │ + │ └────────┬────────┘ + │ │ + └────────┬─────────┘ + │ + ▼ +┌─────────────────┐ +│ 显示筛选结果 │ +└────────┬────────┘ + │ + ┌────┴────┐ + ▼ ▼ +┌────────┐ ┌────────┐ +│高亮显示│ │添加到 │ +└───┬────┘ │选择集 │ + │ └───┬────┘ + │ │ + └─────┬─────┘ + │ + ▼ +┌─────────────────┐ +│ 保存筛选条件? │────否────┐ +└────────┬────────┘ │ + │是 │ + ▼ │ +┌─────────────────┐ │ +│ 保存筛选条件 │ │ +└────────┬────────┘ │ + │ │ + └─────────┬─────────┘ + │ + ▼ + 结束 +``` + +## 2.3.2.7. 接口 + +### 公共接口 +```csharp +/// +/// 物流元素筛选器 +/// +public class LogisticsElementFilter +{ + /// + /// 按类型筛选 + /// + /// 类型列表 + /// 筛选结果 + public List FilterByTypes(List types); + + /// + /// 按可通行性筛选 + /// + /// 是否可通行 + /// 筛选结果 + public List FilterByTraversability(bool isTraversable); + + /// + /// 按优先级范围筛选 + /// + /// 最小优先级 + /// 最大优先级 + /// 筛选结果 + public List FilterByPriorityRange(int minPriority, int maxPriority); + + /// + /// 执行组合筛选 + /// + /// 筛选条件 + /// 筛选结果 + public FilterResult ApplyFilter(FilterCriteria criteria); + + /// + /// 高亮显示筛选结果 + /// + /// 要突出显示的元素 + public void HighlightResults(List items); +} +``` + +### 数据结构接口 +```csharp +/// +/// 筛选条件 +/// +public class FilterCriteria +{ + public List ElementTypes { get; set; } + public bool? IsTraversable { get; set; } + public int? MinPriority { get; set; } + public int? MaxPriority { get; set; } + public FilterCombinationMode CombinationMode { get; set; } +} + +/// +/// 筛选组合模式 +/// +public enum FilterCombinationMode +{ + And, // 与 - 满足所有条件 + Or // 或 - 满足任一条件 +} +``` + +## 2.3.2.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 筛选结果 +/// +public class FilterResult +{ + /// + /// 筛选匹配的元素列表 + /// + public List Items { get; set; } + + /// + /// 匹配元素数量 + /// + public int Count => Items?.Count ?? 0; + + /// + /// 筛选耗时 + /// + public TimeSpan ElapsedTime { get; set; } + + /// + /// 应用的筛选条件 + /// + public FilterCriteria AppliedCriteria { get; set; } +} +``` + +## 2.3.2.9. 数据结构 + +### FilterCriteria 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| ElementTypes | List | 要筛选的元素类型 | +| IsTraversable | bool? | 可通行性条件(null表示不限制) | +| MinPriority | int? | 最小优先级 | +| MaxPriority | int? | 最大优先级 | +| CombinationMode | FilterCombinationMode | 条件组合模式 | + +### FilterResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Items | List | 筛选结果的元素 | +| Count | int | 结果数量 | +| ElapsedTime | TimeSpan | 筛选耗时 | +| AppliedCriteria | FilterCriteria | 应用的筛选条件 | + +### SavedFilter 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Id | string | 保存的筛选ID | +| Name | string | 筛选名称 | +| Criteria | FilterCriteria | 筛选条件 | +| CreateTime | DateTime | 创建时间 | diff --git a/doc/introduction/2.3.3_路径时间标签功能设计说明.md b/doc/introduction/2.3.3_路径时间标签功能设计说明.md new file mode 100644 index 0000000..4bdd3bf --- /dev/null +++ b/doc/introduction/2.3.3_路径时间标签功能设计说明.md @@ -0,0 +1,308 @@ +# 2.3.3 路径时间标签功能设计说明 + +## 2.3.3.1. 模块描述 + +路径时间标签模块是层级创建功能的重要组成部分,负责支持路径时间标签设置,以预估运输时间。该模块通过分析路径的长度、元素类型(如门、电梯、楼梯的速度限制)等因素,计算物流运输的预估时间,为路径规划提供时间维度的参考。 + +该模块与TimeTagService、TimeTagCalculator和PathRoute紧密集成,实现基于路径特征的时间估算功能。 + +## 2.3.3.2. 功能 + +### 核心功能 +1. **时间估算**:基于路径特征估算运输时间 +2. **分段计时**:对路径的不同段进行分段计时 +3. **时间标签显示**:在路径上显示时间标签 +4. **速度限制应用**:应用通道元素的速度限制 +5. **时间导出**:导出时间估算结果 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.3.3.F1 | 路径分析 | 分析路径的长度、坡度等特征 | +| 2.3.3.F2 | 速度计算 | 根据元素类型计算各段速度 | +| 2.3.3.F3 | 时间计算 | 计算总运输时间和分段时间 | +| 2.3.3.F4 | 时间标签 | 在路径点显示时间标签 | +| 2.3.3.F5 | 分段显示 | 显示各段的预计时间 | +| 2.3.3.F6 | 时间导出 | 导出时间数据到文件 | +| 2.3.3.F7 | TimeLiner集成 | 与TimeLiner任务时间同步 | + +## 2.3.3.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 时间计算响应 | < 200ms | 计算路径时间的响应时间 | +| 批量计算时间 | < 1秒 | 批量计算多条路径的时间 | +| 标签渲染时间 | < 100ms | 渲染时间标签的时间 | +| 内存占用 | < 50MB | 时间计算的额外内存占用 | + +### 性能优化策略 +1. 缓存路径特征计算结果 +2. 批量时间计算优化 +3. 时间标签按需渲染 + +## 2.3.3.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| Route | PathRoute | 是 | 要计算时间的路径 | +| ObjectSpeed | double | 否 | 物体移动速度(米/秒),默认0.8 | +| ApplySpeedLimits | bool | 否 | 是否应用速度限制,默认true | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| TotalTime | double | 总运输时间(秒) | +| SegmentTimes | List | 分段时间列表 | +| TimeTags | List | 时间标签列表 | +| AverageSpeed | double | 平均速度(米/秒) | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 路径选择 +- 速度参数设置 +- 时间标签显示选项 + +#### 界面输出 +- 总时间显示 +- 分段时间表 +- 时间标签可视化 +- 导出结果提示 + +## 2.3.3.5. 算法 + +### 时间估算算法 +``` +算法:基于路径特征的时间估算 +输入:路径,物体速度 +输出:时间估算结果 + +1. 初始化总时间为0 +2. 对于路径的每个段: + 3. 获取段长度 + 4. 获取段的元素类型和速度限制 + 5. 计算段速度: + - 取物体速度和速度限制的较小值 + 6. 计算段时间:长度 / 速度 + 7. 累加到总时间 +8. 返回总时间和分段详情 +``` + +### 分段计时算法 +``` +算法:路径分段计时 +输入:路径点列表 +输出:分段时间列表 + +1. 对于每对相邻路径点: + 2. 计算两点间距离 + 3. 识别经过的物流元素 + 4. 获取元素的速度限制 + 5. 计算通过时间 + 6. 记录分段信息 +7. 返回分段时间列表 +``` + +## 2.3.3.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 选择路径 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 分析路径特征 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 获取速度限制 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 计算分段时间 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 计算总时间 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 生成时间标签 │ +└────────┬────────┘ + │ + ┌────┴────┐ + ▼ ▼ +┌────────┐ ┌────────┐ +│显示标签│ │导出时间│ +└───┬────┘ └───┬────┘ + │ │ + └─────┬─────┘ + │ + ▼ + 结束 +``` + +## 2.3.3.7. 接口 + +### 公共接口 +```csharp +/// +/// 时间标签服务 +/// +public class TimeTagService +{ + /// + /// 计算路径时间 + /// + /// 路径对象 + /// 物体速度 + /// 时间计算结果 + public TimeCalculationResult CalculatePathTime(PathRoute route, double objectSpeed = 0.8); + + /// + /// 生成时间标签 + /// + /// 时间计算结果 + /// 时间标签列表 + public List GenerateTimeTags(TimeCalculationResult result); + + /// + /// 在视图中显示时间标签 + /// + /// 时间标签 + public void DisplayTimeTags(List timeTags); + + /// + /// 导出时间数据 + /// + /// 时间计算结果 + /// 导出路径 + public void ExportTimeData(TimeCalculationResult result, string filePath); +} +``` + +### 辅助接口 +```csharp +/// +/// 时间计算器 +/// +public class TimeTagCalculator +{ + /// + /// 计算段的通过时间 + /// + public double CalculateSegmentTime(PathSegment segment, double speed); + + /// + /// 获取元素的速度限制 + /// + public double GetSpeedLimit(ModelItem element); +} +``` + +## 2.3.3.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 时间计算结果 +/// +public class TimeCalculationResult +{ + /// + /// 总运输时间(秒) + /// + public double TotalTimeSeconds { get; set; } + + /// + /// 总运输时间(格式化为 mm:ss) + /// + public string TotalTimeFormatted => FormatTime(TotalTimeSeconds); + + /// + /// 分段时间详情 + /// + public List SegmentTimes { get; set; } + + /// + /// 平均速度(米/秒) + /// + public double AverageSpeed { get; set; } +} + +/// +/// 分段时间信息 +/// +public class SegmentTimeInfo +{ + /// + /// 段索引 + /// + public int SegmentIndex { get; set; } + + /// + /// 段长度(米) + /// + public double Length { get; set; } + + /// + /// 通过时间(秒) + /// + public double TimeSeconds { get; set; } + + /// + /// 段速度(米/秒) + /// + public double Speed { get; set; } +} +``` + +## 2.3.3.9. 数据结构 + +### TimeCalculationResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| TotalTimeSeconds | double | 总运输时间(秒) | +| SegmentTimes | List | 分段时间列表 | +| AverageSpeed | double | 平均速度(米/秒) | +| RouteName | string | 路径名称 | +| CalculationTime | DateTime | 计算时间 | + +### SegmentTimeInfo 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| SegmentIndex | int | 段索引 | +| StartPoint | PathPoint | 起点 | +| EndPoint | PathPoint | 终点 | +| Length | double | 段长度(米) | +| TimeSeconds | double | 通过时间(秒) | +| Speed | double | 段速度(米/秒) | +| ElementType | LogisticsElementType | 主要元素类型 | + +### TimeTag 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Position | Point3D | 标签位置 | +| TimeValue | double | 时间值(秒) | +| TimeText | string | 时间显示文本 | +| LabelType | TimeTagType | 标签类型 | + +### TimeTagType 枚举 +| 值 | 说明 | +|---|------| +| Start | 起点时间 | +| Segment | 分段点 | +| Cumulative | 累计时间 | +| End | 终点时间 | diff --git a/doc/introduction/2.4.1_交互式导航控件功能设计说明.md b/doc/introduction/2.4.1_交互式导航控件功能设计说明.md new file mode 100644 index 0000000..8369ab7 --- /dev/null +++ b/doc/introduction/2.4.1_交互式导航控件功能设计说明.md @@ -0,0 +1,280 @@ +# 2.4.1 交互式导航控件功能设计说明 + +## 2.4.1.1. 模块描述 + +交互式导航控件模块是交互式导航功能的核心模块,负责创建交互式导航控件,允许用户选择不同的起点和终点,动态生成路径。该模块提供直观友好的用户界面,使用户能够轻松地进行路径规划操作,并实时预览生成的路径结果。 + +该模块与NavigationMapGenerator、PathPlanningManager和WPF视图层紧密集成,提供完整的路径规划交互体验。 + +## 2.4.1.2. 功能 + +### 核心功能 +1. **起点选择**:交互式选择路径起点 +2. **终点选择**:交互式选择路径终点 +3. **路径生成**:根据选择的起终点动态生成路径 +4. **实时预览**:实时显示生成的路径 +5. **路径调整**:支持调整路径参数重新生成 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.4.1.F1 | 起点设置 | 在三维视图中设置起点 | +| 2.4.1.F2 | 终点设置 | 在三维视图中设置终点 | +| 2.4.1.F3 | 路径计算 | 自动计算最优路径 | +| 2.4.1.F4 | 路径显示 | 在三维视图中显示路径 | +| 2.4.1.F5 | 参数调整 | 调整路径规划参数 | +| 2.4.1.F6 | 路径保存 | 保存生成的路径 | +| 2.4.1.F7 | 多点导航 | 支持多个途经点 | +| 2.4.1.F8 | 路径比较 | 比较不同路径方案 | + +## 2.4.1.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 路径生成响应 | < 2秒 | 从选择到生成路径的响应时间 | +| 界面响应时间 | < 100ms | 控件操作的响应时间 | +| 路径渲染时间 | < 500ms | 路径可视化渲染时间 | +| 支持并发操作 | 5个 | 同时处理的路径规划请求数 | + +### 性能优化策略 +1. 异步路径计算避免阻塞UI +2. 路径结果缓存 +3. 增量渲染路径 + +## 2.4.1.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| StartPoint | Point3D | 是 | 起点坐标 | +| EndPoint | Point3D | 是 | 终点坐标 | +| ViaPoints | List | 否 | 途经点列表 | +| ObjectSize | double | 否 | 物体尺寸(米) | +| Strategy | PathStrategy | 否 | 路径策略,默认Shortest | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| GeneratedPath | PathRoute | 生成的路径对象 | +| PathLength | double | 路径长度(米) | +| EstimatedTime | double | 预估时间(秒) | +| PathPoints | List | 路径点列表 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 起点/终点选择按钮 +- 途经点添加/删除 +- 参数设置控件 +- 路径生成按钮 + +#### 界面输出 +- 起终点标记显示 +- 路径连线显示 +- 路径信息显示面板 +- 操作提示信息 + +## 2.4.1.5. 算法 + +### 动态路径生成算法 +``` +算法:根据起终点动态生成路径 +输入:起点,终点,途经点,参数 +输出:生成的路径 + +1. 验证起终点有效性 +2. 构建路径点序列 + - 起点 + - 途经点(如果有) + - 终点 +3. 调用路径规划算法 +4. 生成平滑路径 +5. 计算路径长度和时间 +6. 返回路径对象 +``` + +### A*路径规划算法 +``` +算法:A*寻路算法 +输入:起点,终点,网格地图 +输出:最优路径 + +1. 初始化开放列表和关闭列表 +2. 将起点加入开放列表 +3. 当开放列表不为空: + 4. 取出F值最小的节点 + 5. 如果是终点, reconstruct path + 6. 移动到关闭列表 + 7. 遍历邻居节点: + 8. 如果在关闭列表,跳过 + 9. 计算G、H、F值 + 10. 如果在开放列表,更新值 + 11. 否则加入开放列表 +12. 返回路径 +``` + +## 2.4.1.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 打开导航控件 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 选择起点 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 选择终点 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ 是 +│ 添加途经点? │──────────┐ +└────────┬────────┘ │ + │否 │ + ▼ │ +┌─────────────────┐ │ +│ 设置规划参数 │ │ +└────────┬────────┘ │ + │ │ + ▼ │ +┌─────────────────┐ │ +│ 点击生成路径 │ │ +└────────┬────────┘ │ + │ │ + ▼ │ +┌─────────────────┐ │ +│ 执行路径计算 │ │ +└────────┬────────┘ │ + │ │ + ▼ │ +┌─────────────────┐ │ +│ 显示路径结果 │◄─────────┘ +└────────┬────────┘ + │ + ┌────┴────┐ + ▼ ▼ +┌────────┐ ┌────────┐ +│调整参数│ │保存路径│ +└───┬────┘ └───┬────┘ + │ │ + └─────┬─────┘ + │ + ▼ + 结束 +``` + +## 2.4.1.7. 接口 + +### 公共接口 +```csharp +/// +/// 导航地图生成器 +/// +public class NavigationMapGenerator +{ + /// + /// 生成导航路径 + /// + /// 起点 + /// 终点 + /// 路径参数 + /// 生成的路径 + public PathRoute GenerateNavigationPath(Point3D startPoint, Point3D endPoint, PathParameters parameters); + + /// + /// 添加途经点 + /// + public void AddViaPoint(Point3D point); + + /// + /// 清除途经点 + /// + public void ClearViaPoints(); + + /// + /// 设置路径策略 + /// + public void SetPathStrategy(PathStrategy strategy); +} + +/// +/// 路径参数 +/// +public class PathParameters +{ + public double ObjectLength { get; set; } + public double ObjectWidth { get; set; } + public double ObjectHeight { get; set; } + public double SafetyMargin { get; set; } + public PathStrategy Strategy { get; set; } +} +``` + +## 2.4.1.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 路径策略枚举 +/// +public enum PathStrategy +{ + /// + /// 最短路径 + /// + Shortest, + + /// + /// 最快路径 + /// + Fastest, + + /// + /// 最安全路径(避开障碍物) + /// + Safest, + + /// + /// 平衡路径 + /// + Balanced +} +``` + +## 2.4.1.9. 数据结构 + +### PathParameters 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| ObjectLength | double | 物体长度(米) | +| ObjectWidth | double | 物体宽度(米) | +| ObjectHeight | double | 物体高度(米) | +| SafetyMargin | double | 安全间隙(米) | +| Strategy | PathStrategy | 路径策略 | +| MaxSlope | double | 最大坡度(度) | + +### PathStrategy 枚举 +| 值 | 说明 | +|---|------| +| Shortest | 优先最短距离 | +| Fastest | 优先最快速度 | +| Safest | 优先最安全 | +| Balanced | 平衡考虑 | + +### NavigationResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Path | PathRoute | 生成的路径 | +| Success | bool | 是否成功 | +| Message | string | 结果消息 | +| CalculationTime | TimeSpan | 计算耗时 | diff --git a/doc/introduction/2.4.2_结果输出功能设计说明.md b/doc/introduction/2.4.2_结果输出功能设计说明.md new file mode 100644 index 0000000..d8cdc20 --- /dev/null +++ b/doc/introduction/2.4.2_结果输出功能设计说明.md @@ -0,0 +1,296 @@ +# 2.4.2 结果输出功能设计说明 + +## 2.4.2.1. 模块描述 + +结果输出模块是交互式导航功能的重要组成部分,负责输出导航地图和路径规划结果,可以是视频或者图片。该模块将路径规划的结果以多种可视化形式输出,便于用户保存、分享和报告使用。 + +该模块与NavigationMapGenerator、PathAnimationManager和媒体导出功能紧密集成,支持高质量的视觉输出。 + +## 2.4.2.2. 功能 + +### 核心功能 +1. **图片输出**:将路径规划结果导出为图片 +2. **视频输出**:生成路径导航视频 +3. **导航地图生成**:生成包含路径的导航地图 +4. **视角控制**:控制输出视角和视图范围 +5. **输出配置**:配置输出分辨率、格式等参数 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.4.2.F1 | 静态图片导出 | 导出当前视图或指定视角的图片 | +| 2.4.2.F2 | 路径视频生成 | 沿路径生成漫游视频 | +| 2.4.2.F3 | 导航地图生成 | 生成2D/3D导航地图 | +| 2.4.2.F4 | 视角设置 | 设置相机视角和路径 | +| 2.4.2.F5 | 分辨率配置 | 配置输出分辨率 | +| 2.4.2.F6 | 格式选择 | 选择输出格式(PNG/JPG/MP4等) | +| 2.4.2.F7 | 批量输出 | 批量输出多条路径结果 | + +## 2.4.2.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 图片导出时间 | < 2秒 | 导出单张图片的时间 | +| 视频生成速度 | > 10FPS | 视频生成的帧率 | +| 支持分辨率 | 4K | 支持的最大输出分辨率 | +| 内存占用 | < 500MB | 输出过程的内存占用 | + +### 性能优化策略 +1. 异步视频生成避免阻塞UI +2. 帧缓存优化 +3. 硬件加速渲染 + +## 2.4.2.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| Route | PathRoute | 是 | 要输出的路径 | +| OutputType | OutputType | 是 | 输出类型(图片/视频) | +| Resolution | Size | 否 | 输出分辨率,默认1920x1080 | +| Format | string | 否 | 文件格式,根据类型自动确定 | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| OutputFilePath | string | 输出文件路径 | +| FileSize | long | 输出文件大小 | +| GenerationTime | TimeSpan | 生成耗时 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 输出类型选择 +- 分辨率设置 +- 文件格式选择 +- 保存路径选择 + +#### 界面输出 +- 生成进度显示 +- 预览窗口 +- 输出结果提示 +- 文件打开链接 + +## 2.4.2.5. 算法 + +### 图片导出算法 +``` +算法:导出路径规划结果为图片 +输入:路径,视角参数,输出配置 +输出:图片文件 + +1. 设置相机位置和方向 +2. 配置渲染参数 +3. 渲染场景到帧缓冲区 +4. 编码为指定格式(PNG/JPG) +5. 保存到文件 +``` + +### 视频生成算法 +``` +算法:生成路径漫游视频 +输入:路径,视频配置 +输出:视频文件 + +1. 计算相机路径(沿路径的相机位置) +2. 初始化视频编码器 +3. 对于视频的每一帧: + 4. 计算当前相机位置 + 5. 渲染场景 + 6. 编码帧到视频 +7. 完成编码并保存文件 +``` + +## 2.4.2.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 选择输出路径 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 选择输出类型 │ +└────────┬────────┘ + │ + ┌────┴────┐ + ▼ ▼ +┌────────┐ ┌────────┐ +│图片 │ │视频 │ +└───┬────┘ └───┬────┘ + │ │ + ▼ ▼ +┌────────┐ ┌────────┐ +│设置视角│ │设置相机│ +└───┬────┘ │路径 │ + │ └───┬────┘ + │ │ + │ ▼ + │ ┌────────┐ + │ │设置时长│ + │ └───┬────┘ + │ │ + └─────┬─────┘ + │ + ▼ +┌─────────────────┐ +│ 设置分辨率/格式 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 选择保存路径 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 开始生成输出 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 显示生成进度 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 完成并打开文件 │ +└────────┬────────┘ + │ + ▼ + 结束 +``` + +## 2.4.2.7. 接口 + +### 公共接口 +```csharp +/// +/// 结果输出管理器 +/// +public class ResultOutputManager +{ + /// + /// 导出路径为图片 + /// + /// 路径对象 + /// 图片配置 + /// 输出结果 + public OutputResult ExportAsImage(PathRoute route, ImageExportConfig config); + + /// + /// 生成路径漫游视频 + /// + /// 路径对象 + /// 视频配置 + /// 输出结果 + public OutputResult GenerateVideo(PathRoute route, VideoExportConfig config); + + /// + /// 生成导航地图 + /// + public NavigationMap GenerateNavigationMap(PathRoute route); +} + +/// +/// 图片导出配置 +/// +public class ImageExportConfig +{ + public int Width { get; set; } + public int Height { get; set; } + public ImageFormat Format { get; set; } + public Viewpoint Viewpoint { get; set; } +} + +/// +/// 视频导出配置 +/// +public class VideoExportConfig +{ + public int Width { get; set; } + public int Height { get; set; } + public int FrameRate { get; set; } + public double Duration { get; set; } + public VideoFormat Format { get; set; } +} +``` + +## 2.4.2.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 输出类型 +/// +public enum OutputType +{ + /// + /// 静态图片 + /// + Image, + + /// + /// 视频 + /// + Video, + + /// + /// 导航地图 + /// + NavigationMap +} + +/// +/// 图片格式 +/// +public enum ImageFormat +{ + PNG, + JPEG, + BMP +} +``` + +## 2.4.2.9. 数据结构 + +### OutputType 枚举 +| 值 | 说明 | +|---|------| +| Image | 静态图片输出 | +| Video | 视频输出 | +| NavigationMap | 导航地图输出 | + +### ImageExportConfig 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Width | int | 图片宽度 | +| Height | int | 图片高度 | +| Format | ImageFormat | 图片格式 | +| Viewpoint | Viewpoint | 相机视角 | +| IncludeAnnotations | bool | 是否包含标注 | + +### VideoExportConfig 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Width | int | 视频宽度 | +| Height | int | 视频高度 | +| FrameRate | int | 帧率(FPS) | +| Duration | double | 时长(秒) | +| Format | VideoFormat | 视频格式 | +| CameraHeight | double | 相机高度(米) | + +### OutputResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Success | bool | 是否成功 | +| FilePath | string | 输出文件路径 | +| FileSize | long | 文件大小(字节) | +| GenerationTime | TimeSpan | 生成耗时 | +| ErrorMessage | string | 错误消息(如果失败) | diff --git a/doc/introduction/2.4.3_输出格式功能设计说明.md b/doc/introduction/2.4.3_输出格式功能设计说明.md new file mode 100644 index 0000000..b7b40ff --- /dev/null +++ b/doc/introduction/2.4.3_输出格式功能设计说明.md @@ -0,0 +1,311 @@ +# 2.4.3 输出格式功能设计说明 + +## 2.4.3.1. 模块描述 + +输出格式模块是交互式导航功能的关键模块,负责支持路径规划结果结构化文件输出(XML/JSON/CSV),确保结果文件能够导入DELMIA。该模块提供了标准化的数据交换格式,使路径规划结果可以在不同的系统和软件之间进行交换和复用。 + +该模块与ExportPathCommand、PathDataManager和各类导出器(XML/JSON/CSV)紧密集成,实现灵活的数据导出功能。 + +## 2.4.3.2. 功能 + +### 核心功能 +1. **XML格式输出**:导出为XML格式的结构化数据 +2. **JSON格式输出**:导出为JSON格式的结构化数据 +3. **CSV格式输出**:导出为CSV表格格式 +4. **DELMIA兼容**:确保输出格式兼容DELMIA导入 +5. **数据转换**:支持不同格式之间的数据转换 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.4.3.F1 | XML导出 | 导出路径数据为XML格式 | +| 2.4.3.F2 | JSON导出 | 导出路径数据为JSON格式 | +| 2.4.3.F3 | CSV导出 | 导出路径数据为CSV格式 | +| 2.4.3.F4 | DELMIA格式 | 生成DELMIA兼容的输出 | +| 2.4.3.F5 | 格式验证 | 验证输出格式正确性 | +| 2.4.3.F6 | 批量导出 | 批量导出多条路径 | +| 2.4.3.F7 | 字段定制 | 定制导出的字段内容 | + +## 2.4.3.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 导出响应时间 | < 1秒 | 导出单条路径的响应时间 | +| 批量导出速度 | > 100条/秒 | 批量导出的处理速度 | +| 文件大小优化 | < 1MB | 单条路径的导出文件大小 | +| 内存占用 | < 100MB | 导出过程的内存占用 | + +### 性能优化策略 +1. 流式写入大文件 +2. 异步导出操作 +3. 数据压缩 + +## 2.4.3.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| Routes | List | 是 | 要导出的路径列表 | +| Format | ExportFormat | 是 | 导出格式 | +| ExportOptions | ExportOptions | 否 | 导出选项 | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| FilePath | string | 导出文件路径 | +| ExportedCount | int | 导出的路径数量 | +| FileSize | long | 文件大小 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 导出格式选择 +- 字段选择勾选 +- 文件路径选择 +- DELMIA兼容选项 + +#### 界面输出 +- 导出进度显示 +- 文件大小信息 +- 导出结果提示 +- 文件预览 + +## 2.4.3.5. 算法 + +### XML导出算法 +``` +算法:导出路径为XML格式 +输入:路径列表,导出选项 +输出:XML文件 + +1. 创建XML文档 +2. 添加根元素 +3. 对于每条路径: + 4. 创建元素 + 5. 添加路径属性(ID、名称、长度等) + 6. 添加子元素 + 7. 对于每个路径点: + 8. 创建元素 + 9. 添加坐标和属性 +10. 保存XML文件 +``` + +### JSON导出算法 +``` +算法:导出路径为JSON格式 +输入:路径列表,导出选项 +输出:JSON文件 + +1. 创建路径数据对象列表 +2. 对于每条路径: + 3. 序列化路径对象为JSON对象 + 4. 添加到列表 +5. 序列化整个列表为JSON字符串 +6. 保存到文件 +``` + +### CSV导出算法 +``` +算法:导出路径为CSV格式 +输入:路径列表,导出选项 +输出:CSV文件 + +1. 写入CSV表头 +2. 对于每条路径的每个点: + 3. 创建数据行 + 4. 写入坐标、类型等信息 + 5. 写入CSV文件 +``` + +## 2.4.3.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 选择要导出的路径 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 选择导出格式 │ +└────────┬────────┘ + │ + ┌────┼────┬────────┐ + ▼ ▼ ▼ ▼ +┌──────┐┌──────┐┌──────┐┌──────┐ +│ XML ││ JSON ││ CSV ││DELMIA│ +└──┬───┘└──┬───┘└──┬───┘└──┬───┘ + │ │ │ │ + └───────┼───────┼───────┘ + │ │ + ▼ ▼ + ┌─────────────────────┐ + │ 配置导出字段和选项 │ + └──────────┬──────────┘ + │ + ▼ + ┌─────────────────────┐ + │ 选择保存文件路径 │ + └──────────┬──────────┘ + │ + ▼ + ┌─────────────────────┐ + │ 执行导出操作 │ + └──────────┬──────────┘ + │ + ▼ + ┌─────────────────────┐ + │ 验证导出结果 │ + └──────────┬──────────┘ + │ + ▼ + ┌─────────────────────┐ + │ 显示导出完成信息 │ + └──────────┬──────────┘ + │ + ▼ + 结束 +``` + +## 2.4.3.7. 接口 + +### 公共接口 +```csharp +/// +/// 导出路径命令 +/// +public class ExportPathCommand +{ + /// + /// 执行导出 + /// + /// 路径列表 + /// 导出格式 + /// 文件路径 + /// 导出结果 + public ExportResult Execute(List routes, ExportFormat format, string filePath); +} + +/// +/// 导出格式枚举 +/// +public enum ExportFormat +{ + XML, + JSON, + CSV, + DELMIA +} + +/// +/// 导出选项 +/// +public class ExportOptions +{ + public bool IncludeCoordinates { get; set; } + public bool IncludeTiming { get; set; } + public bool IncludeProperties { get; set; } + public bool UseMeters { get; set; } +} +``` + +## 2.4.3.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// DELMIA导出配置 +/// 用于生成DELMIA兼容的路径数据 +/// +public class DelmiaExportConfig +{ + /// + /// 坐标系类型 + /// DELMIA使用特定的坐标系约定 + /// + public CoordinateSystemType CoordinateSystem { get; set; } + + /// + /// 是否包含速度信息 + /// + public bool IncludeVelocity { get; set; } + + /// + /// 采样间隔(秒) + /// + public double SampleInterval { get; set; } +} +``` + +## 2.4.3.9. 数据结构 + +### ExportFormat 枚举 +| 值 | 说明 | +|---|------| +| XML | XML格式 | +| JSON | JSON格式 | +| CSV | CSV格式 | +| DELMIA | DELMIA兼容格式 | + +### ExportOptions 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| IncludeCoordinates | bool | 包含坐标信息 | +| IncludeTiming | bool | 包含时间信息 | +| IncludeProperties | bool | 包含属性信息 | +| UseMeters | bool | 使用米制单位 | +| Precision | int | 坐标精度(小数位) | + +### XML格式示例 +```xml + + + + 125.5 + 156.9 + + + 10.0 + 20.0 + 0.0 + + + + + +``` + +### JSON格式示例 +```json +{ + "paths": [ + { + "id": "path001", + "name": "主通道路径", + "length": 125.5, + "estimatedTime": 156.9, + "points": [ + { + "index": 0, + "type": "Start", + "x": 10.0, + "y": 20.0, + "z": 0.0 + } + ] + } + ] +} +``` + +### CSV格式示例 +```csv +PathID,PathName,PointIndex,PointType,X,Y,Z +path001,主通道路径,0,Start,10.0,20.0,0.0 +path001,主通道路径,1,WayPoint,15.0,25.0,0.0 +``` diff --git a/doc/introduction/2.5.1_动画生成和播放功能设计说明.md b/doc/introduction/2.5.1_动画生成和播放功能设计说明.md new file mode 100644 index 0000000..29b8430 --- /dev/null +++ b/doc/introduction/2.5.1_动画生成和播放功能设计说明.md @@ -0,0 +1,374 @@ +# 2.5.1 动画生成和播放功能设计说明 + +## 2.5.1.1. 模块描述 + +动画生成和播放模块是碰撞检测功能的核心模块,负责指定物流组件(待载转运车),选择路径,生成动画仿真物流组件的运动过程。支持设置动画时长,支持动画的播放、停止和步进播放。该模块通过TimeLiner集成和动态变换实现沿路径的动画效果,为碰撞检测提供动态测试环境。 + +该模块与PathAnimationManager、TimeLinerIntegrationManager和PathCurveEngine紧密集成,实现流畅的路径动画仿真。 + +## 2.5.1.2. 功能 + +### 核心功能 +1. **动画生成**:根据路径生成物流组件的运动动画 +2. **动画播放**:播放生成的动画 +3. **动画控制**:支持播放、暂停、停止、步进控制 +4. **时长设置**:支持设置动画总时长 +5. **速度控制**:支持调整播放速度 +6. **双向播放**:支持正向和反向播放 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.5.1.F1 | 动画对象选择 | 选择要动画的物流组件 | +| 2.5.1.F2 | 路径选择 | 选择动画路径 | +| 2.5.1.F3 | 动画生成 | 生成沿路径的动画 | +| 2.5.1.F4 | 播放控制 | 播放、暂停、停止动画 | +| 2.5.1.F5 | 步进控制 | 单步前进/后退 | +| 2.5.1.F6 | 时长设置 | 设置动画总时长 | +| 2.5.1.F7 | 速度调节 | 调节播放速度倍率 | +| 2.5.1.F8 | 进度跳转 | 跳转到指定进度 | +| 2.5.1.F9 | 循环播放 | 设置循环播放模式 | +| 2.5.1.F10 | TimeLiner集成 | 与TimeLiner任务同步 | + +## 2.5.1.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 动画生成时间 | < 2秒 | 生成动画的响应时间 | +| 播放帧率 | > 30FPS | 动画播放的帧率 | +| 内存占用 | < 200MB | 动画过程的内存占用 | +| 支持路径长度 | 无限制 | 支持的最长路径 | + +### 性能优化策略 +1. 预计算动画帧数据 +2. 使用空间索引优化碰撞检测 +3. 帧数据缓存和复用 + +## 2.5.1.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| AnimatedObject | ModelItem | 是 | 动画对象 | +| Route | PathRoute | 是 | 动画路径 | +| Duration | double | 否 | 动画时长(秒),默认10秒 | +| FrameRate | int | 否 | 帧率,默认30FPS | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| AnimationFrames | List | 动画帧数据 | +| TotalFrames | int | 总帧数 | +| CurrentFrame | int | 当前帧索引 | +| AnimationState | AnimationState | 动画状态 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 对象选择操作 +- 路径选择 +- 播放控制按钮 +- 进度条拖动 +- 速度调节滑块 + +#### 界面输出 +- 动画状态显示 +- 进度条更新 +- 当前帧信息显示 +- 播放时间显示 + +## 2.5.1.5. 算法 + +### 动画生成算法 +``` +算法:生成路径动画 +输入:动画对象,路径,时长,帧率 +输出:动画帧数据 + +1. 计算总帧数:duration * frameRate +2. 对于每帧: + 3. 计算进度:frameIndex / totalFrames + 4. 根据进度计算路径上的位置 + 5. 计算朝向(根据路径方向) + 6. 创建动画帧数据 +7. 返回所有帧数据 +``` + +### 路径位置计算算法 +``` +算法:计算路径上的位置 +输入:路径点列表,进度(0-1) +输出:位置和朝向 + +1. 计算目标距离:总长度 * 进度 +2. 遍历路径段: + 3. 如果目标距离在当前段内: + 4. 计算段内插值比例 + 5. 插值计算位置 + 6. 计算朝向向量 + 7. 返回结果 + 8. 减去当前段长度,继续 +``` + +### 动画帧插值算法 +``` +算法:平滑插值动画帧 +输入:当前帧索引,总帧数,路径数据 +输出:插值后的位置和旋转 + +1. 计算精确的进度值 +2. 找到前后关键帧 +3. 计算插值权重 +4. 对位置进行Lerp插值 +5. 对旋转进行Slerp插值 +6. 返回插值结果 +``` + +## 2.5.1.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 选择动画对象 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 选择动画路径 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 设置动画参数 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 生成动画数据 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 开始播放动画 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 更新对象位置 │ +└────────┬────────┘ + │ + ┌────┴────┐ + ▼ ▼ +┌────────┐ ┌────────┐ +│继续播放│ │用户控制│ +└───┬────┘ └───┬────┘ + │ 暂停 │ + │ ┌────────┘ + │ ▼ + │ ┌──────────┐ + │ │ 暂停状态 │ + │ └───┬──────┘ + │ │ 继续 + └─────┤ + │ + ▼ +┌─────────────────┐ +│ 动画结束/停止 │ +└────────┬────────┘ + │ + ▼ + 结束 +``` + +## 2.5.1.7. 接口 + +### 公共接口 +```csharp +/// +/// 路径动画管理器 +/// +public class PathAnimationManager +{ + /// + /// 创建动画 + /// + /// 动画对象 + /// 动画路径 + /// 动画配置 + public void CreateAnimation(ModelItem animatedObject, PathRoute route, AnimationConfig config); + + /// + /// 播放动画 + /// + public void Play(); + + /// + /// 暂停动画 + /// + public void Pause(); + + /// + /// 停止动画 + /// + public void Stop(); + + /// + /// 步进播放 + /// + /// 方向:1=前进,-1=后退 + public void Step(int direction); + + /// + /// 跳转到指定进度 + /// + /// 进度(0-1) + public void Seek(double progress); + + /// + /// 设置播放速度 + /// + /// 速度倍率 + public void SetPlaybackSpeed(double speed); +} + +/// +/// 动画配置 +/// +public class AnimationConfig +{ + public double Duration { get; set; } + public int FrameRate { get; set; } + public double DetectionTolerance { get; set; } + public bool EnableCollisionDetection { get; set; } +} +``` + +### 事件接口 +```csharp +/// +/// 动画状态变更事件 +/// +public event EventHandler StateChanged; + +/// +/// 动画进度更新事件 +/// +public event EventHandler ProgressUpdated; + +/// +/// 动画帧更新事件 +/// +public event EventHandler FrameUpdated; +``` + +## 2.5.1.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 动画状态 +/// +public enum AnimationState +{ + /// + /// 空闲,未生成动画 + /// + Idle, + + /// + /// 已就绪,动画已生成但未播放 + /// + Ready, + + /// + /// 播放中 + /// + Playing, + + /// + /// 暂停 + /// + Paused, + + /// + /// 已停止 + /// + Stopped, + + /// + /// 已完成 + /// + Finished +} + +/// +/// 动画帧数据 +/// +public class AnimationFrame +{ + /// + /// 帧索引 + /// + public int Index { get; set; } + + /// + /// 进度(0-1) + /// + public double Progress { get; set; } + + /// + /// 该帧的位置 + /// + public Point3D Position { get; set; } + + /// + /// 绕Z轴的偏航角(弧度) + /// + public double YawRadians { get; set; } +} +``` + +## 2.5.1.9. 数据结构 + +### AnimationState 枚举 +| 值 | 说明 | +|---|------| +| Idle | 空闲状态 | +| Ready | 已就绪 | +| Playing | 播放中 | +| Paused | 暂停 | +| Stopped | 已停止 | +| Finished | 已完成 | + +### AnimationConfig 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Duration | double | 动画时长(秒) | +| FrameRate | int | 帧率(FPS) | +| DetectionTolerance | double | 检测容差(米) | +| EnableCollisionDetection | bool | 启用碰撞检测 | +| LoopPlayback | bool | 循环播放 | + +### AnimationFrame 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Index | int | 帧索引 | +| Progress | double | 进度(0-1) | +| Position | Point3D | 位置 | +| YawRadians | double | 偏航角(弧度) | +| Collisions | List | 碰撞结果 | +| HasCollision | bool | 是否有碰撞 | + +### PlaybackState 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| State | AnimationState | 当前状态 | +| CurrentFrame | int | 当前帧索引 | +| CurrentProgress | double | 当前进度 | +| PlaybackSpeed | double | 播放速度倍率 | +| RemainingTime | TimeSpan | 剩余时间 | diff --git a/doc/introduction/2.5.2_碰撞检查功能设计说明.md b/doc/introduction/2.5.2_碰撞检查功能设计说明.md new file mode 100644 index 0000000..a72116a --- /dev/null +++ b/doc/introduction/2.5.2_碰撞检查功能设计说明.md @@ -0,0 +1,338 @@ +# 2.5.2 碰撞检查功能设计说明 + +## 2.5.2.1. 模块描述 + +碰撞检查模块是碰撞检测功能的核心模块,负责在指定物流组件(待载转运车)动画运行过程中,如果与其他模型发生碰撞或干涉,要高亮显示该模型,并记录碰撞结果。支持碰撞记录导出。该模块使用ClashDetective集成和空间索引实现高效的动态碰撞检测。 + +该模块与ClashDetectiveIntegration、PathAnimationManager和CollisionSceneHelper紧密集成,实现实时碰撞检测和结果记录。 + +## 2.5.2.2. 功能 + +### 核心功能 +1. **实时碰撞检测**:在动画播放过程中实时检测碰撞 +2. **碰撞高亮**:高亮显示发生碰撞的模型 +3. **碰撞记录**:记录碰撞的时间、位置、对象等信息 +4. **结果导出**:导出碰撞记录到文件 +5. **ClashDetective集成**:与Navisworks ClashDetective联动 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.5.2.F1 | 预计算碰撞 | 预计算可能的碰撞点 | +| 2.5.2.F2 | 实时检测 | 动画过程中的实时碰撞检测 | +| 2.5.2.F3 | 碰撞高亮 | 高亮显示碰撞对象 | +| 2.5.2.F4 | 碰撞记录 | 记录碰撞详情 | +| 2.5.2.F5 | 结果查看 | 查看碰撞结果列表 | +| 2.5.2.F6 | 记录导出 | 导出碰撞记录 | +| 2.5.2.F7 | 排除设置 | 设置不参与碰撞检测的对象 | +| 2.5.2.F8 | 容差设置 | 设置碰撞检测容差 | + +## 2.5.2.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 检测响应时间 | < 50ms | 单次碰撞检测的响应时间 | +| 帧率影响 | < 5FPS | 碰撞检测对动画帧率的影响 | +| 支持对象数量 | > 10000 | 支持检测的场景对象数量 | +| 内存占用 | < 200MB | 碰撞检测的额外内存占用 | + +### 性能优化策略 +1. 使用空间索引加速检测 +2. 碰撞结果缓存 +3. 分层检测减少计算量 + +## 2.5.2.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| AnimatedObject | ModelItem | 是 | 运动对象 | +| ExcludedObjects | List | 否 | 排除的对象列表 | +| Tolerance | double | 否 | 检测容差(米),默认0.05 | +| UseClashDetective | bool | 否 | 使用ClashDetective,默认true | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Collisions | List | 碰撞结果列表 | +| CollisionCount | int | 碰撞总数 | +| UniqueCollisions | int | 去重后的碰撞数 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 检测容差设置 +- 排除对象选择 +- 手动触发检测 + +#### 界面输出 +- 碰撞列表显示 +- 碰撞位置高亮 +- 碰撞统计信息 +- 结果导出提示 + +## 2.5.2.5. 算法 + +### 碰撞检测算法 +``` +算法:基于空间索引的碰撞检测 +输入:运动对象,场景对象,容差 +输出:碰撞结果 + +1. 获取运动对象的包围盒 +2. 膨胀包围盒(增加容差) +3. 使用空间索引查询可能碰撞的对象 +4. 对于每个候选对象: + 5. 进行精确的碰撞检测 + 6. 如果碰撞: + 7. 记录碰撞信息 +8. 返回所有碰撞结果 +``` + +### ClashDetective集成算法 +``` +算法:使用ClashDetective检测碰撞 +输入:运动对象,检测配置 +输出:碰撞结果 + +1. 创建Clash测试 +2. 设置测试参数 +3. 执行测试 +4. 获取碰撞结果 +5. 解析结果数据 +6. 转换为内部格式 +7. 返回碰撞列表 +``` + +### 碰撞记录算法 +``` +算法:记录碰撞信息 +输入:碰撞结果 +输出:记录数据 + +1. 对于每个碰撞: + 2. 记录时间戳 + 3. 记录动画进度 + 4. 记录碰撞位置 + 5. 记录涉及的对象 + 6. 记录碰撞类型 + 7. 保存到数据库 +8. 返回记录ID +``` + +## 2.5.2.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 配置检测参数 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 设置排除对象 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ 是 +│ 预计算碰撞? │──────────┐ +└────────┬────────┘ │ + │否 │ + ▼ │ +┌─────────────────┐ │ +│ 开始动画播放 │ │ +└────────┬────────┘ │ + │ │ + ▼ │ +┌─────────────────┐ │ +│ 实时碰撞检测 │ │ +└────────┬────────┘ │ + │ │ + ┌────┴────┐ │ + ▼ ▼ │ +┌────────┐ ┌────────┐ │ +│发现碰撞│ │无碰撞 │ │ +└───┬────┘ └───┬────┘ │ + │ │ │ + ▼ │ │ +┌────────┐ │ │ +│高亮显示│ │ │ +└───┬────┘ │ │ + │ │ │ + ▼ │ │ +┌────────┐ │ │ +│记录碰撞│ │ │ +└───┬────┘ │ │ + │ │ │ + └─────┬─────┘ │ + │ │ + ▼ │ +┌─────────────────┐ │ +│ 继续动画? │──────────┤ +└────────┬────────┘ 否 │ + │ │ + │是 │ + │ │ + └───────────────────┤ + │ + ▼ + ┌─────────────────┐ + │ 执行ClashDetective检测 │ + └────────┬────────┘ + │ + ▼ + ┌─────────────────┐ + │ 合并检测结果 │ + └────────┬────────┘ + │ + ▼ + ┌─────────────────┐ + │ 显示最终结果 │ + └────────┬────────┘ + │ + ▼ + 结束 +``` + +## 2.5.2.7. 接口 + +### 公共接口 +```csharp +/// +/// ClashDetective集成 +/// +public class ClashDetectiveIntegration +{ + /// + /// 执行碰撞检测测试 + /// + /// 运动对象 + /// 检测配置 + /// 检测结果 + public ClashTestResult RunClashTest(ModelItem animatedObject, ClashTestConfig config); + + /// + /// 获取当前碰撞结果 + /// + public List GetCurrentCollisions(); + + /// + /// 导出碰撞结果 + /// + /// 导出路径 + public void ExportCollisions(string filePath); + + /// + /// 设置排除对象 + /// + public void SetExcludedObjects(List excludedObjects); +} + +/// +/// 碰撞检测配置 +/// +public class ClashTestConfig +{ + public double Tolerance { get; set; } + public bool UsePreciseDetection { get; set; } + public List ExcludedObjects { get; set; } +} +``` + +### 事件接口 +```csharp +/// +/// 碰撞检测事件参数 +/// +public class CollisionDetectedEventArgs : EventArgs +{ + public ModelItem AnimatedObject { get; set; } + public ModelItem CollisionObject { get; set; } + public Point3D Position { get; set; } + public double AnimationProgress { get; set; } +} + +/// +/// 碰撞检测事件 +/// +public event EventHandler CollisionDetected; +``` + +## 2.5.2.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 碰撞结果 +/// +public class CollisionResult +{ + /// + /// 运动对象 + /// + public ModelItem Item1 { get; set; } + + /// + /// 被碰撞对象 + /// + public ModelItem Item2 { get; set; } + + /// + /// 碰撞位置 + /// + public Point3D CollisionPoint { get; set; } + + /// + /// 碰撞时的动画进度(0-1) + /// + public double AnimationProgress { get; set; } + + /// + /// 碰撞时间 + /// + public DateTime Timestamp { get; set; } +} +``` + +## 2.5.2.9. 数据结构 + +### CollisionResult 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Item1 | ModelItem | 运动对象 | +| Item2 | ModelItem | 被碰撞对象 | +| CollisionPoint | Point3D | 碰撞位置 | +| AnimationProgress | double | 动画进度(0-1) | +| Timestamp | DateTime | 碰撞时间 | +| CollisionType | CollisionType | 碰撞类型 | +| PenetrationDepth | double | 穿透深度 | + +### CollisionType 枚举 +| 值 | 说明 | +|---|------| +| Hard | 硬碰撞(实体接触) | +| Soft | 软碰撞(容差范围内) | +| Clearance | 间隙不足 | + +### ClashTestConfig 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Tolerance | double | 检测容差(米) | +| UsePreciseDetection | bool | 使用精确检测 | +| ExcludedObjects | List | 排除对象 | +| TestName | string | 测试名称 | + +### CollisionStatistics 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| TotalCollisions | int | 总碰撞数 | +| UniqueCollisions | int | 去重后碰撞数 | +| HardCollisions | int | 硬碰撞数 | +| SoftCollisions | int | 软碰撞数 | +| MostHitObject | ModelItem | 被碰撞最多的对象 | +| FirstCollisionTime | double | 首次碰撞进度 | diff --git a/doc/introduction/2.5.3_路径规划分析功能设计说明.md b/doc/introduction/2.5.3_路径规划分析功能设计说明.md new file mode 100644 index 0000000..e9aaa3d --- /dev/null +++ b/doc/introduction/2.5.3_路径规划分析功能设计说明.md @@ -0,0 +1,389 @@ +# 2.5.3 路径规划分析功能设计说明 + +## 2.5.3.1. 模块描述 + +路径规划分析模块是碰撞检测功能的高级分析模块,负责对多个路径运行的碰撞结果进行分析,生成路径分析报告,选择最佳路径,提供调整建议。该模块通过综合分析多条路径的安全性、效率、转弯难度等指标,为用户提供数据驱动的路径优化建议。 + +该模块与PathAnalysisEngine、PathAnalysisReportGenerator和PathAnalysisService紧密集成,实现全面的路径分析功能。 + +## 2.5.3.2. 功能 + +### 核心功能 +1. **多路径分析**:对多条路径进行综合分析 +2. **路径评分**:根据多维度指标对路径评分 +3. **最佳路径选择**:自动选择最佳路径方案 +4. **路径分组**:按终点对路径进行分组比较 +5. **分析报告生成**:生成详细的路径分析报告 +6. **优化建议**:提供路径调整建议 + +### 子功能 +| 功能编号 | 功能名称 | 功能描述 | +|---------|---------|---------| +| 2.5.3.F1 | 安全分析 | 分析路径的安全性和碰撞风险 | +| 2.5.3.F2 | 效率分析 | 分析路径的效率指标 | +| 2.5.3.F3 | 转弯分析 | 分析路径的转弯难度 | +| 2.5.3.F4 | 直达分析 | 分析路径的直达程度 | +| 2.5.3.F5 | 路径分组 | 按终点对路径分组 | +| 2.5.3.F6 | 综合评分 | 计算路径的综合评分 | +| 2.5.3.F7 | 最佳路径 | 推荐最佳路径 | +| 2.5.3.F8 | 报告生成 | 生成分析报告 | +| 2.5.3.F9 | 建议生成 | 生成优化建议 | + +## 2.5.3.3. 性能 + +### 性能指标 +| 指标名称 | 目标值 | 说明 | +|---------|-------|------| +| 分析响应时间 | < 3秒 | 单条路径的分析时间 | +| 批量分析速度 | > 10条/秒 | 多条路径的分析速度 | +| 报告生成时间 | < 5秒 | 生成分析报告的时间 | +| 内存占用 | < 300MB | 分析过程的内存占用 | + +### 性能优化策略 +1. 并行分析多条路径 +2. 分析结果缓存 +3. 增量分析优化 + +## 2.5.3.4. 输入输出项 + +### 1. 字段输入输出 + +#### 输入字段 +| 字段名 | 类型 | 必填 | 说明 | +|-------|------|-----|------| +| Routes | List | 是 | 要分析的路径列表 | +| Strategy | AnalysisStrategy | 否 | 分析策略,默认Balanced | +| CollisionData | List | 否 | 碰撞数据 | + +#### 输出字段 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| AnalysisResults | List | 分析结果列表 | +| BestRoute | PathRoute | 最佳路径 | +| Report | AnalysisReport | 分析报告 | +| Recommendations | List | 优化建议 | + +### 2. 界面交互输入输出 + +#### 界面输入 +- 路径选择 +- 分析策略选择 +- 权重参数调整 +- 报告导出操作 + +#### 界面输出 +- 路径评分显示 +- 对比图表 +- 分析报告预览 +- 建议列表 + +## 2.5.3.5. 算法 + +### 路径评分算法 +``` +算法:多维度路径评分 +输入:路径,碰撞数据,策略 +输出:综合评分 + +1. 计算安全分数(基于碰撞数) + - 无碰撞:100分 + - 有碰撞:根据碰撞严重程度扣分 + +2. 计算效率分数(基于路径长度) + - 与最短路径比较 + - 越短分数越高 + +3. 计算转弯难度分数 + - 分析转弯角度 + - 急转弯越多分数越低 + +4. 计算直达分数 + - 分析路径曲折程度 + - 越直达分数越高 + +5. 根据策略计算加权总分 +6. 返回各维度分数和综合分 +``` + +### 路径分组算法 +``` +算法:按终点分组路径 +输入:路径列表 +输出:分组结果 + +1. 初始化分组列表 +2. 对于每条路径: + 3. 获取路径终点 + 4. 查找是否已有匹配的组 + 5. 如果找到,加入该组 + 6. 否则创建新组 +7. 更新各组统计信息 +8. 返回分组列表 +``` + +### 优化建议算法 +``` +算法:生成路径优化建议 +输入:路径分析结果 +输出:建议列表 + +1. 分析路径的薄弱环节 +2. 对于每个问题: + 3. 识别问题类型 + 4. 查找相关最佳实践 + 5. 生成具体建议 +6. 按优先级排序建议 +7. 返回建议列表 +``` + +## 2.5.3.6. 流程逻辑 + +``` +开始 + │ + ▼ +┌─────────────────┐ +│ 选择要分析的路径│ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 选择分析策略 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 加载碰撞数据 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 执行路径分析 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 按终点分组路径 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 计算各维度分数 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 计算综合评分 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 选择最佳路径 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 生成优化建议 │ +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ 生成分析报告 │ +└────────┬────────┘ + │ + ┌────┴────┐ + ▼ ▼ +┌────────┐ ┌────────┐ +│查看报告│ │导出报告│ +└───┬────┘ └───┬────┘ + │ │ + └─────┬─────┘ + │ + ▼ + 结束 +``` + +## 2.5.3.7. 接口 + +### 公共接口 +```csharp +/// +/// 路径分析引擎 +/// +public class PathAnalysisEngine +{ + /// + /// 分析单条路径 + /// + /// 路径对象 + /// 分析上下文 + /// 详细分析结果 + public PathDetailedAnalysis AnalyzePath(PathRoute route, AnalysisContext context); + + /// + /// 对多条路径进行分组分析 + /// + /// 路径列表 + /// 分组结果 + public List GroupPathsByEndpoint(List routes); + + /// + /// 分析并分组多条路径 + /// + public List AnalyzeAndGroupPaths(List routes, string strategy); + + /// + /// 选择最佳路径 + /// + /// 分析结果列表 + /// 最佳路径 + public PathRoute SelectBestPath(List analyses); +} + +/// +/// 路径分析报告生成器 +/// +public class PathAnalysisReportGenerator +{ + /// + /// 生成分析报告 + /// + public AnalysisReport GenerateReport(List groups, string strategy); + + /// + /// 导出报告 + /// + public void ExportReport(AnalysisReport report, string filePath, ReportFormat format); +} +``` + +## 2.5.3.8. 注释设计 + +### 代码注释规范 +```csharp +/// +/// 分析策略 +/// +public enum AnalysisStrategy +{ + /// + /// 安全优先 + /// + SafetyFirst, + + /// + /// 效率优先 + /// + EfficiencyFirst, + + /// + /// 平衡策略 + /// + Balanced, + + /// + /// 自定义权重 + /// + Custom +} + +/// +/// 路径详细分析结果 +/// +public class PathDetailedAnalysis +{ + /// + /// 路径ID + /// + public string RouteId { get; set; } + + /// + /// 路径名称 + /// + public string RouteName { get; set; } + + /// + /// 安全分数(0-100) + /// + public double SafetyScore { get; set; } + + /// + /// 效率分数(0-100) + /// + public double EfficiencyScore { get; set; } + + /// + /// 转弯难度分数(0-100) + /// + public double TurnDifficultyScore { get; set; } + + /// + /// 直达分数(0-100) + /// + public double TortuosityScore { get; set; } + + /// + /// 综合加权评分 + /// + public double WeightedScore { get; set; } +} +``` + +## 2.5.3.9. 数据结构 + +### PathDetailedAnalysis 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| RouteId | string | 路径ID | +| RouteName | string | 路径名称 | +| TotalLength | double | 总长度(米) | +| EstimatedTime | double | 预估时间(秒) | +| SafetyScore | double | 安全分数(0-100) | +| EfficiencyScore | double | 效率分数(0-100) | +| TurnDifficultyScore | double | 转弯难度分数(0-100) | +| TortuosityScore | double | 直达分数(0-100) | +| WeightedScore | double | 综合加权评分 | +| CollisionCount | int | 碰撞次数 | +| HotspotCount | int | 热点数量 | + +### EndpointGroup 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| GroupId | string | 组ID | +| GroupName | string | 组名称 | +| EndPoint | Point3D | 终点坐标 | +| EndPointDescription | string | 终点描述 | +| PathAnalyses | List | 路径分析列表 | +| BestPath | PathDetailedAnalysis | 最佳路径 | +| AverageScore | double | 平均评分 | + +### AnalysisReport 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| ReportId | string | 报告ID | +| GeneratedTime | DateTime | 生成时间 | +| Strategy | AnalysisStrategy | 分析策略 | +| Groups | List | 分组结果 | +| OverallBestPath | PathRoute | 整体最佳路径 | +| Recommendations | List | 优化建议 | +| Summary | string | 分析摘要 | + +### Recommendation 结构 +| 字段名 | 类型 | 说明 | +|-------|------|------| +| Id | string | 建议ID | +| Type | RecommendationType | 建议类型 | +| Priority | int | 优先级(1-5) | +| Title | string | 建议标题 | +| Description | string | 建议描述 | +| AffectedPath | string | 相关路径 | +| ExpectedImprovement | string | 预期改进 | + +### RecommendationType 枚举 +| 值 | 说明 | +|---|------| +| Safety | 安全改进 | +| Efficiency | 效率提升 | +| PathSmoothing | 路径平滑 | +| CollisionAvoidance | 碰撞避免 | +| AlternativeRoute | 替代路径 | diff --git a/doc/introduction/template.md b/doc/introduction/template.md new file mode 100644 index 0000000..0c64771 --- /dev/null +++ b/doc/introduction/template.md @@ -0,0 +1,14 @@ +2.1.XX模块设计说明 + +2.1.1. XX设计说明。 +2.1.1.1. 模块描述。 +2.1.1.2. 功能 +2.1.1.3. 性能 +2.1.1.4. 输入输出项 + 1.字段输入输出 + 2.界面交互输入输出 +2.1.1.5. 算法 +2.1.1.6. 流程逻辑 +2.1.1.7. 接口 +2.1.1.8. 注释设计 +2.1.1.9. 数据结构 diff --git a/doc/requirement/通道选择及路径点规划功能开发.xlsx b/doc/requirement/通道选择及路径点规划功能开发.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..19488fe39d17a7aa9d412642cbfc3a5f271b8ca8 GIT binary patch literal 11567 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 a{fiVRF9rU#Ja}c`A_GCb%Aruc{rVrC@mf;= literal 0 HcmV?d00001