优化插件启动时的动作

This commit is contained in:
tian 2025-10-14 16:29:05 +08:00
parent b7a112354d
commit 3aaa176ce6
10 changed files with 156 additions and 220 deletions

View File

@ -2,6 +2,11 @@
## 功能点
### [2025/10/14]
1. [x] (功能优化)用空间索引优化碰撞路径预处理
2. [x] (功能优化)规范文档打开前/后的初始化行为
### [2025/10/12]
1. [x] 实验性功能用体素网格实现3D路径规划

View File

@ -484,7 +484,7 @@ namespace NavisworksTransport
var pathManager = PathPlanningManager.GetActivePathManager();
if (pathManager != null)
{
pathManager.EnsureDatabaseInitialized();
pathManager.DatabaseInitialize();
LogManager.Info("[文档管理] 已触发PathDatabase初始化");
}
}, "初始化PathDatabase");

View File

@ -443,80 +443,16 @@ namespace NavisworksTransport
{
// 设置静态实例
Instance = this;
_floorDetector = new FloorDetector();
// 初始化缓存
_floorCache = new Dictionary<string, List<SplitPreviewResult>>();
_cacheLock = new object();
// 验证Navisworks运行时环境
ValidateNavisworksRuntime();
LogManager.Info("[SimplifiedModelSplitter] 简化分层管理器已初始化,包含缓存机制和运行时验证");
LogManager.Debug("[ModelSplitterManager] 分层管理器已初始化");
}
/// <summary>
/// 验证Navisworks运行时环境 - 基于示例中的最佳实践
/// </summary>
private void ValidateNavisworksRuntime()
{
try
{
LogManager.Info("[SimplifiedModelSplitter] 开始验证Navisworks运行时环境...");
// 1. 检查线程模型 - 必须在STA线程中
var apartmentState = System.Threading.Thread.CurrentThread.GetApartmentState();
LogManager.Info($"[分层管理器] 当前线程状态: {apartmentState}");
if (apartmentState != System.Threading.ApartmentState.STA)
{
LogManager.Warning("[SimplifiedModelSplitter] 警告当前不在STA线程中这可能导致API调用失败");
LogManager.Warning("[SimplifiedModelSplitter] 建议:确保主线程标记为[STAThread]");
}
// 2. 检查Navisworks API可用性 - 适用于Navisworks 2026
try
{
// 尝试访问Navisworks Application来验证API是否可用
var app = NavisApplication.ActiveDocument;
LogManager.Info("[SimplifiedModelSplitter] Navisworks API可用性检查通过");
}
catch (Exception apiEx)
{
LogManager.Error($"[分层管理器] Navisworks API不可用: {apiEx.Message}");
LogManager.Error("[SimplifiedModelSplitter] 解决方案确保在Navisworks环境中运行此插件");
}
// 3. 检查文档状态
try
{
var document = NavisApplication.ActiveDocument;
if (document != null)
{
LogManager.Info($"[分层管理器] 活动文档: {document.FileName ?? ""}");
LogManager.Info($"[分层管理器] 文档模型数量: {document.Models?.Count ?? 0}");
}
else
{
LogManager.Warning("[SimplifiedModelSplitter] 当前没有活动文档");
}
}
catch (Exception docEx)
{
LogManager.Warning($"[分层管理器] 检查文档状态时出错: {docEx.Message}");
}
// 4. 内存状态检查
long memoryMB = GC.GetTotalMemory(false) / 1024 / 1024;
LogManager.Info($"[分层管理器] 当前内存使用: {memoryMB} MB");
LogManager.Info("[SimplifiedModelSplitter] Navisworks运行时环境验证完成");
}
catch (Exception ex)
{
LogManager.Error($"[分层管理器] 运行时环境验证失败: {ex.Message}");
}
}
#endregion

View File

