修正存储单位错误,规范单位使用

This commit is contained in:
tian 2026-02-18 16:10:36 +08:00
parent 9751287884
commit 7da2ddf230
4 changed files with 138 additions and 121 deletions

View File

@ -90,9 +90,9 @@ namespace NavisworksTransport.Core.Animation
private static readonly Dictionary<string, List<CollisionResult>> _collisionResultCache = new Dictionary<string, List<CollisionResult>>(); // 碰撞结果缓存
private ModelItem _animatedObject;
private bool _isVirtualObject = false; // 是否使用虚拟物体
private double _virtualObjectLength = 0; // 虚拟物体长度(
private double _virtualObjectWidth = 0; // 虚拟物体宽度(
private double _virtualObjectHeight = 0; // 虚拟物体高度(
private double _virtualObjectLength = 0; // 虚拟物体长度(模型单位
private double _virtualObjectWidth = 0; // 虚拟物体宽度(模型单位
private double _virtualObjectHeight = 0; // 虚拟物体高度(模型单位
private List<Point3D> _pathPoints;
private List<ModelItem> _manualCollisionTargets = new List<ModelItem>();
private bool _manualCollisionOverrideEnabled = false;
@ -444,13 +444,14 @@ namespace NavisworksTransport.Core.Animation
/// <summary>
/// 设置虚拟物体参数(批处理专用)
/// 参数使用模型单位与Navisworks API一致
/// </summary>
public void SetVirtualObjectParameters(bool isVirtualObject, double length, double width, double height)
{
_isVirtualObject = isVirtualObject;
_virtualObjectLength = length;
_virtualObjectWidth = width;
_virtualObjectHeight = height;
_virtualObjectLength = length; // 模型单位
_virtualObjectWidth = width; // 模型单位
_virtualObjectHeight = height; // 模型单位
}
/// <summary>

View File

