重构创建和显示虚拟车辆的功能
This commit is contained in:
parent
075fd5c602
commit
0a2e29cee9
@ -4,7 +4,7 @@
|
||||
|
||||
### [2026/1/6]
|
||||
|
||||
1. [ ] (BUG)虚拟车辆模型每次点击都重建
|
||||
1. [x] (BUG)虚拟车辆模型每次点击都重建
|
||||
2. [x] (BUG)碰撞结果高亮,应该显示clashdetective检测的结果
|
||||
3. [x] (优化)对clashdetective的检测结果,进行向上合并,找到集合对象。
|
||||
4. [x] (功能)碰撞检测结果保存数据库,列表展示
|
||||
|
||||
@ -297,19 +297,15 @@ namespace NavisworksTransport
|
||||
ModelItem vehicleObject = null;
|
||||
if (testInfo.IsVirtualVehicle)
|
||||
{
|
||||
// 创建虚拟车辆
|
||||
vehicleObject = VirtualVehicleManager.Instance.CreateVirtualVehicle(
|
||||
// 显示虚拟车辆
|
||||
VirtualVehicleManager.Instance.ShowVirtualVehicle(
|
||||
testInfo.VirtualVehicleLength,
|
||||
testInfo.VirtualVehicleWidth,
|
||||
testInfo.VirtualVehicleHeight
|
||||
) ?? throw new InvalidOperationException($"[LoadClashDetectiveResultsFromDatabase] 创建虚拟车辆失败");
|
||||
LogManager.Info($"[LoadClashDetectiveResultsFromDatabase] 已创建虚拟车辆: {testInfo.VirtualVehicleLength}×{testInfo.VirtualVehicleWidth}×{testInfo.VirtualVehicleHeight}m");
|
||||
|
||||
// 将虚拟车辆显示出来(确保不被隐藏)
|
||||
var doc = Application.ActiveDocument;
|
||||
var vehicleItems = new ModelItemCollection { vehicleObject };
|
||||
doc.Models.SetHidden(vehicleItems, false);
|
||||
LogManager.Info($"[LoadClashDetectiveResultsFromDatabase] 虚拟车辆已显示");
|
||||
);
|
||||
vehicleObject = VirtualVehicleManager.Instance.CurrentVirtualVehicle
|
||||
?? throw new InvalidOperationException($"[LoadClashDetectiveResultsFromDatabase] 显示虚拟车辆失败");
|
||||
LogManager.Info($"[LoadClashDetectiveResultsFromDatabase] 已显示虚拟车辆: {testInfo.VirtualVehicleLength}×{testInfo.VirtualVehicleWidth}×{testInfo.VirtualVehicleHeight}m");
|
||||
}
|
||||
else if (testInfo.VehicleModelIndex.HasValue && !string.IsNullOrEmpty(testInfo.VehiclePathId))
|
||||
{
|
||||
|
||||
@ -626,6 +626,17 @@ namespace NavisworksTransport
|
||||
LogManager.Warning($"[文档管理] 清理Idle事件管理器时出现警告: {ex.Message}");
|
||||
}
|
||||
|
||||
// 清理虚拟车辆
|
||||
try
|
||||
{
|
||||
VirtualVehicleManager.Instance.Cleanup();
|
||||
LogManager.Info("[文档管理] 已清理虚拟车辆");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Warning($"[文档管理] 清理虚拟车辆时出现警告: {ex.Message}");
|
||||
}
|
||||
|
||||
// 清除临时材质
|
||||
try
|
||||
{
|
||||
|
||||
@ -56,81 +56,177 @@ namespace NavisworksTransport.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建虚拟车辆立方体
|
||||
/// 显示虚拟车辆
|
||||
/// </summary>
|
||||
/// <param name="lengthMeters">长度(米)- X方向</param>
|
||||
/// <param name="widthMeters">宽度(米)- Y方向</param>
|
||||
/// <param name="heightMeters">高度(米)- Z方向</param>
|
||||
/// <returns>创建的ModelItem</returns>
|
||||
public ModelItem CreateVirtualVehicle(double lengthMeters, double widthMeters, double heightMeters)
|
||||
/// <param name="lengthMeters">长度(米)</param>
|
||||
/// <param name="widthMeters">宽度(米)</param>
|
||||
/// <param name="heightMeters">高度(米)</param>
|
||||
public void ShowVirtualVehicle(double lengthMeters, double widthMeters, double heightMeters)
|
||||
{
|
||||
try
|
||||
{
|
||||
LogManager.Info($"=== 创建虚拟车辆 ===");
|
||||
LogManager.Info($"目标尺寸: {lengthMeters:F2}m × {widthMeters:F2}m × {heightMeters:F2}m");
|
||||
|
||||
// 1. 清理之前的虚拟车辆
|
||||
RemoveVirtualVehicle();
|
||||
|
||||
// 2. 获取单位立方体文件路径
|
||||
var unitCubePath = GetUnitCubeFilePath();
|
||||
if (string.IsNullOrEmpty(unitCubePath) || !File.Exists(unitCubePath))
|
||||
{
|
||||
throw new FileNotFoundException($"找不到单位立方体文件: {unitCubePath}");
|
||||
}
|
||||
|
||||
LogManager.Info($"单位立方体文件: {unitCubePath}");
|
||||
|
||||
// 3. 记录追加前的模型数量
|
||||
var doc = Application.ActiveDocument;
|
||||
int modelCountBefore = doc.Models.Count;
|
||||
LogManager.Info($"追加前模型数量: {modelCountBefore}");
|
||||
|
||||
// 4. 追加单位立方体文件
|
||||
if (!doc.TryAppendFile(unitCubePath))
|
||||
// 检查虚拟车辆模型是否已存在
|
||||
if (_virtualVehicleModel != null)
|
||||
{
|
||||
throw new InvalidOperationException($"无法追加文件: {unitCubePath}");
|
||||
int currentIndex = doc.Models.IndexOf(_virtualVehicleModel);
|
||||
if (currentIndex >= 0)
|
||||
{
|
||||
// 模型存在,显示它并更新尺寸
|
||||
LogManager.Info($"虚拟车辆模型已存在(索引: {currentIndex}),显示并更新尺寸");
|
||||
|
||||
var modelItems = new ModelItemCollection { _virtualVehicleModelItem };
|
||||
doc.Models.SetHidden(modelItems, false);
|
||||
|
||||
// 获取实际的几何体项
|
||||
_virtualVehicleModelItem = _virtualVehicleModel.RootItem;
|
||||
var geometryItem = FindFirstGeometryItem(_virtualVehicleModelItem);
|
||||
if (geometryItem != null && !geometryItem.Equals(_virtualVehicleModelItem))
|
||||
{
|
||||
_virtualVehicleModelItem = geometryItem;
|
||||
}
|
||||
|
||||
// 重置变换并缩放到目标尺寸
|
||||
ResetVirtualVehicleTransform();
|
||||
ScaleVirtualVehicle(lengthMeters, widthMeters, heightMeters);
|
||||
|
||||
_isVirtualVehicleActive = true;
|
||||
LogManager.Info($"虚拟车辆更新成功");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Warning($"已保存的虚拟车辆模型不在文档中,需要重新创建");
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 获取新追加的模型
|
||||
int modelCountAfter = doc.Models.Count;
|
||||
LogManager.Info($"追加后模型数量: {modelCountAfter}");
|
||||
|
||||
if (modelCountAfter <= modelCountBefore)
|
||||
{
|
||||
throw new InvalidOperationException("追加文件后模型数量未增加");
|
||||
}
|
||||
|
||||
_virtualVehicleModel = doc.Models.Last();
|
||||
_virtualVehicleModelItem = _virtualVehicleModel.RootItem;
|
||||
|
||||
LogManager.Info($"虚拟车辆模型: {_virtualVehicleModel.FileName}");
|
||||
LogManager.Info($"虚拟车辆根项: {_virtualVehicleModelItem.DisplayName}");
|
||||
|
||||
// 6. 获取实际的几何体项(可能在子节点中)
|
||||
var geometryItem = FindFirstGeometryItem(_virtualVehicleModelItem);
|
||||
if (geometryItem != null && !geometryItem.Equals(_virtualVehicleModelItem))
|
||||
{
|
||||
LogManager.Info($"找到几何体项: {geometryItem.DisplayName}");
|
||||
_virtualVehicleModelItem = geometryItem;
|
||||
}
|
||||
|
||||
// 7. 缩放到目标尺寸
|
||||
ScaleVirtualVehicle(lengthMeters, widthMeters, heightMeters);
|
||||
|
||||
_isVirtualVehicleActive = true;
|
||||
|
||||
LogManager.Info($"虚拟车辆创建成功");
|
||||
return _virtualVehicleModelItem;
|
||||
// 模型不存在,创建新的
|
||||
CreateVirtualVehicleInternal(doc, lengthMeters, widthMeters, heightMeters);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"创建虚拟车辆失败: {ex.Message}", ex);
|
||||
RemoveVirtualVehicle();
|
||||
throw;
|
||||
LogManager.Error($"显示虚拟车辆失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 隐藏虚拟车辆
|
||||
/// </summary>
|
||||
public void HideVirtualVehicle()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_virtualVehicleModelItem != null)
|
||||
{
|
||||
var doc = Application.ActiveDocument;
|
||||
var modelItems = new ModelItemCollection { _virtualVehicleModelItem };
|
||||
doc.Models.SetHidden(modelItems, true);
|
||||
|
||||
LogManager.Info($"已隐藏虚拟车辆模型");
|
||||
}
|
||||
|
||||
// 隐藏时设置为非激活状态,但保留模型引用
|
||||
_isVirtualVehicleActive = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"隐藏虚拟车辆失败: {ex.Message}");
|
||||
_isVirtualVehicleActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建虚拟车辆(内部方法)
|
||||
/// </summary>
|
||||
private void CreateVirtualVehicleInternal(Document doc, double lengthMeters, double widthMeters, double heightMeters)
|
||||
{
|
||||
LogManager.Info($"=== 创建虚拟车辆 ===");
|
||||
LogManager.Info($"目标尺寸: {lengthMeters:F2}m × {widthMeters:F2}m × {heightMeters:F2}m");
|
||||
|
||||
// 加载新的虚拟车辆模型
|
||||
LoadNewVirtualVehicleModel(doc);
|
||||
|
||||
// 获取实际的几何体项
|
||||
_virtualVehicleModelItem = _virtualVehicleModel.RootItem;
|
||||
var geometryItem = FindFirstGeometryItem(_virtualVehicleModelItem);
|
||||
if (geometryItem != null && !geometryItem.Equals(_virtualVehicleModelItem))
|
||||
{
|
||||
_virtualVehicleModelItem = geometryItem;
|
||||
}
|
||||
|
||||
// 重置变换并缩放到目标尺寸
|
||||
ResetVirtualVehicleTransform();
|
||||
ScaleVirtualVehicle(lengthMeters, widthMeters, heightMeters);
|
||||
|
||||
// 设置状态
|
||||
_isVirtualVehicleActive = true;
|
||||
|
||||
LogManager.Info($"虚拟车辆创建成功");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载新的虚拟车辆模型
|
||||
/// </summary>
|
||||
private void LoadNewVirtualVehicleModel(Document doc)
|
||||
{
|
||||
LogManager.Info($"需要加载新的虚拟车辆模型");
|
||||
|
||||
// 1. 获取单位立方体文件路径
|
||||
var unitCubePath = GetUnitCubeFilePath();
|
||||
if (string.IsNullOrEmpty(unitCubePath) || !File.Exists(unitCubePath))
|
||||
{
|
||||
throw new FileNotFoundException($"找不到单位立方体文件: {unitCubePath}");
|
||||
}
|
||||
|
||||
LogManager.Info($"单位立方体文件: {unitCubePath}");
|
||||
|
||||
// 2. 记录追加前的模型数量
|
||||
int modelCountBefore = doc.Models.Count;
|
||||
LogManager.Info($"追加前模型数量: {modelCountBefore}");
|
||||
|
||||
// 3. 追加单位立方体文件
|
||||
if (!doc.TryAppendFile(unitCubePath))
|
||||
{
|
||||
throw new InvalidOperationException($"无法追加文件: {unitCubePath}");
|
||||
}
|
||||
|
||||
// 4. 验证并获取新追加的模型
|
||||
int modelCountAfter = doc.Models.Count;
|
||||
LogManager.Info($"追加后模型数量: {modelCountAfter}");
|
||||
|
||||
if (modelCountAfter <= modelCountBefore)
|
||||
{
|
||||
throw new InvalidOperationException("追加文件后模型数量未增加");
|
||||
}
|
||||
|
||||
// 保存模型引用(最后一个模型就是刚追加的)
|
||||
_virtualVehicleModel = doc.Models.Last();
|
||||
|
||||
LogManager.Info($"虚拟车辆模型: {_virtualVehicleModel.FileName}");
|
||||
LogManager.Info($"虚拟车辆根项: {_virtualVehicleModel.RootItem.DisplayName}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置虚拟车辆变换为单位矩阵
|
||||
/// </summary>
|
||||
private void ResetVirtualVehicleTransform()
|
||||
{
|
||||
if (_virtualVehicleModel == null) return;
|
||||
|
||||
var doc = Application.ActiveDocument;
|
||||
|
||||
// 创建单位变换矩阵
|
||||
Transform3D identityTransform = new Transform3D();
|
||||
Transform3DComponents identityComponents = identityTransform.Factor();
|
||||
|
||||
// 应用单位变换
|
||||
Units currentUnits = _virtualVehicleModel.Units;
|
||||
doc.Models.SetModelUnitsAndTransform(_virtualVehicleModel, currentUnits, identityTransform, false);
|
||||
|
||||
LogManager.Info("已重置虚拟车辆变换");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缩放虚拟车辆到目标尺寸
|
||||
/// 使用DocumentModels.SetModelUnitsAndTransform方法进行模型级缩放
|
||||
@ -208,31 +304,47 @@ namespace NavisworksTransport.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除虚拟车辆(隐藏模型,因为Navisworks API不支持直接删除追加的模型)
|
||||
/// 移除虚拟车辆(使用 TryRemoveFile 真正删除模型)
|
||||
/// </summary>
|
||||
public void RemoveVirtualVehicle()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_virtualVehicleModelItem != null)
|
||||
var doc = Application.ActiveDocument;
|
||||
|
||||
if (_virtualVehicleModel != null)
|
||||
{
|
||||
// Navisworks API不支持直接删除追加的模型
|
||||
// 使用隐藏方式处理
|
||||
var doc = Application.ActiveDocument;
|
||||
var modelItems = new ModelItemCollection { _virtualVehicleModelItem };
|
||||
doc.Models.SetHidden(modelItems, true);
|
||||
|
||||
LogManager.Info($"已隐藏虚拟车辆模型");
|
||||
// 动态查找模型索引
|
||||
int currentIndex = doc.Models.IndexOf(_virtualVehicleModel);
|
||||
|
||||
if (currentIndex >= 0)
|
||||
{
|
||||
// 使用 TryRemoveFile 真正删除模型
|
||||
bool removed = doc.TryRemoveFile(currentIndex);
|
||||
|
||||
if (removed)
|
||||
{
|
||||
LogManager.Info($"已删除虚拟车辆模型(索引: {currentIndex})");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Warning($"删除虚拟车辆模型失败(索引: {currentIndex})");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Warning($"虚拟车辆模型不在文档中,无法删除");
|
||||
}
|
||||
}
|
||||
|
||||
// 清理引用但不尝试删除模型
|
||||
// 清理引用
|
||||
_virtualVehicleModel = null;
|
||||
_virtualVehicleModelItem = null;
|
||||
_isVirtualVehicleActive = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"隐藏虚拟车辆失败: {ex.Message}");
|
||||
LogManager.Error($"删除虚拟车辆失败: {ex.Message}");
|
||||
_virtualVehicleModel = null;
|
||||
_virtualVehicleModelItem = null;
|
||||
_isVirtualVehicleActive = false;
|
||||
|
||||
@ -481,18 +481,16 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
LogManager.Info("已切换到虚拟车辆模式,将之前的手动选择物体归位并清理动画数据");
|
||||
}
|
||||
|
||||
// ✨ 统一逻辑:启用虚拟车辆时立即创建并对齐到起点
|
||||
if (VirtualVehicleManager.Instance.IsVirtualVehicleActive == false)
|
||||
{
|
||||
LogManager.Info("正在创建并初始化虚拟车辆到起点...");
|
||||
var vModel = VirtualVehicleManager.Instance.CreateVirtualVehicle(
|
||||
VirtualVehicleLength, VirtualVehicleWidth, VirtualVehicleHeight);
|
||||
// 显示虚拟车辆,并同步到起点
|
||||
LogManager.Info("正在显示虚拟车辆到起点...");
|
||||
VirtualVehicleManager.Instance.ShowVirtualVehicle(
|
||||
VirtualVehicleLength, VirtualVehicleWidth, VirtualVehicleHeight);
|
||||
|
||||
if (vModel != null && CurrentPathRoute != null && CurrentPathRoute.Points != null)
|
||||
{
|
||||
var points = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList();
|
||||
_pathAnimationManager?.SyncToPathStart(vModel, points);
|
||||
}
|
||||
var vModel = VirtualVehicleManager.Instance.CurrentVirtualVehicle;
|
||||
if (vModel != null && CurrentPathRoute != null && CurrentPathRoute.Points != null)
|
||||
{
|
||||
var points = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList();
|
||||
_pathAnimationManager?.SyncToPathStart(vModel, points);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -502,10 +500,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
// ✨ 模式切换清理:切换到手动选择模式时,移除存在的虚拟车辆并清理数据
|
||||
// ✨ 模式切换清理:切换到手动选择模式时,隐藏虚拟车辆并清理数据
|
||||
try
|
||||
{
|
||||
VirtualVehicleManager.Instance.RemoveVirtualVehicle();
|
||||
// 不删除虚拟车辆,只隐藏它
|
||||
VirtualVehicleManager.Instance.HideVirtualVehicle();
|
||||
_pathAnimationManager?.ClearAnimationResults(); // 清理虚拟车辆留下的动画数据
|
||||
LogManager.Info("已切换到手动选择模式,自动隐藏虚拟车辆并清理动画数据");
|
||||
}
|
||||
@ -2133,20 +2132,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
if (animatedObject == null)
|
||||
{
|
||||
LogManager.Info("[ExecuteGenerateAnimation] 虚拟车辆不存在,正在创建...");
|
||||
UpdateMainStatus("正在创建虚拟车辆...", -1, true);
|
||||
LogManager.Info("[ExecuteGenerateAnimation] 虚拟车辆不存在,正在显示...");
|
||||
UpdateMainStatus("正在显示虚拟车辆...", -1, true);
|
||||
|
||||
animatedObject = Core.VirtualVehicleManager.Instance.CreateVirtualVehicle(
|
||||
VirtualVehicleManager.Instance.ShowVirtualVehicle(
|
||||
VirtualVehicleLength,
|
||||
VirtualVehicleWidth,
|
||||
VirtualVehicleHeight
|
||||
);
|
||||
animatedObject = VirtualVehicleManager.Instance.CurrentVirtualVehicle;
|
||||
}
|
||||
|
||||
if (animatedObject == null)
|
||||
{
|
||||
LogManager.Error("[动画生成] 虚拟车辆创建失败");
|
||||
UpdateMainStatus("生成失败:无法创建虚拟车辆");
|
||||
LogManager.Error("[动画生成] 虚拟车辆显示失败");
|
||||
UpdateMainStatus("生成失败:无法显示虚拟车辆");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user