@ -117,40 +117,6 @@ namespace NavisworksTransport
_activePathManager = this;
LogManager.Debug($"[路径管理] 设置_activePathManager静态引用, ManagerId: {_managerId}");
// 尝试初始化路径分析数据库
EnsureDatabaseInitialized();
}
/// <summary>
/// 确保路径分析数据库已初始化(支持延迟初始化)
/// </summary>
public void EnsureDatabaseInitialized()
{
if (_pathDatabase != null && _analysisService != null)
{
LogManager.Info("路径分析数据库已初始化,跳过");
return;
}
try
{
var documentPath = Autodesk.Navisworks.Api.Application.ActiveDocument?.FileName;
if (!string.IsNullOrEmpty(documentPath))
{
_pathDatabase = new PathDatabase(documentPath);
_analysisService = new PathAnalysisService(_pathDatabase);
LogManager.Info($"路径分析数据库初始化成功,文档路径: {documentPath}");
}
else
{
LogManager.Warning("文档路径为空,路径分析数据库初始化将延迟到文档加载后");
}
}
catch (Exception ex)
{
LogManager.Error($"初始化路径分析数据库失败: {ex.Message}", ex);
}
// 获取已注册的圆形渲染插件实例
try
{
@ -175,6 +141,7 @@ namespace NavisworksTransport
_renderPlugin = null;
}
// 初始化核心数据结构
_walkableAreas = new List<ModelItem>();
_routes = new List<PathRoute>();
_currentRoute = new PathRoute("默认路径");
@ -182,10 +149,47 @@ namespace NavisworksTransport
_coordinateConverter = null; // 将在需要时初始化
_pathPointMarkers = new List<PathPointMarker>();
// 从数据库加载历史路径到内存
LoadHistoricalRoutesFromDatabase();
LogManager.Info($"PathPlanningManager初始化完成ManagerId: {_managerId}");
// 注意:数据库初始化延迟到文档加载完成后
// 在 MainPlugin.OnModelsCollectionChanged 中会调用 DatabaseInitialize()
}
/// <summary>
/// 路径分析数据库初始化
/// 此方法应在文档加载完成后调用
/// </summary>
public void DatabaseInitialize()
{
// 如果已经初始化,直接返回
if (_pathDatabase != null && _analysisService != null)
{
LogManager.Debug("路径分析数据库已初始化,跳过");
return;
}
try
{
var documentPath = Application.ActiveDocument?.FileName;
if (!string.IsNullOrEmpty(documentPath))
{
_pathDatabase = new PathDatabase(documentPath);
_analysisService = new PathAnalysisService(_pathDatabase);
LogManager.Info($"路径分析数据库初始化成功,文档路径: {documentPath}");
// 从数据库加载历史路径到内存
LoadHistoricalRoutesFromDatabase();
}
else
{
// 文档路径为空时,静默跳过(这种情况不应该发生,因为调用者应该确保文档已加载)
LogManager.Debug("文档路径为空,跳过数据库初始化");
}
}
catch (Exception ex)
{
LogManager.Error($"初始化路径分析数据库失败: {ex.Message}", ex);
}
}
/// <summary>

View File

@ -200,8 +200,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
return Math.Round(pathLength / (_animationFrameRate * _animationDuration), 3);
}
// 无法计算时返回0让问题暴露
if (pathLength <= 0 || _animationFrameRate <= 0 || _animationDuration <= 0)
// 无法计算时返回0
// 注意:如果路径为空(pathLength==0),这是正常的初始状态,不输出警告
// 只有在配置参数异常时才输出警告
if (pathLength > 0 && (_animationFrameRate <= 0 || _animationDuration <= 0))
{
LogManager.Warning($"[AnimationControlViewModel] 无法计算碰撞检测精度 - 路径长度:{pathLength}m, 帧率:{_animationFrameRate}fps, 时长:{_animationDuration}s");
}
@ -224,8 +226,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
return Math.Round(pathLength / _animationDuration, 2);
}
// 无法计算时返回0让问题暴露
if (pathLength <= 0 || _animationDuration <= 0)
// 无法计算时返回0
// 注意:如果路径为空(pathLength==0),这是正常的初始状态,不输出警告
// 只有在配置参数异常时才输出警告
if (pathLength > 0 && _animationDuration <= 0)
{
LogManager.Warning($"[AnimationControlViewModel] 无法计算运动速度 - 路径长度:{pathLength}m, 时长:{_animationDuration}s");
}

View File

