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);
}
///