@ -2104,26 +2104,24 @@ namespace NavisworksTransport
/// <summary>
/// 设置物体参数从PathPlanningManager同步
/// </summary>
/// <param name="objectLength">物体长度(米)</param>
/// <param name="objectWidth">物体宽度(米)</param>
/// <param name="objectHeight">物体高度(米)</param>
/// <param name="safetyMargin">安全间隙(米)</param>
/// <summary>
/// 设置通行空间参数 - 外部传入模型单位,内部直接使用
/// </summary>
/// <param name="passageAcrossPath">垂直于路径方向的通行空间尺寸(模型单位)</param>
/// <param name="passageNormalToPath">法线方向的通行空间尺寸(模型单位)</param>
/// <param name="passageAlongPath">沿路径方向的通行空间尺寸(模型单位)</param>
/// <param name="passageNormalToPathVertical">垂直段的高度(物体长度 + 2×安全间隙模型单位</param>
/// <param name="passageNormalToPathHorizontal">水平段的高度(物体高度 + 2×安全间隙模型单位</param>
/// <summary>
/// 设置通行空间参数 - 外部传入米制单位,内部存储为模型单位
/// </summary>
public void SetPassageSpaceParameters(double passageAcrossPathInMeters, double passageNormalToPathInMeters, double passageAlongPathInMeters, double passageNormalToPathVerticalInMeters = 0, double passageNormalToPathHorizontalInMeters = 0)
public void SetPassageSpaceParameters(double passageAcrossPath, double passageNormalToPath, double passageAlongPath, double passageNormalToPathVertical, double passageNormalToPathHorizontal)
{
// 转换为模型单位存储
double factor = UnitsConverter.GetMetersToUnitsConversionFactor();
_passageAlongPath = passageAlongPathInMeters * factor;
_passageAcrossPath = passageAcrossPathInMeters * factor;
_passageNormalToPath = passageNormalToPathInMeters * factor;
// 直接存储模型单位(调用方已转换)
_passageAlongPath = passageAlongPath;
_passageAcrossPath = passageAcrossPath;
_passageNormalToPath = passageNormalToPath;
// 保存垂直段和水平段的高度(用于吊装路径分段渲染)
_objectLength = passageNormalToPathVerticalInMeters * factor;
_objectHeight = passageNormalToPathHorizontalInMeters * factor;
_objectLength = passageNormalToPathVertical;
_objectHeight = passageNormalToPathHorizontal;
// 参数改变时刷新所有普通路径因为RibbonLine模式也使用物体宽度
RefreshNormalPaths();

View File

@ -207,9 +207,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
public ModelItem AnimatedObject { get; set; }
// 虚拟物体尺寸当IsVirtualObject=true时使用
public double VirtualObjectLength { get; set; }
public double VirtualObjectWidth { get; set; }
public double VirtualObjectHeight { get; set; }
public double VirtualObjectLengthInMeters { get; set; }
public double VirtualObjectWidthInMeters { get; set; }
public double VirtualObjectHeightInMeters { get; set; }
public string TestTimeDisplay => Record.TestTime.ToString("MM-dd HH:mm:ss");
public string CollisionCountDisplay => $"{Record.CollisionCount}个";
@ -332,10 +332,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 虚拟物体相关字段
private bool _useVirtualObject = false; // 使用虚拟物体
private double _virtualObjectLength; // 虚拟物体长度(米)
private double _virtualObjectWidth; // 虚拟物体宽度(米)
private double _virtualObjectHeight; // 虚拟物体高度(米)
private double _safetyMargin; // 检测间隙(米),从路径编辑同步
private double _virtualObjectLengthInMeters; // 虚拟物体长度(米)
private double _virtualObjectWidthInMeters; // 虚拟物体宽度(米)
private double _virtualObjectHeightInMeters; // 虚拟物体高度(米)
private double _safetyMarginInMeters; // 检测间隙(米),从路径编辑同步
// 角度修正相关字段
private double _objectRotationCorrection; // 物体角度修正值(度,顺时针)
@ -673,7 +673,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 显示虚拟物体
LogManager.Info("正在显示虚拟物体...");
VirtualObjectManager.Instance.ShowVirtualObject(
VirtualObjectLength, VirtualObjectWidth, VirtualObjectHeight);
VirtualObjectLengthInMeters, VirtualObjectWidthInMeters, VirtualObjectHeightInMeters);
// 重置角度修正值(虚拟物体重新选择时重置)
ObjectRotationCorrection = 0.0;
@ -702,7 +702,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (_pathAnimationManager != null &&
VirtualObjectManager.Instance.IsVirtualObjectActive)
{
_pathAnimationManager.SetVirtualObjectParameters(true, VirtualObjectLength, VirtualObjectWidth, VirtualObjectHeight);
var metersToUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
_pathAnimationManager.SetVirtualObjectParameters(true,
VirtualObjectLengthInMeters * metersToUnits,
VirtualObjectWidthInMeters * metersToUnits,
VirtualObjectHeightInMeters * metersToUnits);
_pathAnimationManager.RestoreObjectToCADPosition();
LogManager.Info("已切换到手动选择模式,虚拟物体已归位");
}
@ -731,28 +735,28 @@ namespace NavisworksTransport.UI.WPF.ViewModels
/// <summary>
/// 虚拟物体长度(米)- 只读,从路径编辑同步
/// </summary>
public double VirtualObjectLength
public double VirtualObjectLengthInMeters
{
get => _virtualObjectLength;
private set => SetProperty(ref _virtualObjectLength, value);
get => _virtualObjectLengthInMeters;
private set => SetProperty(ref _virtualObjectLengthInMeters, value);
}
/// <summary>
/// 虚拟物体宽度(米)- 只读,从路径编辑同步
/// </summary>
public double VirtualObjectWidth
public double VirtualObjectWidthInMeters
{
get => _virtualObjectWidth;
private set => SetProperty(ref _virtualObjectWidth, value);
get => _virtualObjectWidthInMeters;
private set => SetProperty(ref _virtualObjectWidthInMeters, value);
}
/// <summary>
/// 虚拟物体高度(米)- 只读,从路径编辑同步
/// </summary>
public double VirtualObjectHeight
public double VirtualObjectHeightInMeters
{
get => _virtualObjectHeight;
private set => SetProperty(ref _virtualObjectHeight, value);
get => _virtualObjectHeightInMeters;
private set => SetProperty(ref _virtualObjectHeightInMeters, value);
}
/// <summary>
@ -775,15 +779,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels
/// 设置虚拟物体参数由主ViewModel调用
/// 参数单位:米
/// </summary>
public void SetVirtualObjectParameters(double length, double width, double height, double safetyMargin)
public void SetVirtualObjectParameters(double length, double width, double height, double safetyMarginInMeters)
{
LogManager.Info($"[AnimationControlViewModel] SetVirtualObjectParameters被调用: length={length:F4}, width={width:F4}, height={height:F4}, safetyMargin={safetyMargin:F4}");
VirtualObjectLength = length;
VirtualObjectWidth = width;
VirtualObjectHeight = height;
_safetyMargin = safetyMargin;
LogManager.Info($"[AnimationControlViewModel] SetVirtualObjectParameters被调用: length={length:F4}, width={width:F4}, height={height:F4}, safetyMarginInMeters={safetyMarginInMeters:F4}");
VirtualObjectLengthInMeters = length;
VirtualObjectWidthInMeters = width;
VirtualObjectHeightInMeters = height;
_safetyMarginInMeters = safetyMarginInMeters;
LogManager.Info($"[AnimationControlViewModel] 虚拟物体参数已更新: {length:F1}米 × {width:F1}米 × {height:F1}米, 检测间隙: {safetyMargin:F2}米, _safetyMargin={_safetyMargin:F4}");
LogManager.Info($"[AnimationControlViewModel] 虚拟物体参数已更新: {length:F1}米 × {width:F1}米 × {height:F1}米, 检测间隙: {safetyMarginInMeters:F2}米, _safetyMarginInMeters={_safetyMarginInMeters:F4}");
// 如果当前使用虚拟物体模式,更新生成动画的可用状态
if (UseVirtualObject)
@ -1103,21 +1107,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels
UpdateMainStatus("碰撞检测就绪");
// 从配置读取安全间隙(用于预计算)- 使用米单位接口
_safetyMargin = config.PathEditing.SafetyMarginMeters;
_safetyMarginInMeters = config.PathEditing.SafetyMarginMeters;
AnimationFrameRate = config.Animation.FrameRate;
// 从配置读取检测容差用于ClashDetective- 使用米单位接口用于显示
_detectionTolerance = config.Animation.DetectionToleranceMeters;
// 🔥 从配置加载虚拟物体尺寸(与路径编辑保持一致,使用米单位接口)
VirtualObjectLength = config.PathEditing.ObjectLengthMeters;
VirtualObjectWidth = config.PathEditing.ObjectWidthMeters;
VirtualObjectHeight = config.PathEditing.ObjectHeightMeters;
VirtualObjectLengthInMeters = config.PathEditing.ObjectLengthMeters;
VirtualObjectWidthInMeters = config.PathEditing.ObjectWidthMeters;
VirtualObjectHeightInMeters = config.PathEditing.ObjectHeightMeters;
// 设置动画按钮的初始状态
UpdateAnimationButtonStates();
LogManager.Info($"动画设置初始化完成 - 帧率:{SelectedFrameRate}fps, 持续时间:{AnimationDuration}秒, 安全间隙:{_safetyMargin}米");
LogManager.Info($"动画设置初始化完成 - 帧率:{SelectedFrameRate}fps, 持续时间:{AnimationDuration}秒, 安全间隙:{_safetyMarginInMeters}米");
// 订阅配置变更事件
SubscribeToConfigChanges();
@ -1191,12 +1195,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
var config = ConfigManager.Instance.Current;
// 更新物体参数
VirtualObjectLength = config.PathEditing.ObjectLengthMeters;
VirtualObjectWidth = config.PathEditing.ObjectWidthMeters;
VirtualObjectHeight = config.PathEditing.ObjectHeightMeters;
_safetyMargin = config.PathEditing.SafetyMarginMeters;
VirtualObjectLengthInMeters = config.PathEditing.ObjectLengthMeters;
VirtualObjectWidthInMeters = config.PathEditing.ObjectWidthMeters;
VirtualObjectHeightInMeters = config.PathEditing.ObjectHeightMeters;
_safetyMarginInMeters = config.PathEditing.SafetyMarginMeters;
LogManager.Info($"物体参数已更新 - 尺寸:{VirtualObjectLength:F1}x{VirtualObjectWidth:F1}x{VirtualObjectHeight:F1}米, 安全间隙:{_safetyMargin:F2}米");
LogManager.Info($"物体参数已更新 - 尺寸:{VirtualObjectLengthInMeters:F1}x{VirtualObjectWidthInMeters:F1}x{VirtualObjectHeightInMeters:F1}米, 安全间隙:{_safetyMarginInMeters:F2}米");
}
}
catch (Exception ex)
@ -2189,8 +2193,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
return;
}
// 设置虚拟物体参数到动画管理器
_pathAnimationManager?.SetVirtualObjectParameters(true, VirtualObjectLength, VirtualObjectWidth, VirtualObjectHeight);
// 设置虚拟物体参数到动画管理器(转换为模型单位)
var metersToUnitsMove = UnitsConverter.GetMetersToUnitsConversionFactor();
_pathAnimationManager?.SetVirtualObjectParameters(true,
VirtualObjectLengthInMeters * metersToUnitsMove,
VirtualObjectWidthInMeters * metersToUnitsMove,
VirtualObjectHeightInMeters * metersToUnitsMove);
}
else
{
@ -2414,11 +2422,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
double unitsToMeters = UnitsConverter.GetUnitsToMetersConversionFactor(Autodesk.Navisworks.Api.Application.ActiveDocument.Units);
// 创建并显示虚拟物体(尺寸从模型单位转换为米)
animatedObject = VirtualObjectManager.Instance.CreateVirtualObject(
selectedResult.VirtualObjectLength * unitsToMeters,
selectedResult.VirtualObjectWidth * unitsToMeters,
selectedResult.VirtualObjectHeight * unitsToMeters);
selectedResult.VirtualObjectLengthInMeters * unitsToMeters,
selectedResult.VirtualObjectWidthInMeters * unitsToMeters,
selectedResult.VirtualObjectHeightInMeters * unitsToMeters);
selectedResult.AnimatedObject = animatedObject;
LogManager.Info($"[碰撞构件] 创建虚拟物体并聚焦: {selectedResult.VirtualObjectLength:F2}x{selectedResult.VirtualObjectWidth:F2}x{selectedResult.VirtualObjectHeight:F2}");
LogManager.Info($"[碰撞构件] 创建虚拟物体并聚焦: {selectedResult.VirtualObjectLengthInMeters:F2}x{selectedResult.VirtualObjectWidthInMeters:F2}x{selectedResult.VirtualObjectHeightInMeters:F2}");
}
catch (Exception ex)
{
@ -2447,9 +2455,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
double unitsToMeters = UnitsConverter.GetUnitsToMetersConversionFactor(Autodesk.Navisworks.Api.Application.ActiveDocument.Units);
// 显示虚拟物体(如果已存在且尺寸相同,会显示;如果尺寸不同,会更新尺寸)
VirtualObjectManager.Instance.ShowVirtualObject(
selectedResult.VirtualObjectLength * unitsToMeters,
selectedResult.VirtualObjectWidth * unitsToMeters,
selectedResult.VirtualObjectHeight * unitsToMeters);
selectedResult.VirtualObjectLengthInMeters * unitsToMeters,
selectedResult.VirtualObjectWidthInMeters * unitsToMeters,
selectedResult.VirtualObjectHeightInMeters * unitsToMeters);
LogManager.Debug("[碰撞构件] 虚拟物体已确保可见");
}
catch (Exception ex)
@ -3041,12 +3049,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
Description = $"动画生成于 {DateTime.Now:yyyy-MM-dd HH:mm:ss}"
};
// 虚拟物体尺寸
// 虚拟物体尺寸(米 → 模型单位,数据库存储模型单位)
if (UseVirtualObject)
{
record.VirtualObjectLength = VirtualObjectLength;
record.VirtualObjectWidth = VirtualObjectWidth;
record.VirtualObjectHeight = VirtualObjectHeight;
double metersToUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
record.VirtualObjectLength = VirtualObjectLengthInMeters * metersToUnits;
record.VirtualObjectWidth = VirtualObjectWidthInMeters * metersToUnits;
record.VirtualObjectHeight = VirtualObjectHeightInMeters * metersToUnits;
}
// 真实物体信息
else if (SelectedAnimatedObject != null)
@ -3243,9 +3252,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 真实物体尝试解析PathId获取引用
if (record.IsVirtualObject)
{
resultViewModel.VirtualObjectLength = record.VirtualObjectLength;
resultViewModel.VirtualObjectWidth = record.VirtualObjectWidth;
resultViewModel.VirtualObjectHeight = record.VirtualObjectHeight;
resultViewModel.VirtualObjectLengthInMeters = record.VirtualObjectLength;
resultViewModel.VirtualObjectWidthInMeters = record.VirtualObjectWidth;
resultViewModel.VirtualObjectHeightInMeters = record.VirtualObjectHeight;
}
else if (record.ObjectModelIndex.HasValue && !string.IsNullOrEmpty(record.ObjectPathId))
{
@ -3713,9 +3722,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
UpdateMainStatus("正在显示虚拟物体...", -1, true);
VirtualObjectManager.Instance.ShowVirtualObject(
VirtualObjectLength,
VirtualObjectWidth,
VirtualObjectHeight
VirtualObjectLengthInMeters,
VirtualObjectWidthInMeters,
VirtualObjectHeightInMeters
);
animatedObject = VirtualObjectManager.Instance.CurrentVirtualObject;
@ -3767,15 +3776,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 准备物体尺寸参数(从米转换为模型单位)
var metersToModelUnits = Utils.UnitsConverter.GetMetersToUnitsConversionFactor();
double vLength = UseVirtualObject ? VirtualObjectLength * metersToModelUnits : 0;
double vWidth = UseVirtualObject ? VirtualObjectWidth * metersToModelUnits : 0;
double vHeight = UseVirtualObject ? VirtualObjectHeight * metersToModelUnits : 0;
double safetyMargin = _safetyMargin * metersToModelUnits;
double vLength = UseVirtualObject ? VirtualObjectLengthInMeters * metersToModelUnits : 0;
double vWidth = UseVirtualObject ? VirtualObjectWidthInMeters * metersToModelUnits : 0;
double vHeight = UseVirtualObject ? VirtualObjectHeightInMeters * metersToModelUnits : 0;
double safetyMarginInMeters = _safetyMarginInMeters * metersToModelUnits;
LogManager.Info($"[ExecuteGenerateAnimation] 准备调用CreateAnimation: UseVirtualObject={UseVirtualObject}, 物体尺寸: {vLength:F2}×{vWidth:F2}×{vHeight:F2}模型单位, 安全间隙: {safetyMargin:F4}模型单位 (_safetyMargin={_safetyMargin:F4}米)");
LogManager.Info($"[ExecuteGenerateAnimation] 准备调用CreateAnimation: UseVirtualObject={UseVirtualObject}, 物体尺寸: {vLength:F2}×{vWidth:F2}×{vHeight:F2}模型单位, 安全间隙: {safetyMarginInMeters:F4}模型单位 (_safetyMarginInMeters={_safetyMarginInMeters:F4}米)");
_pathAnimationManager.CreateAnimation(animatedObject, pathPoints, AnimationDuration, CurrentPathRoute.Name, CurrentPathRoute.Id, UseVirtualObject,
vLength, vWidth, vHeight, safetyMargin);
vLength, vWidth, vHeight, safetyMarginInMeters);
var totalElapsed = (DateTime.Now - cacheStartTime).TotalMilliseconds;
LogManager.Info($"[动画生成] 动画生成完成,总耗时: {totalElapsed:F1}ms");
@ -3783,7 +3792,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (UseVirtualObject)
{
LogManager.Info($"虚拟物体尺寸: {VirtualObjectLength:F1}×{VirtualObjectWidth:F1}×{VirtualObjectHeight:F1}m");
LogManager.Info($"虚拟物体尺寸: {VirtualObjectLengthInMeters:F1}×{VirtualObjectWidthInMeters:F1}×{VirtualObjectHeightInMeters:F1}m");
}
if (IsManualCollisionTargetEnabled)
@ -3839,28 +3848,34 @@ namespace NavisworksTransport.UI.WPF.ViewModels
/// <summary>
/// 计算旋转后的有效宽度和长度
/// 返回值为模型单位与Navisworks API一致
/// </summary>
/// <returns>(有效宽度, 有效长度)</returns>
/// <returns>(有效宽度, 有效长度) - 模型单位</returns>
private (double effectiveWidth, double effectiveLength) CalculateRotatedDimensions()
{
double baseLength, baseWidth;
double baseLengthMeters, baseWidthMeters;
if (UseVirtualObject)
{
baseLength = VirtualObjectLength;
baseWidth = VirtualObjectWidth;
baseLengthMeters = VirtualObjectLengthInMeters;
baseWidthMeters = VirtualObjectWidthInMeters;
}
else if (SelectedAnimatedObject != null)
{
// 使用保存的原始尺寸,避免物体旋转后包围盒尺寸变化
baseLength = _objectOriginalLength;
baseWidth = _objectOriginalWidth;
// 使用保存的原始尺寸(米),避免物体旋转后包围盒尺寸变化
baseLengthMeters = _objectOriginalLength;
baseWidthMeters = _objectOriginalWidth;
}
else
{
return (0, 0);
}
// 转换为模型单位
var metersToUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
double baseLength = baseLengthMeters * metersToUnits;
double baseWidth = baseWidthMeters * metersToUnits;
// 如果没有角度修正,直接返回原始尺寸
if (_objectRotationCorrection == 0.0)
{
@ -3877,7 +3892,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 旋转后的长度 = |长度*cos| + |宽度*sin|
double effectiveLength = baseLength * cos + baseWidth * sin;
LogManager.Debug($"[角度修正] 旋转后尺寸: 原始({baseLength:F2}×{baseWidth:F2}) -> 有效({effectiveLength:F2}×{effectiveWidth:F2}), 角度={_objectRotationCorrection:F1}°");
LogManager.Debug($"[角度修正] 旋转后尺寸: 原始({baseLengthMeters:F2}m×{baseWidthMeters:F2}m) -> 有效({effectiveLength / metersToUnits:F2}m×{effectiveWidth / metersToUnits:F2}m), 角度={_objectRotationCorrection:F1}°");
return (effectiveWidth, effectiveLength);
}
@ -3906,12 +3921,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels
throw new InvalidOperationException("[通行空间可视化] 无法获取PathPointRenderPlugin实例");
}
// 计算通行空间尺寸(
// 计算通行空间尺寸(模型单位
double passageAcrossPath, passageNormalToPath, passageAlongPath;
double passageNormalToPathVertical, passageNormalToPathHorizontal;
// 使用从路径编辑同步过来的检测间隙
double safetyMargin = _safetyMargin;
// 将安全间隙从米转换为模型单位
var metersToUnitsPassage = UnitsConverter.GetMetersToUnitsConversionFactor();
double safetyMargin = _safetyMarginInMeters * metersToUnitsPassage;
double virtualObjectHeight = VirtualObjectHeightInMeters * metersToUnitsPassage;
if (UseVirtualObject)
{
@ -3920,48 +3937,47 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
// 空中路径(空轨或吊装):高度上下都加间隙
passageAcrossPath = effectiveWidth + 2 * safetyMargin; // 旋转后宽度 + 2*间隙(垂直于路径方向)
passageNormalToPath = VirtualObjectHeight + 2 * safetyMargin; // Z方向高度+ 2*间隙(法线方向)
passageNormalToPath = virtualObjectHeight + 2 * safetyMargin; // Z方向高度+ 2*间隙(法线方向)
passageAlongPath = effectiveLength; // 旋转后长度(沿路径方向)
// 吊装路径分段参数
passageNormalToPathVertical = effectiveLength + 2 * safetyMargin; // 垂直段:物体长度 + 2*间隙
passageNormalToPathHorizontal = VirtualObjectHeight + 2 * safetyMargin; // 水平段:物体高度 + 2*间隙
LogManager.Debug($"[通行空间可视化] 空中路径使用虚拟物体尺寸: 有效长度={effectiveLength:F2}m, 有效宽度={effectiveWidth:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
passageNormalToPathHorizontal = virtualObjectHeight + 2 * safetyMargin; // 水平段:物体高度 + 2*间隙
LogManager.Debug($"[通行空间可视化] 空中路径使用虚拟物体尺寸: 有效长度={effectiveLength / metersToUnitsPassage:F2}m, 有效宽度={effectiveWidth / metersToUnitsPassage:F2}m, 通行空间沿路径={passageAlongPath / metersToUnitsPassage:F2}m, 垂直路径={passageAcrossPath / metersToUnitsPassage:F2}m, 法线={passageNormalToPath / metersToUnitsPassage:F2}m");
}
else if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Ground)
{
// 地面路径物体的长度方向X轴前进方向朝向路径方向
// 通行空间沿路径方向 = X方向尺寸长度垂直于路径方向 = Y方向尺寸宽度高度上方加间隙下方不需要因为有地面
passageAcrossPath = effectiveWidth + 2 * safetyMargin; // 旋转后宽度 + 2*间隙(垂直于路径方向)
passageNormalToPath = VirtualObjectHeight + safetyMargin; // Z方向高度+ 间隙(法线方向,只有上方)
passageNormalToPath = virtualObjectHeight + safetyMargin; // Z方向高度+ 间隙(法线方向,只有上方)
passageAlongPath = effectiveLength; // 旋转后长度(沿路径方向)
// 地面路径不需要分段参数
passageNormalToPathVertical = passageNormalToPath;
passageNormalToPathHorizontal = passageNormalToPath;
LogManager.Debug($"[通行空间可视化] 地面路径使用虚拟物体尺寸: 有效长度={effectiveLength:F2}m, 有效宽度={effectiveWidth:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
LogManager.Debug($"[通行空间可视化] 地面路径使用虚拟物体尺寸: 有效长度={effectiveLength / metersToUnitsPassage:F2}m, 有效宽度={effectiveWidth / metersToUnitsPassage:F2}m, 通行空间沿路径={passageAlongPath / metersToUnitsPassage:F2}m, 垂直路径={passageAcrossPath / metersToUnitsPassage:F2}m, 法线={passageNormalToPath / metersToUnitsPassage:F2}m");
}
else // Rail
{
// 空轨路径物体的长度方向X轴前进方向朝向路径方向
// 通行空间沿路径方向 = X方向尺寸长度垂直于路径方向 = Y方向尺寸宽度高度上下都加间隙在空中
passageAcrossPath = effectiveWidth + 2 * safetyMargin; // 旋转后宽度 + 2*间隙(垂直于路径方向)
passageNormalToPath = VirtualObjectHeight + 2 * safetyMargin; // Z方向高度+ 2*间隙(法线方向,上下都加)
passageNormalToPath = virtualObjectHeight + 2 * safetyMargin; // Z方向高度+ 2*间隙(法线方向,上下都加)
passageAlongPath = effectiveLength; // 旋转后长度(沿路径方向)
// 空轨路径不需要分段参数
passageNormalToPathVertical = passageNormalToPath;
passageNormalToPathHorizontal = passageNormalToPath;
LogManager.Debug($"[通行空间可视化] 空轨路径使用虚拟物体尺寸: 有效长度={effectiveLength:F2}m, 有效宽度={effectiveWidth:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
LogManager.Debug($"[通行空间可视化] 空轨路径使用虚拟物体尺寸: 有效长度={effectiveLength / metersToUnitsPassage:F2}m, 有效宽度={effectiveWidth / metersToUnitsPassage:F2}m, 通行空间沿路径={passageAlongPath / metersToUnitsPassage:F2}m, 垂直路径={passageAcrossPath / metersToUnitsPassage:F2}m, 法线={passageNormalToPath / metersToUnitsPassage:F2}m");
}
}
else if (SelectedAnimatedObject != null)
{
// 使用选择物体的包围盒尺寸
// 使用选择物体的包围盒尺寸(模型单位)
var bbox = SelectedAnimatedObject.BoundingBox();
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
// 将模型单位转换为米
double sizeX = (bbox.Max.X - bbox.Min.X) / metersToModelUnits; // X方向 = 长度(前进方向)
double sizeY = (bbox.Max.Y - bbox.Min.Y) / metersToModelUnits; // Y方向 = 宽度(侧面)
double sizeZ = (bbox.Max.Z - bbox.Min.Z) / metersToModelUnits; // Z方向 = 高度
// 包围盒尺寸已经是模型单位
double sizeX = bbox.Max.X - bbox.Min.X; // X方向 = 长度(前进方向)
double sizeY = bbox.Max.Y - bbox.Min.Y; // Y方向 = 宽度(侧面)
double sizeZ = bbox.Max.Z - bbox.Min.Z; // Z方向 = 高度
// 根据路径类型确定通行空间的尺寸
if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Rail || CurrentPathRoute.PathType == NavisworksTransport.PathType.Hoisting)
@ -3974,7 +3990,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 吊装路径分段参数
passageNormalToPathVertical = effectiveLength + 2 * safetyMargin; // 垂直段:物体长度 + 2*间隙
passageNormalToPathHorizontal = sizeZ + 2 * safetyMargin; // 水平段:物体高度 + 2*间隙
LogManager.Debug($"[通行空间可视化] 空中路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): 有效长度={effectiveLength:F2}m, 有效宽度={effectiveWidth:F2}m, 高度={sizeZ:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
LogManager.Debug($"[通行空间可视化] 空中路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): 有效长度={effectiveLength / metersToUnitsPassage:F2}m, 有效宽度={effectiveWidth / metersToUnitsPassage:F2}m, 高度={sizeZ / metersToUnitsPassage:F2}m, 通行空间沿路径={passageAlongPath / metersToUnitsPassage:F2}m, 垂直路径={passageAcrossPath / metersToUnitsPassage:F2}m, 法线={passageNormalToPath / metersToUnitsPassage:F2}m");
}
else if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Ground)
{
@ -3987,7 +4003,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 地面路径不需要分段参数
passageNormalToPathVertical = passageNormalToPath;
passageNormalToPathHorizontal = passageNormalToPath;
LogManager.Debug($"[通行空间可视化] 地面路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): 有效长度={effectiveLength:F2}m, 有效宽度={effectiveWidth:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
LogManager.Debug($"[通行空间可视化] 地面路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): 有效长度={effectiveLength / metersToUnitsPassage:F2}m, 有效宽度={effectiveWidth / metersToUnitsPassage:F2}m, 通行空间沿路径={passageAlongPath / metersToUnitsPassage:F2}m, 垂直路径={passageAcrossPath / metersToUnitsPassage:F2}m, 法线={passageNormalToPath / metersToUnitsPassage:F2}m");
}
else // Rail
{
@ -3999,7 +4015,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
passageAlongPath = effectiveLength; // 旋转后长度(沿路径方向)
passageNormalToPathVertical = passageNormalToPath;
passageNormalToPathHorizontal = passageNormalToPath;
LogManager.Debug($"[通行空间可视化] 空轨路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): 有效长度={effectiveLength:F2}m, 有效宽度={effectiveWidth:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
LogManager.Debug($"[通行空间可视化] 空轨路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): 有效长度={effectiveLength / metersToUnitsPassage:F2}m, 有效宽度={effectiveWidth / metersToUnitsPassage:F2}m, 通行空间沿路径={passageAlongPath / metersToUnitsPassage:F2}m, 垂直路径={passageAcrossPath / metersToUnitsPassage:F2}m, 法线={passageNormalToPath / metersToUnitsPassage:F2}m");
}
}
else
@ -4008,14 +4024,14 @@ namespace NavisworksTransport.UI.WPF.ViewModels
throw new InvalidOperationException("[通行空间可视化] 配置错误:既不使用虚拟物体也没有选择物体");
}
// 设置通行空间参数到渲染插件(所有路径类型都设置用于RibbonLine宽度等
// 设置通行空间参数到渲染插件(传递模型单位
renderPlugin.SetPassageSpaceParameters(
passageAcrossPath,
passageNormalToPath,
passageAlongPath,
passageNormalToPathVertical,
passageNormalToPathHorizontal);
LogManager.Debug($"[通行空间可视化] 已设置通行空间参数: 沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m, 安全间隙={safetyMargin:F2}m");
LogManager.Debug($"[通行空间可视化] 已设置通行空间参数: 沿路径={passageAlongPath / metersToUnitsPassage:F2}m, 垂直路径={passageAcrossPath / metersToUnitsPassage:F2}m, 法线={passageNormalToPath / metersToUnitsPassage:F2}m, 安全间隙={_safetyMarginInMeters:F2}m");
// 根据路径类型决定是否切换到物体通行空间模式
bool enableObjectSpace = false;
@ -4087,9 +4103,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (UseVirtualObject)
{
// 使用虚拟物体时,只需要有效的物体尺寸
hasValidObject = VirtualObjectLength > 0 &&
VirtualObjectWidth > 0 &&
VirtualObjectHeight > 0;
hasValidObject = VirtualObjectLengthInMeters > 0 &&
VirtualObjectWidthInMeters > 0 &&
VirtualObjectHeightInMeters > 0;
}
else
{
@ -4770,6 +4786,8 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
// 创建批处理队列项
// 注意:虚拟物体尺寸需要从米转换为模型单位存入数据库
double metersToUnitsForQueue = UnitsConverter.GetMetersToUnitsConversionFactor();
var queueItem = new BatchQueueItem
{
RouteId = CurrentPathRoute.Id,
@ -4783,11 +4801,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 碰撞检测配置
DetectionToleranceMeters = _detectionTolerance,
// 运动物体配置
// 运动物体配置(米 → 模型单位,数据库存储模型单位)
IsVirtualObject = UseVirtualObject,
VirtualObjectLength = VirtualObjectLength,
VirtualObjectWidth = VirtualObjectWidth,
VirtualObjectHeight = VirtualObjectHeight,
VirtualObjectLength = VirtualObjectLengthInMeters * metersToUnitsForQueue,
VirtualObjectWidth = VirtualObjectWidthInMeters * metersToUnitsForQueue,
VirtualObjectHeight = VirtualObjectHeightInMeters * metersToUnitsForQueue,
// 被检测项配置
DetectAllObjects = !IsManualCollisionTargetEnabled,

View File

@ -375,11 +375,11 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
Foreground="#FF2B579A"
Background="#FFF5F5F5">
<Run Text="长 "/>
<Run Text="{Binding VirtualObjectLength, StringFormat=F1, Mode=OneWay}"/>
<Run Text="{Binding VirtualObjectLengthInMeters, StringFormat=F1, Mode=OneWay}"/>
<Run Text="m × 宽 "/>
<Run Text="{Binding VirtualObjectWidth, StringFormat=F1, Mode=OneWay}"/>
<Run Text="{Binding VirtualObjectWidthInMeters, StringFormat=F1, Mode=OneWay}"/>
<Run Text="m × 高 "/>
<Run Text="{Binding VirtualObjectHeight, StringFormat=F1, Mode=OneWay}"/>
<Run Text="{Binding VirtualObjectHeightInMeters, StringFormat=F1, Mode=OneWay}"/>
<Run Text="m"/>
</TextBlock>
<Button Grid.Column="2"