@ -944,7 +944,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
async () => await ShowAllLayersAsync(),
() => IsNotProcessing);
LogManager.Info("分层管理命令初始化完成 - 使用统一Command Pattern框架");
LogManager.Info("分层管理命令初始化完成");
}, "初始化命令");
}
@ -2718,20 +2718,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
// 设置默认输出目录
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
OutputDirectory = Path.Combine(documentsPath, "NavisworksTransport", "分层输出");
});
// 刷新可用属性
await RefreshAttributesAsync();
// 更新选择状态
await UpdateCurrentSelectionAsync();
// 刷新楼层属性模型选择状态
await RefreshSelectionAsync();
}
catch (Exception ex)
{

View File

@ -33,10 +33,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
#region
private readonly UIStateManager _uiStateManager;
// 选择事件订阅管理器
private SelectionEventSubscription _selectionEventSubscription;
// 文档模型集合变化事件订阅标志
private bool _modelsCollectionEventSubscribed;
// 资源释放状态标志
private bool _disposed;
@ -395,6 +398,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 订阅Navisworks选择变化事件 - 使用新的选择管理服务
SubscribeToSelectionEvents();
// 订阅文档模型集合变化事件
SubscribeToDocumentModelsEvents();
// 异步初始化
InitializeAsync();
@ -920,6 +926,83 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 选择状态格式化方法已移至NavisworksSelectionHelper中
#region
/// <summary>
/// 订阅文档模型集合变化事件
/// </summary>
private void SubscribeToDocumentModelsEvents()
{
try
{
var document = NavisApplication.ActiveDocument;
if (document?.Models != null && !_modelsCollectionEventSubscribed)
{
document.Models.CollectionChanged += OnDocumentModelsCollectionChanged;
_modelsCollectionEventSubscribed = true;
LogManager.Info("[ModelSettingsViewModel] 已订阅文档Models.CollectionChanged事件");
}
}
catch (Exception ex)
{
LogManager.Error($"[ModelSettingsViewModel] 订阅文档模型集合事件失败: {ex.Message}", ex);
}
}
/// <summary>
/// 取消订阅文档模型集合变化事件
/// </summary>
private void UnsubscribeFromDocumentModelsEvents()
{
try
{
if (_modelsCollectionEventSubscribed)
{
var document = NavisApplication.ActiveDocument;
if (document?.Models != null)
{
document.Models.CollectionChanged -= OnDocumentModelsCollectionChanged;
}
_modelsCollectionEventSubscribed = false;
LogManager.Info("[ModelSettingsViewModel] 已取消订阅文档Models.CollectionChanged事件");
}
}
catch (Exception ex)
{
LogManager.Error($"[ModelSettingsViewModel] 取消订阅文档模型集合事件失败: {ex.Message}", ex);
}
}
/// <summary>
/// 文档模型集合变化事件处理器
/// </summary>
private async void OnDocumentModelsCollectionChanged(object sender, EventArgs e)
{
// 如果已经释放,直接返回
if (_disposed) return;
try
{
var document = NavisApplication.ActiveDocument;
var modelsCount = document?.Models?.Count ?? 0;
LogManager.Info($"[ModelSettingsViewModel] 文档模型集合变化,当前模型数量: {modelsCount}");
// 只有在有模型的情况下才刷新物流模型列表
if (modelsCount > 0)
{
LogManager.Info("[ModelSettingsViewModel] 检测到文档模型加载完成,自动刷新物流模型列表");
await RefreshLogisticsModelsAsync();
}
}
catch (Exception ex)
{
LogManager.Error($"[ModelSettingsViewModel] 处理文档模型集合变化事件异常: {ex.Message}", ex);
}
}
#endregion
#region
/// <summary>
@ -1053,17 +1136,16 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
});
// 刷新选择状态
await RefreshSelectionAsync();
// 注意:不在初始化时刷新选择状态和物流模型列表
// 刷新会在以下情况自动触发:
// 1. 选择状态 - 通过 NavisworksSelectionHelper 的选择变化事件自动刷新
// 2. 物流模型列表 - 通过 Models.CollectionChanged 事件在文档加载后自动刷新
// 刷新物流模型列表
await RefreshLogisticsModelsAsync();
// 🔧 确保初始化完成后所有Command状态正确
await _uiStateManager.ExecuteUIUpdateAsync(() =>
{
RefreshAllCommands();
UpdateMainStatus("分层属性设置已就绪");
UpdateMainStatus("类别设置已就绪");
});
}
catch (Exception ex)
@ -1253,6 +1335,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 取消选择事件订阅
UnsubscribeFromSelectionEvents();
// 取消文档模型集合事件订阅
UnsubscribeFromDocumentModelsEvents();
LogManager.Info("[ModelSettingsViewModel] 资源清理完成");
}
catch (Exception ex)

