From fcc87b2cb0b86e60c6a44638e15ebc443037a049 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Wed, 14 Jan 2026 11:41:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A9=BA=E9=97=B4=E7=B4=A2?= =?UTF-8?q?=E5=BC=95=E6=A0=BC=E5=AD=90=E5=A4=A7=E5=B0=8F=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E5=8A=A8=E7=94=BB=E7=A2=B0=E6=92=9E?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E6=80=A7=E8=83=BD=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=AE=BE=E7=BD=AE=E7=9A=84=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- default_config.toml | 3 ++ doc/requirement/todo_features.md | 4 +-- src/Core/Animation/PathAnimationManager.cs | 7 ++-- src/Core/Config/ConfigManager.cs | 2 ++ src/Core/Config/SystemConfig.cs | 5 +++ src/PathPlanning/RailGeometryHelper.cs | 2 +- .../WPF/ViewModels/ModelSettingsViewModel.cs | 36 +++++++++---------- 7 files changed, 34 insertions(+), 25 deletions(-) diff --git a/default_config.toml b/default_config.toml index 8b1d0e7..a9fab39 100644 --- a/default_config.toml +++ b/default_config.toml @@ -40,6 +40,9 @@ duration_seconds = 10.0 # 检测间隙(米) detection_gap_meters = 0.05 +# 空间索引格子大小(米)- 用于动画碰撞检测的空间索引,推荐值:车辆宽度 +spatial_index_cell_size = 1.0 + [logistics] # 可通行性(默认值:true) traversable = true diff --git a/doc/requirement/todo_features.md b/doc/requirement/todo_features.md index d734751..9b7750a 100644 --- a/doc/requirement/todo_features.md +++ b/doc/requirement/todo_features.md @@ -4,8 +4,8 @@ ### [2026/1/13] -1. [ ] (优化)检查API调用的线程安全问题,提高插件的稳定性 -2. [ ] (优化)减少ClashDetective检测部分的耗时 +1. [x] (优化)检查API调用的线程安全问题,提高插件的稳定性 +2. [x] (优化)减少ClashDetective检测部分的耗时 ### [2026/1/6] diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs index 1e18afe..af71c55 100644 --- a/src/Core/Animation/PathAnimationManager.cs +++ b/src/Core/Animation/PathAnimationManager.cs @@ -539,11 +539,10 @@ namespace NavisworksTransport.Core.Animation LogManager.Info("=== 构建全局空间索引 ==="); spatialIndexManager = SpatialIndexManager.Instance; - // 使用传入的车辆宽度参数,而不是从ConfigManager读取 - double vehicleWidthMeters = _virtualVehicleWidth; - double cellSizeInModelUnits = UnitsConverter.ConvertFromMeters(vehicleWidthMeters); + // 使用动画专用的空间索引格子大小配置 + double cellSizeInModelUnits = UnitsConverter.ConvertFromMeters(ConfigManager.Instance.Current.Animation.SpatialIndexCellSize); - LogManager.Info($"[空间索引] 车辆宽度: {vehicleWidthMeters:F2}米 → 格子大小: {cellSizeInModelUnits:F2}模型单位"); + LogManager.Info($"[空间索引] 格子大小: {cellSizeInModelUnits:F2}模型单位 (动画配置)"); // 检查空间索引是否需要重新构建(格子大小变化或未初始化) bool needRebuild = !spatialIndexManager.IsInitialized || diff --git a/src/Core/Config/ConfigManager.cs b/src/Core/Config/ConfigManager.cs index 3a151f8..4e9ffd5 100644 --- a/src/Core/Config/ConfigManager.cs +++ b/src/Core/Config/ConfigManager.cs @@ -198,6 +198,7 @@ namespace NavisworksTransport.Core.Config config.Animation.FrameRate = GetRequiredIntValue(anim, "frame_rate"); config.Animation.DurationSeconds = GetRequiredDoubleValue(anim, "duration_seconds"); config.Animation.DetectionGapMeters = GetRequiredDoubleValue(anim, "detection_gap_meters"); + config.Animation.SpatialIndexCellSize = GetRequiredDoubleValue(anim, "spatial_index_cell_size"); // 加载物流属性配置 if (!model.ContainsKey("logistics")) @@ -344,6 +345,7 @@ namespace NavisworksTransport.Core.Config anim["frame_rate"] = config.Animation.FrameRate; anim["duration_seconds"] = config.Animation.DurationSeconds; anim["detection_gap_meters"] = config.Animation.DetectionGapMeters; + anim["spatial_index_cell_size"] = config.Animation.SpatialIndexCellSize; } } diff --git a/src/Core/Config/SystemConfig.cs b/src/Core/Config/SystemConfig.cs index 14b5080..3ca1803 100644 --- a/src/Core/Config/SystemConfig.cs +++ b/src/Core/Config/SystemConfig.cs @@ -127,6 +127,11 @@ namespace NavisworksTransport.Core.Config /// 检测间隙(米) /// public double DetectionGapMeters { get; set; } + + /// + /// 空间索引格子大小(米)- 用于动画碰撞检测的空间索引 + /// + public double SpatialIndexCellSize { get; set; } } /// diff --git a/src/PathPlanning/RailGeometryHelper.cs b/src/PathPlanning/RailGeometryHelper.cs index 24dc992..2da3828 100644 --- a/src/PathPlanning/RailGeometryHelper.cs +++ b/src/PathPlanning/RailGeometryHelper.cs @@ -422,7 +422,7 @@ namespace NavisworksTransport.PathPlanning if (railItems == null || railItems.Count == 0) { - LogManager.Warning("[空轨] 没有找到设置为空轨属性的模型"); + LogManager.Info("[空轨] 没有找到设置为空轨属性的模型"); return 0; } diff --git a/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs b/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs index acc3161..8ddb022 100644 --- a/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs +++ b/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs @@ -586,12 +586,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (result.Success) { await RefreshLogisticsModelsAsync(); - + // 如果当前处于仅显示物流模式,重新应用可见性设置 if (IsLogisticsOnlyMode) { // 重要:ApplyVisibilityMode包含Navisworks API调用,必须在主线程中执行 - ApplyVisibilityMode(); + await _uiStateManager.ExecuteUIUpdateAsync(() => ApplyVisibilityMode()); } } } @@ -631,8 +631,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels try { - // 2. 纯业务逻辑执行(后台线程,不使用UIStateManager) - var result = await Task.Run(() => + // 2. 业务逻辑执行(必须在主线程上执行,因为包含 Navisworks COM API 调用) + var result = await _uiStateManager.ExecuteUIUpdateAsync(() => { try { @@ -645,12 +645,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels // 使用CategoryAttributeManager的RemoveLogisticsAttributes方法 int successCount = CategoryAttributeManager.RemoveLogisticsAttributes(selectedItems); - return new { - Success = successCount > 0, - Count = successCount, - Message = successCount > 0 ? - $"已清除 {successCount} 个元素的物流属性" : - "没有找到可清除的物流属性" + return new { + Success = successCount > 0, + Count = successCount, + Message = successCount > 0 ? + $"已清除 {successCount} 个元素的物流属性" : + "没有找到可清除的物流属性" }; } catch (Exception ex) @@ -678,12 +678,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels if (result.Success) { await RefreshLogisticsModelsAsync(); - + // 如果当前处于仅显示物流模式,重新应用可见性设置 if (IsLogisticsOnlyMode) { // 重要:ApplyVisibilityMode包含Navisworks API调用,必须在主线程中执行 - ApplyVisibilityMode(); + await _uiStateManager.ExecuteUIUpdateAsync(() => ApplyVisibilityMode()); } } } @@ -721,8 +721,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels try { - // 2. 纯业务逻辑执行(后台线程,不使用UIStateManager) - var result = await Task.Run(() => + // 2. 业务逻辑执行(必须在主线程上执行,因为包含 Navisworks COM API 调用) + var result = await _uiStateManager.ExecuteUIUpdateAsync(() => { try { @@ -730,12 +730,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels var document = NavisApplication.ActiveDocument; var logisticsItems = CategoryAttributeManager.GetAllLogisticsItems(); var models = new List(); - + foreach (var item in logisticsItems) { // 直接使用 CategoryAttributeManager 的 API var info = CategoryAttributeManager.GetLogisticsAttributeInfo(item); - + var model = new LogisticsModel { Name = item.DisplayName ?? "未命名模型", @@ -746,7 +746,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels }; models.Add(model); } - + return new { Success = true, Models = models, Count = models.Count }; } catch (Exception ex) @@ -1163,7 +1163,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels { ShowAllInternal(); } - }, "应用可见性模式"); + }, "应用可见性模式", runOnUIThread: true); } ///