优化虚拟车辆管理,避免动态计算尺寸,直接应用缩放值;更新模型加载完成检测逻辑,改进事件处理

This commit is contained in:
tian 2026-01-16 17:29:04 +08:00
parent 519382f375
commit f4fda4e308
3 changed files with 68 additions and 27 deletions

View File

@ -40,6 +40,11 @@ namespace NavisworksTransport.Core
private Model _virtualVehicleModel;
private bool _isVirtualVehicleActive;
// 🔥 记住虚拟车辆的尺寸变换参数(避免动态计算)
private double _currentLengthMeters = 0;
private double _currentWidthMeters = 0;
private double _currentHeightMeters = 0;
/// <summary>
/// 当前虚拟车辆ModelItem
/// </summary>
@ -87,6 +92,11 @@ namespace NavisworksTransport.Core
_virtualVehicleModelItem = geometryItem;
}
// 清除覆盖变换(之前动画移动和旋转的累积)
modelItems.Clear();
modelItems.Add(_virtualVehicleModelItem);
doc.Models.ResetPermanentTransform(modelItems);
// 重置变换并缩放到目标尺寸
ResetVirtualVehicleTransform();
ScaleVirtualVehicle(lengthMeters, widthMeters, heightMeters);
@ -237,28 +247,23 @@ namespace NavisworksTransport.Core
var doc = Application.ActiveDocument;
// 获取当前包围盒单位立方体应该是1m x 1m x 1m
var boundingBox = _virtualVehicleModelItem.BoundingBox();
double currentLength = boundingBox.Max.X - boundingBox.Min.X;
double currentWidth = boundingBox.Max.Y - boundingBox.Min.Y;
double currentHeight = boundingBox.Max.Z - boundingBox.Min.Z;
// 🔥 记住尺寸参数(避免动态计算)
_currentLengthMeters = lengthMeters;
_currentWidthMeters = widthMeters;
_currentHeightMeters = heightMeters;
// 获取单位转换因子(米到模型单位)
double metersToUnits = Utils.UnitsConverter.GetMetersToUnitsConversionFactor(doc.Units);
// 当前尺寸(米)
double currentLengthMeters = currentLength / metersToUnits;
double currentWidthMeters = currentWidth / metersToUnits;
double currentHeightMeters = currentHeight / metersToUnits;
// 🔥 对于虚拟车辆,直接应用缩放比例(不动态读取当前尺寸)
// 原因:虚拟车辆可能被旋转,导致包围盒尺寸不准确
// 单位立方体是 0.01m × 0.01m × 0.01m
double baseSizeMeters = 0.01;
double scaleX = lengthMeters / baseSizeMeters;
double scaleY = widthMeters / baseSizeMeters;
double scaleZ = heightMeters / baseSizeMeters;
LogManager.Info($"当前尺寸: {currentLengthMeters:F2}m × {currentWidthMeters:F2}m × {currentHeightMeters:F2}m");
LogManager.Info($"目标尺寸: {lengthMeters:F2}m × {widthMeters:F2}m × {heightMeters:F2}m");
// 计算缩放比例
double scaleX = currentLengthMeters > 0 ? lengthMeters / currentLengthMeters : lengthMeters;
double scaleY = currentWidthMeters > 0 ? widthMeters / currentWidthMeters : widthMeters;
double scaleZ = currentHeightMeters > 0 ? heightMeters / currentHeightMeters : heightMeters;
LogManager.Info($"缩放比例: X={scaleX:F2}, Y={scaleY:F2}, Z={scaleZ:F2}");
// 使用Transform3DComponents进行缩放
@ -274,12 +279,8 @@ namespace NavisworksTransport.Core
LogManager.Info($"当前变换 - 平移: ({currentTranslation.X:F2}, {currentTranslation.Y:F2}, {currentTranslation.Z:F2})");
LogManager.Info($"当前变换 - 缩放: ({currentScale.X:F2}, {currentScale.Y:F2}, {currentScale.Z:F2})");
// 设置新的缩放值(在原有缩放基础上乘以新的缩放比例)
transformComponents.Scale = new Vector3D(
currentScale.X * scaleX,
currentScale.Y * scaleY,
currentScale.Z * scaleZ
);
// 🔥 直接应用新的缩放值(不乘以当前缩放,避免累积)
transformComponents.Scale = new Vector3D(scaleX, scaleY, scaleZ);
// 组合成新的变换
Transform3D newTransform = transformComponents.Combine();

View File

@ -2262,7 +2262,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 将PathRouteViewModel的点转换为Point3D列表
var pathPoints = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList();
ModelItem animatedObject;
ModelItem animatedObject = null;
if (UseVirtualVehicle)
{

View File

@ -37,6 +37,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 资源释放状态标志
private bool _disposed;
// 上次模型数量,用于检测模型加载完成
private int _lastModelsCount = -1;
#endregion
#region
@ -933,8 +936,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (document?.Models != null && !_modelsCollectionEventSubscribed)
{
document.Models.SceneLoaded += OnSceneLoaded;
document.Models.CollectionChanged += OnModelsCollectionChanged;
_modelsCollectionEventSubscribed = true;
LogManager.Info("[ModelSettingsViewModel] 已订阅SceneLoaded事件");
LogManager.Info("[ModelSettingsViewModel] 已订阅SceneLoaded和CollectionChanged事件");
}
}
catch (Exception ex)
@ -956,9 +960,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (document?.Models != null)
{
document.Models.SceneLoaded -= OnSceneLoaded;
document.Models.CollectionChanged -= OnModelsCollectionChanged;
}
_modelsCollectionEventSubscribed = false;
LogManager.Info("[ModelSettingsViewModel] 已取消订阅SceneLoaded事件");
LogManager.Info("[ModelSettingsViewModel] 已取消订阅SceneLoaded和CollectionChanged事件");
}
}
catch (Exception ex)
@ -982,8 +987,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
LogManager.Info($"[ModelSettingsViewModel] 场景加载完成,当前模型数量: {modelsCount}");
// 刷新物流模型列表
await RefreshLogisticsModelsAsync();
// 更新上次模型数量
_lastModelsCount = modelsCount;
// 注意:不在 SceneLoaded 事件中直接刷新物流模型列表
// 因为 SceneLoaded 事件可能在模型完全加载之前触发
// 刷新逻辑移到 OnModelsCollectionChanged 中处理
}
catch (Exception ex)
{
@ -991,6 +1000,37 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
/// <summary>
/// 模型集合变化事件处理器 - 用于检测文档加载完成
/// </summary>
private async void OnModelsCollectionChanged(object sender, EventArgs e)
{
// 如果已经释放,直接返回
if (_disposed) return;
try
{
var document = NavisApplication.ActiveDocument;
var currentModelsCount = document?.Models?.Count ?? 0;
// 检测模型数量从 0 变为 >0表示文档已加载完成
if (_lastModelsCount == 0 && currentModelsCount > 0)
{
LogManager.Info($"[ModelSettingsViewModel] 检测到文档加载完成(模型数量: {_lastModelsCount} -> {currentModelsCount}");
// 刷新物流模型列表
await RefreshLogisticsModelsAsync();
}
// 更新上次模型数量
_lastModelsCount = currentModelsCount;
}
catch (Exception ex)
{
LogManager.Error($"[ModelSettingsViewModel] 处理模型集合变化事件异常: {ex.Message}", ex);
}
}
#endregion
#region