修改路径点预览效果和退出清理的bug

This commit is contained in:
tian 2025-09-01 18:36:23 +08:00
parent e72e581f85
commit 508c3e8e79
11 changed files with 1206 additions and 56 deletions

View 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将为建筑工程领域的数字化转型提供强有力的技术支撑。

View 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()

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

View File

@ -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 环境中保证稳定运行与较好性能;
- 解耦分层UIWPF+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可见性与层级控制
- AnimationTimeLinerIntegrationManager、PathAnimationManager动画控制
- CollisionClashDetectiveIntegration碰撞集成动画期缓存 + 结束时统一测试)
- ModelSplitterManager模型切分含简化实现
@ -74,10 +79,12 @@
- Utils日志、坐标/单位转换、Navisworks API 辅助
2.2 系统架构图(截图占位)
- [截图占位] 系统架构图
- 要求:体现 UIWPF+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
- UIWPF + MVVMWinForms 仅用于部分对话框/遗留界面);
- 外部 APIAutodesk Navisworks API2017 目标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 模型切分
- 目标:对大型模型按楼层/属性进行切分,提升性能与操作体验;
- UIModelSplitterDialogWinForms
- CoreModelSplitterManager、SimplifiedModelSplitterManager
@ -111,6 +120,7 @@
- 与可见性/筛选配合以限定工作区域。
3.2 通道选择
- 能力:
- 手动选择:基于 Navisworks 选择;
- 属性筛选:通过 CategoryAttributeManager.FilterByLogisticsType(FilterTraversableItems)
@ -118,6 +128,7 @@
- PathPlanningManager.SelectChannels计算组合边界 CombinedChannelBounds 并事件广播。
3.3 路径点规划(手动 + 自动)
- 手动规划:
- 工具PathClickToolPlugin精确拾取PathPointRenderPlugin3D 渲染);
- 流程:切换到 Creating/Editing 状态 -> 添加点 -> 渲染 -> 校验;
@ -130,33 +141,39 @@
- 路径优化去冗余点、直线可达校验、2.5D 高度插值与起终点原位修正;
3.4 路径管理、编辑、保存与导入
- 编辑:创建/编辑/取消/完成编辑FinishEditing 自动将末点设为终点并触发渲染与事件);
- 文件PathFileSerializerXML 主JSON 简化,不建议作为主格式),支持多路径容器;
- 历史PathHistoryManagerCreated/Edited/ManualSave 等),提供查看历史 UI
- 导入DetectFileFormat -> LoadFromXml/LoadFromJsonJSON 加载简化,优先 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 NavisworksManage 2017需求基线。如需 2026请切换引用与验证用例见下文兼容模式
- .NET Framework4.8
- 开发工具Visual Studio建议 2019/2022
4.2 构建与产物
- 解决方案NavisworksTransport.sln
- 项目NavisworksTransportPlugin.csproj
- 产物NavisworksTransportPlugin.dllbin/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应用级异常捕获线程/任务/未处理),尝试恢复组件,提供用户友好提示;
- LogManagerInfo/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 属性写入:需严格使用相对索引覆盖逻辑(源码已修复),防止属性覆盖错乱;
- 动画碰撞“位置恢复”:测试期间会短暂移动对象做验证,并在结束后恢复。
七、里程碑建议(示例)
- M11 周):路径编辑闭环(手动)、物流属性标注、可见性隔离;
@ -268,7 +292,6 @@
- M41 周):导航输出与 DELMIA 结果结构;
- M51 周性能与兼容性回归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 视图模型与命令绑定。

View File

@ -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()
};

View File

@ -315,6 +315,12 @@ namespace NavisworksTransport.UI.WPF
// 清理PathEditingView
PathEditingView?.Cleanup();
// 🔧 修复清理ModelSettingsView会调用ViewModel的Dispose
_modelSettingsView?.Cleanup();
// 🔧 修复清理LayerManagementView会调用ViewModel的Dispose
_layerManagementView?.Cleanup();
// 清理SystemManagementViewModel
SystemManagementViewModel?.Cleanup();

View File

@ -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
{
// 如果没有提供选择结果,则获取当前选择状态

View File

@ -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;
}
}

View File

@ -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资源清理完成");
}

View File

@ -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}");
}
}
}
}

View File

@ -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}");
}
}
}
}