修改路径点预览效果和退出清理的bug
This commit is contained in:
parent
e72e581f85
commit
508c3e8e79
777
doc/architecture/System_Architecture_Design.md
Normal file
777
doc/architecture/System_Architecture_Design.md
Normal file
@ -0,0 +1,777 @@
|
||||
# NavisworksTransport 系统架构设计方案
|
||||
|
||||
## 项目概述
|
||||
|
||||
NavisworksTransport是一款专为Navisworks 2026平台开发的智能物流路径规划插件,旨在为建筑工程领域提供专业的BIM模型内运输路径优化、碰撞检测和施工模拟解决方案。
|
||||
|
||||
---
|
||||
|
||||
## 3.2.2.1 业务架构
|
||||
|
||||
### 业务目标与价值主张
|
||||
|
||||
NavisworksTransport插件致力于解决建筑施工过程中的物流运输规划难题,通过智能化的路径规划和碰撞检测技术,提升施工效率,降低运输成本,确保施工安全。
|
||||
|
||||
### 核心业务能力
|
||||
|
||||
#### 1. 智能路径规划服务
|
||||
|
||||
- **自动路径生成**: 基于A*算法的智能路径自动规划
|
||||
- **手动路径编辑**: 支持用户自定义路径调整和优化
|
||||
- **多楼层连接**: 跨楼层路径规划和垂直交通整合
|
||||
- **路径可行性分析**: 实时路径验证和可行性评估
|
||||
|
||||
#### 2. 碰撞检测与冲突管理
|
||||
|
||||
- **实时碰撞检测**: 动态监测运输路径中的潜在冲突
|
||||
- **静态障碍物识别**: 自动识别和标记固定障碍物
|
||||
- **动态冲突预警**: 多对象运输时的冲突预警机制
|
||||
- **碰撞报告生成**: 详细的碰撞分析报告和解决方案建议
|
||||
|
||||
#### 3. 动画仿真与可视化
|
||||
|
||||
- **物流运输模拟**: 真实的运输过程动画演示
|
||||
- **时间轴精确控制**: 基于TimeLiner的精确时间控制
|
||||
- **多级速度调节**: 灵活的播放速度控制
|
||||
- **多对象协同**: 支持多个物流对象的协同动画
|
||||
|
||||
#### 4. 模型智能管理
|
||||
|
||||
- **楼层智能识别**: 自动识别和分类模型楼层结构
|
||||
- **分层管理系统**: 基于属性的模型分层组织
|
||||
- **物流类别标注**: 八大物流类别的智能标注系统
|
||||
- **模型分割导出**: 按需模型分割和独立导出功能
|
||||
|
||||
### 业务流程设计
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[选择起点] --> B[设置终点]
|
||||
B --> C[自动路径规划]
|
||||
C --> D[碰撞检测分析]
|
||||
D --> E[路径优化调整]
|
||||
E --> F[动画仿真演示]
|
||||
F --> G[结果导出报告]
|
||||
|
||||
D --> H[发现冲突]
|
||||
H --> I[冲突解决方案]
|
||||
I --> E
|
||||
```
|
||||
|
||||
### 物流分类体系
|
||||
|
||||
基于建筑物流的实际需求,定义八大核心物流类别:
|
||||
|
||||
1. **门 (Doors)**: 进出口通道管理
|
||||
2. **电梯 (Elevators)**: 垂直运输通道
|
||||
3. **楼梯 (Stairs)**: 人工垂直通道
|
||||
4. **通道 (Channels)**: 水平运输走廊
|
||||
5. **障碍物 (Obstacles)**: 固定阻碍物体
|
||||
6. **装卸区 (Loading Zones)**: 材料装卸区域
|
||||
7. **停车区 (Parking)**: 临时停靠区域
|
||||
8. **检查点 (Checkpoints)**: 质检和验收点
|
||||
|
||||
---
|
||||
|
||||
## 3.2.2.2 应用架构
|
||||
|
||||
### 总体架构设计
|
||||
|
||||
NavisworksTransport采用分层式架构设计,确保系统的可维护性、可扩展性和稳定性:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 表现层 (Presentation) │
|
||||
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
|
||||
│ │ WPF MVVM │ │ WinForms │ │ Ribbon UI │ │
|
||||
│ │ 现代化界面 │ │ 传统对话框 │ │ 工具栏集成 │ │
|
||||
│ └─────────────┘ └──────────────┘ └─────────────────┘ │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 业务逻辑层 (Business) │
|
||||
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
|
||||
│ │ 路径规划引擎 │ │ 碰撞检测器 │ │ 动画管理器 │ │
|
||||
│ │ A*算法集成 │ │ 实时冲突检测 │ │ TimeLiner集成 │ │
|
||||
│ └─────────────┘ └──────────────┘ └─────────────────┘ │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 核心服务层 (Core) │
|
||||
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
|
||||
│ │ 状态管理器 │ │ 事件总线 │ │ 日志服务 │ │
|
||||
│ │ UI线程安全 │ │ 组件通信 │ │ 异常处理 │ │
|
||||
│ └─────────────┘ └──────────────┘ └─────────────────┘ │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 数据访问层 (Data) │
|
||||
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
|
||||
│ │ JSON序列化 │ │ XML导出 │ │ Navisworks API │ │
|
||||
│ │ 路径数据 │ │ 配置管理 │ │ COM API集成 │ │
|
||||
│ └─────────────┘ └──────────────┘ └─────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 三重插件架构模式
|
||||
|
||||
NavisworksTransport创新性地采用三重插件协同工作模式:
|
||||
|
||||
#### 1. MainPlugin (主插件)
|
||||
|
||||
- **类型**: AddInPlugin
|
||||
- **职责**: 主界面管理、Ribbon集成、DockPane控制
|
||||
- **特点**: 插件生命周期管理、全局状态维护
|
||||
|
||||
#### 2. PathClickToolPlugin (交互插件)
|
||||
|
||||
- **类型**: ToolPlugin
|
||||
- **职责**: 3D场景交互、鼠标点击事件、路径点设置
|
||||
- **特点**: 实时用户交互响应、空间坐标计算
|
||||
|
||||
#### 3. PathPointRenderPlugin (渲染插件)
|
||||
|
||||
- **类型**: RenderPlugin
|
||||
- **职责**: 3D路径可视化、覆盖层渲染、动画效果
|
||||
- **特点**: 高性能图形渲染、实时视觉反馈
|
||||
|
||||
### 核心管理器组件
|
||||
|
||||
#### PathPlanningManager (路径规划管理器)
|
||||
|
||||
```csharp
|
||||
public class PathPlanningManager
|
||||
{
|
||||
// 路径规划核心功能
|
||||
public PathRoute PlanRoute(Point3D start, Point3D end);
|
||||
public ValidationResult ValidatePath(PathRoute route);
|
||||
public PathRoute OptimizePath(PathRoute route);
|
||||
|
||||
// 事件驱动架构
|
||||
public event EventHandler<PathPlanningEventArgs> PathGenerated;
|
||||
public event EventHandler<CollisionEventArgs> CollisionDetected;
|
||||
}
|
||||
```
|
||||
|
||||
#### LogisticsAnimationManager (动画管理器)
|
||||
|
||||
- **动画控制**: 播放、暂停、停止、速度调节
|
||||
- **多对象协调**: 多个物流对象的同步动画
|
||||
- **时间轴集成**: 与Navisworks TimeLiner深度集成
|
||||
- **碰撞处理**: 动画过程中的实时碰撞检测
|
||||
|
||||
#### UIStateManager (UI状态管理器)
|
||||
|
||||
```csharp
|
||||
public class UIStateManager
|
||||
{
|
||||
// 线程安全的UI更新
|
||||
public async Task ExecuteUIUpdateAsync(Action updateAction);
|
||||
|
||||
// 批量UI更新优化
|
||||
public void QueueUIUpdate(Action updateAction, UIUpdatePriority priority);
|
||||
|
||||
// 状态同步机制
|
||||
public void SynchronizeViewModels();
|
||||
}
|
||||
```
|
||||
|
||||
### MVVM架构实现
|
||||
|
||||
采用标准MVVM模式实现UI与业务逻辑分离:
|
||||
|
||||
- **Model**: PathRoute, PathPoint, LogisticsObject等数据模型
|
||||
- **View**: WPF用户控件、窗口、对话框
|
||||
- **ViewModel**: 数据绑定、命令处理、业务逻辑调用
|
||||
|
||||
---
|
||||
|
||||
## 3.2.2.3 数据架构
|
||||
|
||||
### 核心数据模型设计
|
||||
|
||||
#### 路径数据模型
|
||||
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// 路径路由数据模型
|
||||
/// </summary>
|
||||
public class PathRoute
|
||||
{
|
||||
public Guid Id { get; set; } // 唯一标识
|
||||
public string Name { get; set; } // 路径名称
|
||||
public List<PathPoint> Points { get; set; } // 路径点集合
|
||||
public PathValidationResult Validation { get; set; } // 验证结果
|
||||
public DateTime CreateTime { get; set; } // 创建时间
|
||||
public DateTime ModifyTime { get; set; } // 修改时间
|
||||
public Dictionary<string, object> Metadata { get; set; } // 元数据扩展
|
||||
|
||||
// 路径统计信息
|
||||
public double TotalDistance { get; set; } // 总距离
|
||||
public TimeSpan EstimatedDuration { get; set; } // 预估用时
|
||||
public List<CollisionInfo> Collisions { get; set; } // 碰撞信息
|
||||
}
|
||||
```
|
||||
|
||||
#### 路径点模型
|
||||
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// 路径点数据模型
|
||||
/// </summary>
|
||||
public class PathPoint
|
||||
{
|
||||
public Point3D Position { get; set; } // 3D坐标
|
||||
public int SequenceNumber { get; set; } // 序列号
|
||||
public string Floor { get; set; } // 所属楼层
|
||||
public PathPointType Type { get; set; } // 点类型
|
||||
public List<string> ConnectedNodes { get; set; } // 连接节点
|
||||
|
||||
// 扩展属性
|
||||
public double Height { get; set; } // 高度信息
|
||||
public double Width { get; set; } // 通道宽度
|
||||
public Dictionary<string, string> Attributes { get; set; } // 自定义属性
|
||||
}
|
||||
```
|
||||
|
||||
#### 物流对象模型
|
||||
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// 物流对象数据模型
|
||||
/// </summary>
|
||||
public class LogisticsObject
|
||||
{
|
||||
public string Id { get; set; } // 对象标识
|
||||
public LogisticsCategory Category { get; set; } // 物流类别
|
||||
public BoundingBox3D Bounds { get; set; } // 边界框
|
||||
public Transform3D Transform { get; set; } // 变换矩阵
|
||||
public ModelItem NavisworksItem { get; set; } // Navisworks项引用
|
||||
|
||||
// 物流属性
|
||||
public double Capacity { get; set; } // 容量
|
||||
public double MaxSpeed { get; set; } // 最大速度
|
||||
public List<string> Restrictions { get; set; } // 使用限制
|
||||
public Dictionary<string, string> Properties { get; set; } // 扩展属性
|
||||
}
|
||||
```
|
||||
|
||||
### 数据持久化策略
|
||||
|
||||
#### 1. 主数据存储 (JSON格式)
|
||||
|
||||
```json
|
||||
{
|
||||
"projectInfo": {
|
||||
"name": "物流路径规划项目",
|
||||
"version": "1.0",
|
||||
"createTime": "2024-01-01T00:00:00Z"
|
||||
},
|
||||
"pathRoutes": [
|
||||
{
|
||||
"id": "route-001",
|
||||
"name": "主通道路径",
|
||||
"points": [
|
||||
{
|
||||
"position": {"x": 100.0, "y": 200.0, "z": 0.0},
|
||||
"sequenceNumber": 1,
|
||||
"floor": "F1",
|
||||
"type": "StartPoint"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"totalDistance": 150.5,
|
||||
"estimatedDuration": "00:05:30"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 配置数据存储 (XML格式)
|
||||
|
||||
```xml
|
||||
<Configuration>
|
||||
<UserPreferences>
|
||||
<DefaultSpeed>2.0</DefaultSpeed>
|
||||
<CollisionTolerance>0.5</CollisionTolerance>
|
||||
<AnimationFPS>30</AnimationFPS>
|
||||
</UserPreferences>
|
||||
<SystemSettings>
|
||||
<LogLevel>Info</LogLevel>
|
||||
<AutoSave>true</AutoSave>
|
||||
<BackupInterval>300</BackupInterval>
|
||||
</SystemSettings>
|
||||
</Configuration>
|
||||
```
|
||||
|
||||
#### 3. 缓存数据管理
|
||||
|
||||
- **内存缓存**: 碰撞检测结果、网格地图数据
|
||||
- **会话缓存**: 用户操作历史、临时路径数据
|
||||
- **持久缓存**: 楼层识别结果、模型分析数据
|
||||
|
||||
### 数据交换标准
|
||||
|
||||
#### 导入支持格式
|
||||
|
||||
- **JSON**: 路径数据、项目配置
|
||||
- **CSV**: 批量路径点、统计数据
|
||||
- **XML**: 配置文件、报告模板
|
||||
|
||||
#### 导出支持格式
|
||||
|
||||
- **NWD**: Navisworks文档格式
|
||||
- **JSON**: 标准数据交换格式
|
||||
- **Excel**: 统计报告和分析数据
|
||||
- **PDF**: 项目报告和文档
|
||||
- **CSV**: 数据分析和进一步处理
|
||||
|
||||
### 数据安全与完整性
|
||||
|
||||
#### 数据校验机制
|
||||
|
||||
```csharp
|
||||
public class DataValidator
|
||||
{
|
||||
public ValidationResult ValidatePathRoute(PathRoute route)
|
||||
{
|
||||
// 路径完整性检查
|
||||
// 坐标有效性验证
|
||||
// 序列号连续性验证
|
||||
// 楼层一致性检查
|
||||
}
|
||||
|
||||
public bool VerifyDataIntegrity(string filePath)
|
||||
{
|
||||
// 文件完整性校验
|
||||
// 数据格式验证
|
||||
// 版本兼容性检查
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 数据备份策略
|
||||
|
||||
- **自动备份**: 定时保存项目数据
|
||||
- **增量备份**: 只保存变更的数据
|
||||
- **版本控制**: 保留历史版本便于回滚
|
||||
- **云端同步**: 支持云存储备份
|
||||
|
||||
---
|
||||
|
||||
## 3.2.2.4 技术架构
|
||||
|
||||
### 技术栈选型与理由
|
||||
|
||||
#### 开发平台选择
|
||||
|
||||
- **目标平台**: Navisworks 2026 (x64)
|
||||
- *理由*: 最新API支持,性能优化,功能完整
|
||||
- **运行时**: .NET Framework 4.8
|
||||
- *理由*: Navisworks 2026官方支持的运行时版本
|
||||
- **开发环境**: Visual Studio 2022 Community
|
||||
- *理由*: 完整的.NET开发工具链,优秀的调试支持
|
||||
|
||||
#### 核心技术选型
|
||||
|
||||
- **编程语言**: C# 8.0
|
||||
- *理由*: 与Navisworks API完美集成,丰富的语言特性
|
||||
- **UI框架组合**:
|
||||
- **WPF + MVVM**: 现代化用户界面,数据绑定优势
|
||||
- **WinForms**: 传统对话框,快速开发
|
||||
- **ElementHost**: 混合UI集成方案
|
||||
|
||||
#### 第三方库集成
|
||||
|
||||
```xml
|
||||
<!-- packages.config -->
|
||||
<packages>
|
||||
<package id="RoyT.AStar" version="2.1.0" targetFramework="net48" />
|
||||
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net48" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
|
||||
</packages>
|
||||
```
|
||||
|
||||
### 关键技术实现
|
||||
|
||||
#### 1. 线程安全架构设计
|
||||
|
||||
**问题**: Navisworks API调用必须在主线程,多线程UI更新容易导致崩溃
|
||||
|
||||
**解决方案**: UIStateManager统一线程调度
|
||||
|
||||
```csharp
|
||||
public class UIStateManager
|
||||
{
|
||||
private readonly ConcurrentQueue<UIUpdateAction> _updateQueue;
|
||||
private readonly DispatcherTimer _updateTimer;
|
||||
|
||||
public async Task ExecuteUIUpdateAsync(Action updateAction)
|
||||
{
|
||||
if (Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
// 已在UI线程,直接执行
|
||||
ExecuteWithExceptionHandling(updateAction);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 切换到UI线程执行
|
||||
await Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
ExecuteWithExceptionHandling(updateAction);
|
||||
}, DispatcherPriority.Normal);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteWithExceptionHandling(Action updateAction)
|
||||
{
|
||||
try
|
||||
{
|
||||
updateAction?.Invoke();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
GlobalExceptionHandler.HandleException(ex, "UI更新异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 异步编程模式
|
||||
|
||||
**事件驱动异步处理**:
|
||||
|
||||
```csharp
|
||||
public class PathPlanningManager
|
||||
{
|
||||
public async Task<PathRoute> PlanRouteAsync(Point3D start, Point3D end)
|
||||
{
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
// CPU密集型的A*算法计算
|
||||
var pathfinder = new PathFinder(gridMap);
|
||||
var result = pathfinder.FindPath(start, end);
|
||||
|
||||
// 在UI线程更新进度
|
||||
await uiStateManager.ExecuteUIUpdateAsync(() =>
|
||||
{
|
||||
OnPathGenerated(new PathPlanningEventArgs(result));
|
||||
});
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 内存管理与性能优化
|
||||
|
||||
**对象池模式**:
|
||||
|
||||
```csharp
|
||||
public class PathPointPool
|
||||
{
|
||||
private readonly ConcurrentQueue<PathPoint> _pool;
|
||||
|
||||
public PathPoint Rent()
|
||||
{
|
||||
if (_pool.TryDequeue(out var point))
|
||||
{
|
||||
return point;
|
||||
}
|
||||
return new PathPoint();
|
||||
}
|
||||
|
||||
public void Return(PathPoint point)
|
||||
{
|
||||
point.Reset(); // 重置状态
|
||||
_pool.Enqueue(point);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**空间索引优化**:
|
||||
|
||||
```csharp
|
||||
public class TriangleSpatialHash
|
||||
{
|
||||
private readonly Dictionary<int, List<Triangle>> _spatialGrid;
|
||||
private readonly double _cellSize;
|
||||
|
||||
public List<Triangle> GetNearbyTriangles(Point3D point, double radius)
|
||||
{
|
||||
var result = new List<Triangle>();
|
||||
var minCell = GetCellIndex(point.X - radius, point.Y - radius);
|
||||
var maxCell = GetCellIndex(point.X + radius, point.Y + radius);
|
||||
|
||||
for (int x = minCell.X; x <= maxCell.X; x++)
|
||||
{
|
||||
for (int y = minCell.Y; y <= maxCell.Y; y++)
|
||||
{
|
||||
var key = GetHashKey(x, y);
|
||||
if (_spatialGrid.TryGetValue(key, out var triangles))
|
||||
{
|
||||
result.AddRange(triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. API集成策略
|
||||
|
||||
**双API协同模式**:
|
||||
|
||||
```csharp
|
||||
public class NavisworksIntegration
|
||||
{
|
||||
// Native API - 核心功能
|
||||
private readonly Application _nativeApp;
|
||||
|
||||
// COM API - 属性持久化
|
||||
private readonly ComApi.Application _comApp;
|
||||
|
||||
public void SetPersistentAttribute(ModelItem item, string key, string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用COM API设置持久化属性
|
||||
var comItem = _comApp.ActiveDocument.Models.RootItem.FindItem(item.InstanceGuid);
|
||||
comItem.PropertyCategories.FindPropertyByDisplayName("User", key).Value = value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 降级到Native API内存属性
|
||||
item.PropertyCategories.FindCategoryByDisplayName("User")
|
||||
.Properties.FindPropertyByDisplayName(key).Value = new VariantData(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 部署架构设计
|
||||
|
||||
#### 文件组织结构
|
||||
|
||||
```
|
||||
%ProgramFiles%\Autodesk\Navisworks Manage 2026\Plugins\
|
||||
└── NavisworksTransportPlugin\
|
||||
├── NavisworksTransportPlugin.dll # 主程序集
|
||||
├── RoyT.AStar.dll # A*算法库
|
||||
├── Newtonsoft.Json.dll # JSON处理库
|
||||
├── Resources\ # 资源文件
|
||||
│ ├── Icons\ # 图标资源
|
||||
│ ├── Templates\ # 模板文件
|
||||
│ └── Localization\ # 本地化资源
|
||||
├── Config\ # 配置文件
|
||||
│ ├── DefaultSettings.xml # 默认设置
|
||||
│ └── LoggingConfig.xml # 日志配置
|
||||
└── Documentation\ # 文档
|
||||
├── UserGuide.pdf # 用户指南
|
||||
└── API_Reference.pdf # API参考
|
||||
```
|
||||
|
||||
#### 安装部署流程
|
||||
|
||||
1. **环境检测**: 验证Navisworks 2026安装
|
||||
2. **权限检查**: 确认插件目录写入权限
|
||||
3. **文件部署**: 复制程序集和资源文件
|
||||
4. **注册插件**: 更新Navisworks插件注册表
|
||||
5. **配置初始化**: 创建默认配置文件
|
||||
6. **完整性验证**: 验证安装完整性
|
||||
|
||||
### 安全性架构设计
|
||||
|
||||
#### 1. 数据安全
|
||||
|
||||
```csharp
|
||||
public class DataSecurity
|
||||
{
|
||||
// 数据加密存储
|
||||
public void SaveEncryptedData(string filePath, object data)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(data);
|
||||
var encrypted = EncryptionHelper.Encrypt(json, GetMachineKey());
|
||||
File.WriteAllText(filePath, encrypted);
|
||||
}
|
||||
|
||||
// 完整性校验
|
||||
public bool VerifyDataIntegrity(string filePath)
|
||||
{
|
||||
var hash = ComputeFileHash(filePath);
|
||||
var storedHash = GetStoredHash(filePath + ".hash");
|
||||
return hash == storedHash;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 运行时安全
|
||||
|
||||
- **输入验证**: 所有用户输入严格验证
|
||||
- **边界检查**: 数组访问和集合操作边界检查
|
||||
- **异常处理**: 完整的异常捕获和恢复机制
|
||||
- **资源管理**: 及时释放非托管资源
|
||||
|
||||
### 可扩展性设计
|
||||
|
||||
#### 插件化架构
|
||||
|
||||
```csharp
|
||||
public interface IPathPlanningAlgorithm
|
||||
{
|
||||
string Name { get; }
|
||||
PathRoute PlanPath(Point3D start, Point3D end, GridMap map);
|
||||
}
|
||||
|
||||
public class AlgorithmManager
|
||||
{
|
||||
private readonly Dictionary<string, IPathPlanningAlgorithm> _algorithms;
|
||||
|
||||
public void RegisterAlgorithm(IPathPlanningAlgorithm algorithm)
|
||||
{
|
||||
_algorithms[algorithm.Name] = algorithm;
|
||||
}
|
||||
|
||||
public PathRoute PlanPath(string algorithmName, Point3D start, Point3D end)
|
||||
{
|
||||
if (_algorithms.TryGetValue(algorithmName, out var algorithm))
|
||||
{
|
||||
return algorithm.PlanPath(start, end, _currentMap);
|
||||
}
|
||||
throw new ArgumentException($"未找到算法: {algorithmName}");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 配置驱动架构
|
||||
|
||||
```csharp
|
||||
public class ConfigurationManager
|
||||
{
|
||||
public T GetConfiguration<T>(string sectionName) where T : class, new()
|
||||
{
|
||||
var section = _config.GetSection(sectionName);
|
||||
return section.Get<T>() ?? new T();
|
||||
}
|
||||
|
||||
public void UpdateConfiguration<T>(string sectionName, T config)
|
||||
{
|
||||
_config.SetSection(sectionName, config);
|
||||
SaveConfiguration();
|
||||
NotifyConfigurationChanged(sectionName);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 监控与运维架构
|
||||
|
||||
#### 1. 日志系统设计
|
||||
|
||||
```csharp
|
||||
public class LogManager
|
||||
{
|
||||
private static readonly ILogger _logger = LoggerFactory.CreateLogger();
|
||||
|
||||
public static void Info(string message, [CallerMemberName] string caller = "")
|
||||
{
|
||||
_logger.LogInformation($"[{caller}] {message}");
|
||||
}
|
||||
|
||||
public static void Error(string message, Exception ex = null, [CallerMemberName] string caller = "")
|
||||
{
|
||||
_logger.LogError(ex, $"[{caller}] {message}");
|
||||
}
|
||||
|
||||
// 性能监控
|
||||
public static IDisposable BeginScope(string operationName)
|
||||
{
|
||||
return _logger.BeginScope($"Operation: {operationName}");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 性能监控
|
||||
|
||||
```csharp
|
||||
public class PerformanceMonitor
|
||||
{
|
||||
private readonly Dictionary<string, PerformanceCounter> _counters;
|
||||
|
||||
public void RecordOperation(string operation, TimeSpan duration)
|
||||
{
|
||||
var counter = GetOrCreateCounter(operation);
|
||||
counter.Record(duration.TotalMilliseconds);
|
||||
}
|
||||
|
||||
public PerformanceReport GenerateReport()
|
||||
{
|
||||
return new PerformanceReport
|
||||
{
|
||||
Timestamp = DateTime.Now,
|
||||
MemoryUsage = GC.GetTotalMemory(false),
|
||||
OperationStats = _counters.ToDictionary(
|
||||
kvp => kvp.Key,
|
||||
kvp => kvp.Value.GetStatistics()
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 错误报告系统
|
||||
|
||||
```csharp
|
||||
public class ErrorReporting
|
||||
{
|
||||
public void ReportError(Exception ex, Dictionary<string, object> context)
|
||||
{
|
||||
var report = new ErrorReport
|
||||
{
|
||||
Exception = ex,
|
||||
Context = context,
|
||||
Environment = GetEnvironmentInfo(),
|
||||
Timestamp = DateTime.Now
|
||||
};
|
||||
|
||||
// 本地保存
|
||||
SaveErrorReport(report);
|
||||
|
||||
// 可选:发送到服务器
|
||||
if (UserConsents && IsOnline)
|
||||
{
|
||||
SendErrorReport(report);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 架构优势与创新点
|
||||
|
||||
### 技术创新
|
||||
|
||||
1. **三重插件协同**: 创新的插件架构模式,各司其职,协同工作
|
||||
2. **线程安全UI管理**: 统一的UI状态管理器,解决多线程UI更新难题
|
||||
3. **双API集成**: Native API与COM API协同,功能完整性与兼容性并重
|
||||
4. **空间索引优化**: 高效的空间数据结构,提升大模型处理性能
|
||||
|
||||
### 架构优势
|
||||
|
||||
1. **高可维护性**: 分层架构,职责清晰,便于团队协作开发
|
||||
2. **强扩展性**: 插件化设计,支持功能模块热插拔
|
||||
3. **高性能**: 内存管理优化,空间索引,异步处理
|
||||
4. **高稳定性**: 完整的异常处理,线程安全设计,资源管理
|
||||
|
||||
### 商业价值
|
||||
|
||||
1. **降本增效**: 智能化路径规划,减少人工设计时间
|
||||
2. **风险控制**: 碰撞预警机制,避免施工冲突
|
||||
3. **决策支持**: 可视化动画演示,辅助方案决策
|
||||
4. **标准化**: 统一的物流分类体系,规范管理流程
|
||||
|
||||
---
|
||||
|
||||
## 结论
|
||||
|
||||
NavisworksTransport系统架构方案充分考虑了建筑工程物流管理的实际需求,结合Navisworks平台的技术特点,设计了完整的四层架构体系。该方案不仅满足当前业务需求,更具备良好的扩展性和维护性,为未来的功能增强和技术演进提供了坚实的基础。
|
||||
|
||||
通过创新的三重插件协同模式、线程安全的UI管理机制、以及高效的数据处理架构,NavisworksTransport将为建筑工程领域的数字化转型提供强有力的技术支撑。
|
||||
162
doc/architecture/architecture_diagram.py
Normal file
162
doc/architecture/architecture_diagram.py
Normal file
@ -0,0 +1,162 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.patches as patches
|
||||
from matplotlib.patches import FancyBboxPatch
|
||||
import numpy as np
|
||||
|
||||
# 设置中文字体 - 优先使用Microsoft YaHei
|
||||
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'DejaVu Sans']
|
||||
plt.rcParams['axes.unicode_minus'] = False
|
||||
|
||||
# 创建图形 - 调整尺寸和DPI
|
||||
fig, ax = plt.subplots(1, 1, figsize=(16, 12))
|
||||
|
||||
# 定义颜色方案
|
||||
colors = {
|
||||
'presentation': '#E3F2FD', # 淡蓝色
|
||||
'business': '#E8F5E8', # 淡绿色
|
||||
'core': '#FFF3E0', # 淡橙色
|
||||
'data': '#F3E5F5', # 淡紫色
|
||||
'border': '#2C3E50', # 深灰色边框
|
||||
'text': '#2C3E50' # 深蓝灰色文字
|
||||
}
|
||||
|
||||
# 层级高度和间距 - 增加高度以容纳更多文字
|
||||
layer_height = 2.2
|
||||
layer_spacing = 0.4
|
||||
component_width = 3.8
|
||||
component_height = 1.4
|
||||
component_spacing = 0.5
|
||||
|
||||
# 总宽度
|
||||
total_width = 13
|
||||
start_x = 1
|
||||
|
||||
# 绘制四个主要层级
|
||||
# 调整层级Y位置以适应新的高度
|
||||
layers = [
|
||||
{
|
||||
'name': '表现层 (Presentation)',
|
||||
'color': colors['presentation'],
|
||||
'y': 8.5,
|
||||
'components': [
|
||||
{'name': 'WPF MVVM\n现代化界面', 'desc': ''},
|
||||
{'name': 'WinForms\n传统对话框', 'desc': ''},
|
||||
{'name': 'Ribbon UI\n工具栏集成', 'desc': ''}
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': '业务逻辑层 (Business)',
|
||||
'color': colors['business'],
|
||||
'y': 6.0,
|
||||
'components': [
|
||||
{'name': '路径规划引擎\nA*算法集成', 'desc': ''},
|
||||
{'name': '碰撞检测器\n实时冲突检测', 'desc': ''},
|
||||
{'name': '动画管理器\nTimeLiner集成', 'desc': ''}
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': '核心服务层 (Core)',
|
||||
'color': colors['core'],
|
||||
'y': 3.5,
|
||||
'components': [
|
||||
{'name': '状态管理器\nUI线程安全', 'desc': ''},
|
||||
{'name': '事件总线\n组件通信', 'desc': ''},
|
||||
{'name': '日志服务\n异常处理', 'desc': ''}
|
||||
]
|
||||
},
|
||||
{
|
||||
'name': '数据访问层 (Data)',
|
||||
'color': colors['data'],
|
||||
'y': 1.0,
|
||||
'components': [
|
||||
{'name': 'JSON序列化\n路径数据', 'desc': ''},
|
||||
{'name': 'XML导出\n配置管理', 'desc': ''},
|
||||
{'name': 'Navisworks API\nCOM API集成', 'desc': ''}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
# 绘制每个层级
|
||||
for layer in layers:
|
||||
# 绘制层级背景
|
||||
layer_rect = FancyBboxPatch(
|
||||
(start_x, layer['y']), total_width, layer_height,
|
||||
boxstyle="round,pad=0.1",
|
||||
facecolor=layer['color'],
|
||||
edgecolor=colors['border'],
|
||||
linewidth=2
|
||||
)
|
||||
ax.add_patch(layer_rect)
|
||||
|
||||
# 绘制层级标题 - 调整位置确保文字在框内正确显示
|
||||
ax.text(start_x + total_width/2, layer['y'] + layer_height - 0.4,
|
||||
layer['name'],
|
||||
ha='center', va='center',
|
||||
fontsize=15, fontweight='bold',
|
||||
color=colors['text'])
|
||||
|
||||
# 计算组件起始位置
|
||||
total_components_width = len(layer['components']) * component_width + (len(layer['components']) - 1) * component_spacing
|
||||
components_start_x = start_x + (total_width - total_components_width) / 2
|
||||
|
||||
# 绘制组件
|
||||
for i, component in enumerate(layer['components']):
|
||||
comp_x = components_start_x + i * (component_width + component_spacing)
|
||||
comp_y = layer['y'] + 0.2
|
||||
|
||||
# 绘制组件框
|
||||
comp_rect = FancyBboxPatch(
|
||||
(comp_x, comp_y), component_width, component_height,
|
||||
boxstyle="round,pad=0.05",
|
||||
facecolor='white',
|
||||
edgecolor=colors['border'],
|
||||
linewidth=1.5
|
||||
)
|
||||
ax.add_patch(comp_rect)
|
||||
|
||||
# 绘制组件文字 - 调整字体大小和位置
|
||||
ax.text(comp_x + component_width/2, comp_y + component_height/2,
|
||||
component['name'],
|
||||
ha='center', va='center',
|
||||
fontsize=11, fontweight='normal',
|
||||
color=colors['text'],
|
||||
linespacing=1.2)
|
||||
|
||||
# 绘制层级之间的连接线
|
||||
for i in range(len(layers) - 1):
|
||||
y_start = layers[i]['y']
|
||||
y_end = layers[i+1]['y'] + layer_height
|
||||
|
||||
# 绘制多条连接线表示数据流
|
||||
for j in range(3):
|
||||
x_pos = start_x + total_width * (j + 1) / 4
|
||||
ax.annotate('', xy=(x_pos, y_start), xytext=(x_pos, y_end),
|
||||
arrowprops=dict(arrowstyle='->', color=colors['border'],
|
||||
lw=1.5, alpha=0.7))
|
||||
|
||||
# 添加架构说明 - 调整位置和字体
|
||||
ax.text(start_x + total_width + 0.5, 6.5,
|
||||
'特点:\n• 分层解耦\n• 职责清晰\n• 易于维护\n• 支持扩展',
|
||||
ha='left', va='center',
|
||||
fontsize=12, fontweight='normal',
|
||||
bbox=dict(boxstyle="round,pad=0.5", facecolor='#F8F9FA', edgecolor=colors['border']),
|
||||
color=colors['text'],
|
||||
linespacing=1.3)
|
||||
|
||||
# 设置图形属性 - 调整范围以适应新的布局
|
||||
ax.set_xlim(0, 17)
|
||||
ax.set_ylim(0, 12)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
|
||||
# 添加标题
|
||||
plt.title('NavisworksTransport 分层架构设计',
|
||||
fontsize=18, fontweight='bold', pad=20, color=colors['text'])
|
||||
|
||||
# 保存图形
|
||||
plt.tight_layout()
|
||||
plt.savefig(r'C:\Users\Tellme\apps\NavisworksTransport\doc\architecture\system_architecture.png',
|
||||
dpi=300, bbox_inches='tight', facecolor='white', edgecolor='none')
|
||||
|
||||
print("架构图已生成: system_architecture.png")
|
||||
plt.show()
|
||||
BIN
doc/architecture/system_architecture.png
Normal file
BIN
doc/architecture/system_architecture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 387 KiB |
@ -5,16 +5,17 @@
|
||||
日期:2025-08-29
|
||||
|
||||
本方案依据以下输入编制:
|
||||
|
||||
- 需求文档:doc/requirement/user_requiement.md(以 Navisworks 2017/Windows 7 为基线)
|
||||
- 项目上下文与结构参考:QWEN.md(包含 Navisworks 2026 的说明,仅作补充参考)
|
||||
- 源代码:src 目录(核心模块:Core、PathPlanning、UI/WPF、Utils 等)
|
||||
|
||||
重要说明:如需求文档与 QWEN.md 在版本目标存在差异(2017 vs 2026),本方案默认以需求文档为准(Navisworks 2017)。若需面向 Navisworks 2026 的兼容性与增强功能,请在部署与验证环节中选配“2026 兼容模式”。
|
||||
|
||||
|
||||
一、总体设计
|
||||
|
||||
1.1 背景与目标
|
||||
|
||||
- 背景:在 Autodesk Navisworks 环境中进行物流路径规划、动画仿真与碰撞检查,需高效的交互式工具,支持路径点编辑、自动路径规划(复杂场景)、导航输出与结构化结果文件(XML/JSON/CSV)。
|
||||
- 目标:
|
||||
- 快速完成通道选择与路径点规划(起点/路径点/终点),支持多路径管理与编辑;
|
||||
@ -24,6 +25,7 @@
|
||||
- 支持结构化结果文件输出,并满足 DELMIA 导入(按需求文档约束)。
|
||||
|
||||
1.2 需求综述(与需求文档对应)
|
||||
|
||||
- 通道选择及路径点规划:模型切分、通道选择、路径点规划、多路径管理、编辑保存与导入、路径点自动贴合;
|
||||
- 物流“类别”设置:新增物流属性类别、设置可通行性/速度/宽度/优先级等属性,筛选与清除;
|
||||
- 层级创建与显示:自动隐藏/淡化非关键层,物流元素筛选,路径时间标签;
|
||||
@ -31,6 +33,7 @@
|
||||
- 碰撞检查:动画生成与播放、碰撞检查/记录导出、路径规划分析与最优路径建议。
|
||||
|
||||
1.3 设计原则
|
||||
|
||||
- 实用优先:在 Navisworks 2017 环境中保证稳定运行与较好性能;
|
||||
- 解耦分层:UI(WPF+MVVM)与核心逻辑(Core、PathPlanning)分离,便于后续扩展;
|
||||
- 向后兼容:在自动规划/碰撞集成等关键能力上提供降级路径(如 BoundingBox 模式回退);
|
||||
@ -38,6 +41,7 @@
|
||||
- 数据可移植:路径/结果提供 XML/JSON/CSV 序列化能力(JSON 加载简化,建议 XML 为主)。
|
||||
|
||||
1.4 核心用例流程概览
|
||||
|
||||
- 路径编辑(手动):
|
||||
1) 用户通道选择(手动/属性筛选/自动查找可通行),计算通道边界;
|
||||
2) 进入编辑模式,3D 点击添加“起点/路径点/终点”,路线渲染与校验;
|
||||
@ -52,10 +56,10 @@
|
||||
1) 导航控件交互产生路径;
|
||||
2) 输出视频/图片与结构化结果(XML/JSON/CSV),满足 DELMIA 导入约束。
|
||||
|
||||
|
||||
二、系统架构
|
||||
|
||||
2.1 分层架构与模块
|
||||
|
||||
- UI 层(WPF + MVVM,少量 WinForms 遗留):
|
||||
- Views: UI/WPF/Views/*(含 PathEditingView、AnimationControlView 等)
|
||||
- ViewModels: UI/WPF/ViewModels/*(LogisticsControlViewModel、PathEditingViewModel 等)
|
||||
@ -64,6 +68,7 @@
|
||||
- PathPlanningManager:路径规划主控(事件驱动、状态机、路径可视化)
|
||||
- CategoryAttributeManager:物流属性管理(COM API + .NET API)
|
||||
- VisibilityManager:可见性与层级控制
|
||||
|
||||
- Animation:TimeLinerIntegrationManager、PathAnimationManager(动画控制)
|
||||
- Collision:ClashDetectiveIntegration(碰撞集成,动画期缓存 + 结束时统一测试)
|
||||
- ModelSplitterManager:模型切分(含简化实现)
|
||||
@ -74,10 +79,12 @@
|
||||
- Utils:日志、坐标/单位转换、Navisworks API 辅助
|
||||
|
||||
2.2 系统架构图(截图占位)
|
||||
|
||||
- [截图占位] 系统架构图
|
||||
- 要求:体现 UI(WPF+MVVM)/Core/PathPlanning/Utils 分层,以及 TimeLiner、Clash 的集成位置与事件流(PathPlanningManager 事件:StatusChanged、EditStateChanged、RouteGenerated 等)。
|
||||
|
||||
2.3 模块关系与数据流
|
||||
|
||||
- UI 通过 ViewModel 调用 PathPlanningManager 与其他 Core 服务;
|
||||
- PathPlanningManager 根据通道选择与编辑状态,驱动网格生成与 A* 求解,并渲染路径标记;
|
||||
- Animation/Collision 订阅路径与动画状态,按批次创建 TimeLiner 任务与 Clash 测试;
|
||||
@ -85,6 +92,7 @@
|
||||
- VisibilityManager 提供“仅显示物流元素/隔离显示”等能力。
|
||||
|
||||
2.4 技术路线与选型
|
||||
|
||||
- 语言/框架:C#,.NET Framework 4.8;
|
||||
- UI:WPF + MVVM(WinForms 仅用于部分对话框/遗留界面);
|
||||
- 外部 API:Autodesk Navisworks API(2017 目标),COM API(属性写入)、TimeLiner API、Clash API;
|
||||
@ -93,15 +101,16 @@
|
||||
- 日志/异常:LogManager、GlobalExceptionHandler。
|
||||
|
||||
2.5 关键数据模型(摘自源码)
|
||||
|
||||
- PathPoint、PathRoute:路径点/路径集合,支持类型(Start/End/WayPoint)、长度/时间统计、XML/JSON 序列化;
|
||||
- ChannelBounds:通道边界与 2D 投影;
|
||||
- PathHistoryEntry/Manager:路径历史;
|
||||
- 事件模型:PathPlanningStatusChangedEventArgs、PathEditStateChangedEventArgs、RouteGeneratedEventArgs 等。
|
||||
|
||||
|
||||
三、功能设计方案(逐模块)
|
||||
|
||||
3.1 模型切分
|
||||
|
||||
- 目标:对大型模型按楼层/属性进行切分,提升性能与操作体验;
|
||||
- UI:ModelSplitterDialog(WinForms);
|
||||
- Core:ModelSplitterManager、SimplifiedModelSplitterManager;
|
||||
@ -111,6 +120,7 @@
|
||||
- 与可见性/筛选配合以限定工作区域。
|
||||
|
||||
3.2 通道选择
|
||||
|
||||
- 能力:
|
||||
- 手动选择:基于 Navisworks 选择;
|
||||
- 属性筛选:通过 CategoryAttributeManager.FilterByLogisticsType(FilterTraversableItems);
|
||||
@ -118,6 +128,7 @@
|
||||
- PathPlanningManager.SelectChannels:计算组合边界 CombinedChannelBounds 并事件广播。
|
||||
|
||||
3.3 路径点规划(手动 + 自动)
|
||||
|
||||
- 手动规划:
|
||||
- 工具:PathClickToolPlugin(精确拾取),PathPointRenderPlugin(3D 渲染);
|
||||
- 流程:切换到 Creating/Editing 状态 -> 添加点 -> 渲染 -> 校验;
|
||||
@ -130,33 +141,39 @@
|
||||
- 路径优化(去冗余点、直线可达校验)、2.5D 高度插值与起终点原位修正;
|
||||
|
||||
3.4 路径管理、编辑、保存与导入
|
||||
|
||||
- 编辑:创建/编辑/取消/完成编辑(FinishEditing 自动将末点设为终点并触发渲染与事件);
|
||||
- 文件:PathFileSerializer(XML 主,JSON 简化,不建议作为主格式),支持多路径容器;
|
||||
- 历史:PathHistoryManager(Created/Edited/ManualSave 等),提供查看历史 UI;
|
||||
- 导入:DetectFileFormat -> LoadFromXml/LoadFromJson(JSON 加载简化,优先 XML)。
|
||||
|
||||
3.5 物流“类别”设置
|
||||
|
||||
- 类别:为模型添加“物流属性”类别(类型、可通行、优先级、车辆尺寸、速度限制、宽度限制等);
|
||||
- 批量处理:Add/Update/Remove,使用 COM API 正确索引方式避免覆盖错误;
|
||||
- 识别筛选:FilterTraversableItems/FilterByLogisticsType/FilterPassableAreas,供通道选择与可见性使用。
|
||||
|
||||
3.6 层级创建与显示
|
||||
|
||||
- 隐藏/淡化非关键层:VisibilityManager.HideNonLogisticsItems/ShowAllItems/IsolateSpecificItems;
|
||||
- 物流元素筛选:ShowLogisticsItemsOnly;
|
||||
- 路径时间标签:在 PathPlanningManager.CalculateEstimatedTime(当前简单估算,后续可接入速度限制)。
|
||||
|
||||
3.7 交互式导航
|
||||
|
||||
- 交互控件:UI/WPF 侧的主面板与路径/起终点选择;
|
||||
- 导出:支持视频/图片占位(由用户录屏或快照)、结构化文件(XML/JSON/CSV);
|
||||
- DELMIA 导入:以 XML/CSV 为主,JSON 仅作参考(需要与 DELMIA 侧字段约定)。
|
||||
|
||||
3.8 动画生成与播放
|
||||
|
||||
- TimeLinerIntegrationManager:创建运输任务(将路径关联到对象)、更新进度与状态文本、清理任务;
|
||||
- PathAnimationManager:具体的路径关键帧/移动输出(见 Core/Animation);
|
||||
- 设计要点:
|
||||
- 以 TimelinerTask 为主线(Navisworks 2017 可用 API 能力有限,使用显示名/选择集传递状态)。
|
||||
|
||||
3.9 碰撞检查
|
||||
|
||||
- ClashDetectiveIntegration:
|
||||
- 动画过程“实时缓存”碰撞(包围盒快速判定 + 去重 + 位置快照);
|
||||
- 动画结束“统一创建并运行”测试(避免过程频繁创建);
|
||||
@ -164,29 +181,33 @@
|
||||
- 兼容性:优先 .NET Clash API,必要时绕过繁重的 COM 插件枚举。
|
||||
|
||||
3.10 路径规划分析
|
||||
|
||||
- 汇总多条路径的碰撞结果,统计次数/距离/受影响对象;
|
||||
- 以“最小碰撞/最短距离/最小转弯次数”等指标推荐最优路径;
|
||||
- 输出分析报告(可选 CSV/XML)。
|
||||
|
||||
3.11 结果输出
|
||||
|
||||
- 地图/路径可视化:3D 渲染 + 可截屏;
|
||||
- 结构化结果:XML/JSON/CSV(建议 XML/CSV 作为主导入格式到 DELMIA)。
|
||||
|
||||
|
||||
四、系统部署方案
|
||||
|
||||
4.1 部署环境要求
|
||||
|
||||
- 操作系统:Windows 7(需求文档基准),建议 Windows 10 及以上(更佳兼容性与性能);
|
||||
- Autodesk Navisworks:Manage 2017(需求基线)。如需 2026,请切换引用与验证用例(见下文兼容模式);
|
||||
- .NET Framework:4.8;
|
||||
- 开发工具:Visual Studio(建议 2019/2022)。
|
||||
|
||||
4.2 构建与产物
|
||||
|
||||
- 解决方案:NavisworksTransport.sln;
|
||||
- 项目:NavisworksTransportPlugin.csproj;
|
||||
- 产物:NavisworksTransportPlugin.dll(bin/Debug 或 bin/Release)。
|
||||
|
||||
4.3 安装与部署流程
|
||||
|
||||
- 自动安装(一键安装):
|
||||
1) 识别 Navisworks 安装目录;
|
||||
2) 将插件 DLL 与必要资源复制到 [Navisworks安装路径]\Plugins\NavisworksTransportPlugin\;
|
||||
@ -196,12 +217,14 @@
|
||||
2) 重启 Navisworks,在“附加模块”中查看“物流路径规划”。
|
||||
|
||||
4.4 运行配置
|
||||
|
||||
- 日志输出:%AppData%\Autodesk Navisworks Manage 2017\PluginsData\NavisworksTransportPlugin(按 QWEN 中 2026 路径作适配);
|
||||
- 配置切换:
|
||||
- 自动路径规划模式网格参数(cellSize、vehicleSize、safetyMargin、vehicleHeight);
|
||||
- 2.5D/BoundingBox 模式选择(自动/强制选项)。
|
||||
|
||||
4.5 验证计划
|
||||
|
||||
- 功能验证(最小可行用例):
|
||||
- 通道选择(手动/自动),边界计算;
|
||||
- 路径编辑:起点/若干路径点/终点,渲染正确;
|
||||
@ -222,20 +245,22 @@
|
||||
- 如需 Navisworks 2026,切换引用并复测 TimeLiner/Clash API 行为差异。
|
||||
|
||||
4.6 2026 兼容模式(可选)
|
||||
|
||||
- 若目标为 Navisworks 2026:
|
||||
- 切换引用到 2026 API;
|
||||
- 复核 QWEN.md 所述运行路径与日志输出位置;
|
||||
- 回归 TimeLiner 与 Clash API 可用性和接口差异;
|
||||
- 扩展安装器适配多版本并行安装。
|
||||
|
||||
|
||||
五、非功能与质量保证
|
||||
|
||||
5.1 日志与异常处理
|
||||
|
||||
- GlobalExceptionHandler:应用级异常捕获(线程/任务/未处理),尝试恢复组件,提供用户友好提示;
|
||||
- LogManager:Info/Warning/Error/Debug 统一记录,关键路径设充分日志(网格生成、A*、碰撞快照)。
|
||||
|
||||
5.2 性能优化要点
|
||||
|
||||
- 网格生成:
|
||||
- ChannelBased 2.5D 优先(垂直扫描、空间哈希、通道优先),失败回退 BoundingBox;
|
||||
- 车辆膨胀:距离变换 O(n*m) 优化,跳过无障碍场景;
|
||||
@ -246,11 +271,11 @@
|
||||
- Search API 替代全量遍历,尤其在通道/楼层检索时。
|
||||
|
||||
5.3 可维护性
|
||||
|
||||
- 分层清晰,事件驱动,保留向后兼容事件(_Legacy);
|
||||
- 路径文件以 XML 为主,便于第三方集成;
|
||||
- 关键类职责单一(PathPlanningManager/CategoryAttributeManager/GridMapGenerator 等)。
|
||||
|
||||
|
||||
六、风险与边界
|
||||
|
||||
- Navisworks 版本差异:2017 与 2026 API 行为差异需要回归验证;
|
||||
@ -259,7 +284,6 @@
|
||||
- COM 属性写入:需严格使用相对索引覆盖逻辑(源码已修复),防止属性覆盖错乱;
|
||||
- 动画碰撞“位置恢复”:测试期间会短暂移动对象做验证,并在结束后恢复。
|
||||
|
||||
|
||||
七、里程碑建议(示例)
|
||||
|
||||
- M1(1 周):路径编辑闭环(手动)、物流属性标注、可见性隔离;
|
||||
@ -268,7 +292,6 @@
|
||||
- M4(1 周):导航输出与 DELMIA 结果结构;
|
||||
- M5(1 周):性能与兼容性回归(2017 基线,若选 2026 追加一轮)。
|
||||
|
||||
|
||||
八、截图占位与要求
|
||||
|
||||
- [截图占位] 系统架构图:
|
||||
@ -286,8 +309,8 @@
|
||||
- [截图占位] 结果文件样例:
|
||||
- 要求:XML/CSV 字段示意,可用于 DELMIA 导入对齐。
|
||||
|
||||
|
||||
附录 A:代码与模块清单(节选)
|
||||
|
||||
- Core/MainPlugin、UI/WPF/LogisticsControlPanel.xaml:主入口与面板;
|
||||
- Core/PathPlanningManager:路径规划主控(状态、事件、可视化、导入导出)
|
||||
- PathPlanning/GridMapGenerator、AutoPathFinder:网格生成与 A* 路径;
|
||||
@ -296,4 +319,3 @@
|
||||
- Core/Collision/ClashDetectiveIntegration:动画期缓存 + 结束创建测试;
|
||||
- Core/VisibilityManager:可见性隔离与统计;
|
||||
- UI/WPF/ViewModels/*:MVVM 视图模型与命令绑定。
|
||||
|
||||
|
||||
@ -886,7 +886,7 @@ namespace NavisworksTransport
|
||||
{
|
||||
StartPoint = prevPoint.Position,
|
||||
EndPoint = previewPoint.Position,
|
||||
Color = Color.White, // 使用白色作为预览连线颜色(灰色在Navisworks API中不可用)
|
||||
Color = Color.FromByteRGB(128, 128, 128), // 统一使用灰色预览连线
|
||||
Radius = GetLineRadius() // 使用与正常连线相同的直径
|
||||
};
|
||||
_previewLines.Add(line1);
|
||||
@ -896,7 +896,7 @@ namespace NavisworksTransport
|
||||
{
|
||||
StartPoint = previewPoint.Position,
|
||||
EndPoint = nextPoint.Position,
|
||||
Color = Color.White,
|
||||
Color = Color.FromByteRGB(128, 128, 128), // 统一使用灰色预览连线
|
||||
Radius = GetLineRadius()
|
||||
};
|
||||
_previewLines.Add(line2);
|
||||
@ -961,25 +961,63 @@ namespace NavisworksTransport
|
||||
{
|
||||
LogManager.WriteLog($"[预览路径渲染] 开始渲染预览路径: {previewRoute.Name}, 点数: {previewRoute.Points.Count}");
|
||||
|
||||
// 清理现有预览
|
||||
ClearPreview();
|
||||
// 只清理预览元素,不影响原有路径
|
||||
ClearPreviewPoint();
|
||||
ClearPreviewLines();
|
||||
|
||||
// 渲染预览路径点
|
||||
// 找到预览点及其索引
|
||||
var previewPointIndex = -1;
|
||||
PathPoint previewPoint = null;
|
||||
|
||||
for (int i = 0; i < previewRoute.Points.Count; i++)
|
||||
{
|
||||
var point = previewRoute.Points[i];
|
||||
|
||||
// 对于修改中的点,使用特殊颜色(白色)
|
||||
if (point.Name.Contains("_预览"))
|
||||
if (previewRoute.Points[i].Name.Contains("_预览"))
|
||||
{
|
||||
RenderPreviewPoint(point);
|
||||
previewPointIndex = i;
|
||||
previewPoint = previewRoute.Points[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染预览连线
|
||||
if (previewRoute.Points.Count > 1)
|
||||
|
||||
if (previewPoint != null && previewPointIndex >= 0)
|
||||
{
|
||||
RenderPreviewPathLines(previewRoute);
|
||||
// 只渲染预览点
|
||||
RenderPreviewPoint(previewPoint);
|
||||
|
||||
// 只渲染与预览点相关的连线
|
||||
// 连接前一个点到预览点
|
||||
if (previewPointIndex > 0)
|
||||
{
|
||||
var prevPoint = previewRoute.Points[previewPointIndex - 1];
|
||||
var line1 = new LineMarker
|
||||
{
|
||||
StartPoint = prevPoint.Position,
|
||||
EndPoint = previewPoint.Position,
|
||||
Color = Color.FromByteRGB(128, 128, 128), // 灰色预览连线
|
||||
Radius = GetLineRadius()
|
||||
};
|
||||
_previewLines.Add(line1);
|
||||
}
|
||||
|
||||
// 连接预览点到下一个点
|
||||
if (previewPointIndex < previewRoute.Points.Count - 1)
|
||||
{
|
||||
var nextPoint = previewRoute.Points[previewPointIndex + 1];
|
||||
var line2 = new LineMarker
|
||||
{
|
||||
StartPoint = previewPoint.Position,
|
||||
EndPoint = nextPoint.Position,
|
||||
Color = Color.FromByteRGB(128, 128, 128), // 灰色预览连线
|
||||
Radius = GetLineRadius()
|
||||
};
|
||||
_previewLines.Add(line2);
|
||||
}
|
||||
|
||||
LogManager.WriteLog($"[预览路径渲染] 已渲染编辑预览: 预览点 + {_previewLines.Count} 条连线");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.WriteLog("[预览路径渲染] 未找到预览点,跳过渲染");
|
||||
}
|
||||
|
||||
RequestViewRefresh();
|
||||
@ -1012,7 +1050,7 @@ namespace NavisworksTransport
|
||||
{
|
||||
StartPoint = startPoint.Position,
|
||||
EndPoint = endPoint.Position,
|
||||
Color = Color.FromByteRGB(128, 128, 128), // 预览连线使用灰色
|
||||
Color = Color.FromByteRGB(128, 128, 128), // 统一使用灰色预览连线
|
||||
Radius = GetLineRadius()
|
||||
};
|
||||
|
||||
|
||||
@ -315,6 +315,12 @@ namespace NavisworksTransport.UI.WPF
|
||||
// 清理PathEditingView
|
||||
PathEditingView?.Cleanup();
|
||||
|
||||
// 🔧 修复:清理ModelSettingsView(会调用ViewModel的Dispose)
|
||||
_modelSettingsView?.Cleanup();
|
||||
|
||||
// 🔧 修复:清理LayerManagementView(会调用ViewModel的Dispose)
|
||||
_layerManagementView?.Cleanup();
|
||||
|
||||
// 清理SystemManagementViewModel
|
||||
SystemManagementViewModel?.Cleanup();
|
||||
|
||||
|
||||
@ -47,6 +47,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
// 选择事件订阅管理器
|
||||
private SelectionEventSubscription _selectionEventSubscription;
|
||||
|
||||
// 资源释放状态标志
|
||||
private bool _disposed;
|
||||
|
||||
#endregion
|
||||
|
||||
@ -2815,27 +2818,45 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 取消正在进行的操作
|
||||
_cancellationTokenSource?.Cancel();
|
||||
_cancellationTokenSource?.Dispose();
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// 取消事件订阅
|
||||
if (_modelSplitterManager != null)
|
||||
/// <summary>
|
||||
/// 释放资源的具体实现
|
||||
/// </summary>
|
||||
/// <param name="disposing">是否正在释放托管资源</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_modelSplitterManager.ProgressChanged -= OnProgressChanged;
|
||||
_modelSplitterManager.StatusChanged -= OnStatusChanged;
|
||||
try
|
||||
{
|
||||
// 取消正在进行的操作
|
||||
_cancellationTokenSource?.Cancel();
|
||||
_cancellationTokenSource?.Dispose();
|
||||
|
||||
// 取消事件订阅
|
||||
if (_modelSplitterManager != null)
|
||||
{
|
||||
_modelSplitterManager.ProgressChanged -= OnProgressChanged;
|
||||
_modelSplitterManager.StatusChanged -= OnStatusChanged;
|
||||
}
|
||||
|
||||
// 取消Navisworks选择变化事件订阅
|
||||
UnsubscribeFromSelectionEvents();
|
||||
|
||||
LogManager.Info("[LayerManagementViewModel] 资源清理完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[LayerManagementViewModel] 资源清理失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// 取消Navisworks选择变化事件订阅
|
||||
UnsubscribeFromSelectionEvents();
|
||||
|
||||
LogManager.Info("[LayerManagementViewModel] 资源清理完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[LayerManagementViewModel] 资源清理失败: {ex.Message}");
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2916,6 +2937,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
private async Task OnSelectionChangedAsync(SelectionStateResult selectionResult)
|
||||
{
|
||||
// 如果已经释放,直接返回
|
||||
if (_disposed) return;
|
||||
|
||||
try
|
||||
{
|
||||
// 更新楼层属性相关的选择状态(使用新的选择结果)
|
||||
@ -2934,6 +2958,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
private async Task UpdateFloorAttributeSelectionStateAsync(SelectionStateResult selectionResult = null)
|
||||
{
|
||||
// 如果已经释放,直接返回
|
||||
if (_disposed) return;
|
||||
|
||||
try
|
||||
{
|
||||
// 如果没有提供选择结果,则获取当前选择状态
|
||||
|
||||
@ -35,6 +35,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
// 选择事件订阅管理器
|
||||
private SelectionEventSubscription _selectionEventSubscription;
|
||||
|
||||
// 资源释放状态标志
|
||||
private bool _disposed;
|
||||
|
||||
#endregion
|
||||
|
||||
@ -766,6 +769,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
private async Task OnSelectionChangedAsync(SelectionStateResult selectionResult)
|
||||
{
|
||||
// 如果已经释放,直接返回
|
||||
if (_disposed) return;
|
||||
|
||||
try
|
||||
{
|
||||
// 更新物流属性相关的选择状态(使用新的选择结果)
|
||||
@ -784,6 +790,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
private async Task UpdateModelSelectionStateAsync(SelectionStateResult selectionResult = null)
|
||||
{
|
||||
// 如果已经释放,直接返回
|
||||
if (_disposed) return;
|
||||
|
||||
try
|
||||
{
|
||||
// 如果没有提供选择结果,则获取当前选择状态
|
||||
@ -1245,16 +1254,34 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 取消选择事件订阅
|
||||
UnsubscribeFromSelectionEvents();
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
LogManager.Info("[ModelSettingsViewModel] 资源清理完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
/// <summary>
|
||||
/// 释放资源的具体实现
|
||||
/// </summary>
|
||||
/// <param name="disposing">是否正在释放托管资源</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
LogManager.Error($"[ModelSettingsViewModel] 资源清理失败: {ex.Message}");
|
||||
if (disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 取消选择事件订阅
|
||||
UnsubscribeFromSelectionEvents();
|
||||
|
||||
LogManager.Info("[ModelSettingsViewModel] 资源清理完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[ModelSettingsViewModel] 资源清理失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +34,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
private string _runningTime = "00:00:00";
|
||||
private string _performanceInfo = "性能监控就绪";
|
||||
|
||||
// 🔧 修复:添加定时器字段以便在清理时停止
|
||||
private System.Windows.Threading.DispatcherTimer _performanceTimer;
|
||||
|
||||
// 🔧 修复:添加释放状态标志
|
||||
private bool _disposed = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 公共属性
|
||||
@ -277,15 +283,30 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
/// </summary>
|
||||
private void StartPerformanceMonitoring()
|
||||
{
|
||||
// 🔧 修复:如果已经释放,不启动定时器
|
||||
if (_disposed)
|
||||
{
|
||||
LogManager.Info("SystemManagementViewModel已释放,跳过性能监控启动");
|
||||
return;
|
||||
}
|
||||
|
||||
var startTime = DateTime.Now;
|
||||
|
||||
// 使用定时器更新性能信息
|
||||
var timer = new System.Windows.Threading.DispatcherTimer();
|
||||
timer.Interval = TimeSpan.FromSeconds(5);
|
||||
timer.Tick += (s, e) =>
|
||||
// 🔧 修复:保存定时器引用以便在清理时停止
|
||||
_performanceTimer = new System.Windows.Threading.DispatcherTimer();
|
||||
_performanceTimer.Interval = TimeSpan.FromSeconds(5);
|
||||
_performanceTimer.Tick += (s, e) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// 🔧 修复:检查释放状态,避免在释放后继续更新UI
|
||||
if (_disposed)
|
||||
{
|
||||
LogManager.Info("SystemManagementViewModel已释放,停止性能监控更新");
|
||||
_performanceTimer?.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新内存使用
|
||||
var process = System.Diagnostics.Process.GetCurrentProcess();
|
||||
var memoryMB = process.WorkingSet64 / (1024 * 1024);
|
||||
@ -301,9 +322,17 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"性能监控更新失败: {ex.Message}");
|
||||
|
||||
// 🔧 修复:发生异常时也停止定时器
|
||||
if (!_disposed)
|
||||
{
|
||||
_performanceTimer?.Stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
timer.Start();
|
||||
_performanceTimer.Start();
|
||||
|
||||
LogManager.Info("SystemManagementViewModel性能监控已启动");
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -552,6 +581,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
// 🔧 修复:检查释放状态,避免在释放后更新UI
|
||||
if (_disposed)
|
||||
{
|
||||
LogManager.Info("SystemManagementViewModel已释放,跳过更新检查UI更新");
|
||||
return;
|
||||
}
|
||||
|
||||
SystemStatus = "当前版本已是最新版本";
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -583,6 +619,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
// 🔧 修复:检查释放状态,避免在释放后更新UI
|
||||
if (_disposed)
|
||||
{
|
||||
LogManager.Info("SystemManagementViewModel已释放,跳过性能报告UI更新");
|
||||
return;
|
||||
}
|
||||
|
||||
SystemStatus = "性能报告生成完成";
|
||||
PerformanceInfo = $"报告已生成 - {DateTime.Now:yyyy-MM-dd HH:mm:ss}";
|
||||
}
|
||||
@ -662,7 +705,17 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
LogManager.Info("开始清理SystemManagementViewModel资源");
|
||||
|
||||
// 目前没有需要特别清理的资源
|
||||
// 🔧 修复:标记为已释放
|
||||
_disposed = true;
|
||||
|
||||
// 🔧 修复:停止性能监控定时器
|
||||
if (_performanceTimer != null)
|
||||
{
|
||||
_performanceTimer.Stop();
|
||||
_performanceTimer.Tick -= null; // 取消事件订阅
|
||||
_performanceTimer = null;
|
||||
LogManager.Info("SystemManagementViewModel性能监控定时器已停止");
|
||||
}
|
||||
|
||||
LogManager.Info("SystemManagementViewModel资源清理完成");
|
||||
}
|
||||
|
||||
@ -70,5 +70,22 @@ namespace NavisworksTransport.UI.WPF.Views
|
||||
LogManager.Error($"[LayerManagementView] 页面卸载失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理资源
|
||||
/// </summary>
|
||||
public void Cleanup()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 清理ViewModel
|
||||
ViewModel?.Dispose();
|
||||
LogManager.Info("LayerManagementView资源清理完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"LayerManagementView清理失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using NavisworksTransport.UI.WPF.ViewModels;
|
||||
using NavisworksTransport.Utils;
|
||||
@ -24,5 +25,25 @@ namespace NavisworksTransport.UI.WPF.Views
|
||||
LogManager.Error($"ModelSettingsView初始化失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理资源
|
||||
/// </summary>
|
||||
public void Cleanup()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 清理ViewModel
|
||||
if (DataContext is ModelSettingsViewModel viewModel)
|
||||
{
|
||||
viewModel.Dispose();
|
||||
LogManager.Info("ModelSettingsView资源清理完成");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"ModelSettingsView清理失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user