View File

@ -174,7 +174,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
try
{
var manager = PathPlanningManager.Instance;
manager.EnsureDatabaseInitialized();
manager.DatabaseInitialize();
}
catch (Exception ex)
{

View File

@ -2148,14 +2148,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
if (_pathPlanningManager == null)
{
LogManager.Info("PathPlanningManager为null,跳过事件订阅");
LogManager.Debug("PathPlanningManager尚未设置,跳过事件订阅");
return;
}
try
{
LogManager.Info($"*** 开始订阅PathPlanningManager事件Manager实例: {_pathPlanningManager.GetType().Name} ***");
// 订阅路径点操作事件(用于手工路径编辑)
_pathPlanningManager.PathPointOperation += OnPathPointOperation;
@ -2174,22 +2172,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 添加错误事件订阅 - 用于处理自动路径规划失败等错误
_pathPlanningManager.ErrorOccurred += OnPathPlanningError;
LogManager.Info("*** PathEditingViewModel已成功订阅PathPlanningManager事件包括RouteGenerated和ErrorOccurred ***");
// 验证事件订阅是否成功
var routeGeneratedField = _pathPlanningManager.GetType().GetEvent("RouteGenerated");
if (routeGeneratedField != null)
{
LogManager.Info($"*** RouteGenerated事件存在事件类型: {routeGeneratedField.EventHandlerType?.Name} ***");
}
else
{
LogManager.Error("*** RouteGenerated事件不存在 ***");
}
// 初始化加载现有路径(包括从数据库加载的历史路径)
RefreshPathRoutes();
LogManager.Info("*** 已从PathPlanningManager加载现有路径到UI ***");
LogManager.Debug("PathEditingViewModel已成功订阅PathPlanningManager事件");
}
catch (Exception ex)
{

View File

@ -460,82 +460,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
UpdateMainStatus("系统管理初始化完成");
});
// 启动性能监控
StartPerformanceMonitoring();
LogManager.Info("系统管理设置初始化完成");
}, "初始化系统管理设置");
}
/// <summary>
/// 启动性能监控 (已优化为Idle事件)
/// </summary>
private void StartPerformanceMonitoring()
{
// 如果已经释放,不启动监控
if (_disposed)
{
LogManager.Info("SystemManagementViewModel已释放跳过性能监控启动");
return;
}
_startTime = DateTime.Now;
_lastPerformanceUpdate = DateTime.MinValue;
// 使用IdleEventManager注册性能监控任务替代DispatcherTimer
const string taskId = "SystemManagement_PerformanceMonitor";
IdleEventManager.Instance.RegisterTask(
taskId,
UpdatePerformanceMetrics, // 要执行的操作
30000, // 30秒间隔 (毫秒)
5 // 中等优先级
);
LogManager.Info("SystemManagementViewModel性能监控已启动 (Idle事件模式)");
}
/// <summary>
/// 更新性能指标 (Idle事件回调方法)
/// </summary>
private void UpdatePerformanceMetrics()
{
try
{
// 检查释放状态避免在释放后继续更新UI
if (_disposed)
{
LogManager.Info("SystemManagementViewModel已释放停止性能监控更新");
IdleEventManager.Instance.UnregisterTask("SystemManagement_PerformanceMonitor");
return;
}
// 更新内存使用
var process = System.Diagnostics.Process.GetCurrentProcess();
var memoryMB = process.WorkingSet64 / (1024 * 1024);
MemoryUsage = $"{memoryMB} MB";
// 更新运行时间
var runTime = DateTime.Now - _startTime;
RunningTime = $"{runTime.Hours:D2}:{runTime.Minutes:D2}:{runTime.Seconds:D2}";
// 记录上次更新时间
_lastPerformanceUpdate = DateTime.Now;
LogManager.Debug($"性能指标已更新: 内存={MemoryUsage}, 运行时间={RunningTime}");
}
catch (Exception ex)
{
LogManager.Error($"性能监控更新失败: {ex.Message}");
// 发生异常时停止监控,避免持续错误
if (!_disposed)
{
IdleEventManager.Instance.UnregisterTask("SystemManagement_PerformanceMonitor");
}
}
}
#endregion
#region