优化通行空间参数设置,统一使用模型单位,调整日志输出格式

This commit is contained in:
tian 2026-01-21 15:01:13 +08:00
parent 131dfba768
commit 91c8f5c6f7
3 changed files with 108 additions and 65 deletions

View File

@ -1612,6 +1612,69 @@ namespace NavisworksTransport
var adjustedStartPoint = new Point3D(startPoint.Position.X, startPoint.Position.Y, startPoint.Position.Z + verticalOffset);
var adjustedEndPoint = new Point3D(endPoint.Position.X, endPoint.Position.Y, endPoint.Position.Z + verticalOffset);
// 暂时注释掉起点终点调整,先观察原始通行空间的误差
/*
// 通行空间模式下,调整起点和终点以包裹车辆
if (_visualizationMode == PathVisualizationMode.VehicleSpace)
{
bool needAdjust = false;
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Ground)
{
needAdjust = true;
}
else if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Aerial &&
visualization.PathRoute.AerialSubType == AerialSubType.Rail)
{
needAdjust = true;
}
if (needAdjust)
{
// 调整起点:沿起点→第二个点的方向后退半个车辆长度
if (i == 0 && sortedPoints.Count >= 2)
{
var nextPoint = sortedPoints[1];
var dx = nextPoint.Position.X - startPoint.Position.X;
var dy = nextPoint.Position.Y - startPoint.Position.Y;
var dz = nextPoint.Position.Z - startPoint.Position.Z;
var length = Math.Sqrt(dx * dx + dy * dy + dz * dz);
LogManager.Info($"[通行空间调整] 起点: 原点=({startPoint.Position.X:F3},{startPoint.Position.Y:F3},{startPoint.Position.Z:F3}), 方向=({dx:F3},{dy:F3},{dz:F3}), 长度={length:F3}, _passageAlongPath={_passageAlongPath:F3}");
if (length > 0.001)
{
var offset = _passageAlongPath / 2.0;
adjustedStartPoint = new Point3D(
startPoint.Position.X - dx / length * offset,
startPoint.Position.Y - dy / length * offset,
startPoint.Position.Z - dz / length * offset + verticalOffset
);
LogManager.Info($"[通行空间调整] 调整后起点=({adjustedStartPoint.X:F3},{adjustedStartPoint.Y:F3},{adjustedStartPoint.Z:F3})");
}
}
// 调整终点:沿倒数第二个点→终点的方向前进半个车辆长度
if (i == sortedPoints.Count - 2 && sortedPoints.Count >= 2)
{
var prevPoint = sortedPoints[i];
var dx = endPoint.Position.X - prevPoint.Position.X;
var dy = endPoint.Position.Y - prevPoint.Position.Y;
var dz = endPoint.Position.Z - prevPoint.Position.Z;
var length = Math.Sqrt(dx * dx + dy * dy + dz * dz);
LogManager.Info($"[通行空间调整] 终点: 原点=({endPoint.Position.X:F3},{endPoint.Position.Y:F3},{endPoint.Position.Z:F3}), 方向=({dx:F3},{dy:F3},{dz:F3}), 长度={length:F3}, _passageAlongPath={_passageAlongPath:F3}");
if (length > 0.001)
{
var offset = _passageAlongPath / 2.0;
adjustedEndPoint = new Point3D(
endPoint.Position.X + dx / length * offset,
endPoint.Position.Y + dy / length * offset,
endPoint.Position.Z + dz / length * offset + verticalOffset
);
LogManager.Info($"[通行空间调整] 调整后终点=({adjustedEndPoint.X:F3},{adjustedEndPoint.Y:F3},{adjustedEndPoint.Z:F3})");
}
}
}
}
*/
var lineMarker = new LineMarker
{
StartPoint = adjustedStartPoint,
@ -1689,22 +1752,13 @@ namespace NavisworksTransport
/// <returns>车辆通行空间标记</returns>
private VehicleSpaceMarker CreateVehicleSpaceMarker(PathPoint fromPoint, PathPoint toPoint)
{
// 获取单位转换系数
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
// 计算车辆通行空间垂直于路径方向的尺寸(米)
double vehicleInflationAcrossPathInMeters = _passageAcrossPath;
// 计算车辆通行空间法线方向的尺寸(米)
double vehicleSpaceNormalToPathInMeters = _passageNormalToPath;
var style = GetRenderStyle(RenderStyleName.VehicleSpace);
return new VehicleSpaceMarker
{
StartPoint = fromPoint.Position,
EndPoint = toPoint.Position,
Width = vehicleInflationAcrossPathInMeters * metersToModelUnits, // 转换为模型单位
Height = vehicleSpaceNormalToPathInMeters * metersToModelUnits, // 转换为模型单位
Width = _passageAcrossPath, // 直接使用模型单位
Height = _passageNormalToPath, // 直接使用模型单位
Color = style.Color, // 车辆通行空间颜色
Alpha = style.Alpha, // 透明度,统一管理
FromIndex = fromPoint.Index,
@ -1804,17 +1858,17 @@ namespace NavisworksTransport
/// <param name="vehicleWidth">车辆宽度(米)</param>
/// <param name="vehicleHeight">车辆高度(米)</param>
/// <param name="safetyMargin">安全间隙(米)</param>
/// <param name="passageNormalToPathVertical">垂直段的高度(物体长度 + 2×安全间隙</param>
/// <param name="passageNormalToPathHorizontal">水平段的高度(物体高度 + 2×安全间隙</param>
public void SetPassageSpaceParameters(double passageAcrossPath, double passageNormalToPath, double passageAlongPath,double passageNormalToPathVertical = 0, double passageNormalToPathHorizontal = 0)
/// <param name="passageNormalToPathVertical">垂直段的高度(物体长度 + 2×安全间隙模型单位</param>
/// <param name="passageNormalToPathHorizontal">水平段的高度(物体高度 + 2×安全间隙模型单位</param>
public void SetPassageSpaceParameters(double passageAcrossPath, double passageNormalToPath, double passageAlongPath, double passageNormalToPathVertical = 0, double passageNormalToPathHorizontal = 0)
{
_passageAlongPath = passageAlongPath; // 通行空间沿路径方向的尺寸(已包括安全间隙,暂不使用
_passageAcrossPath = passageAcrossPath; // 通行空间垂直于路径方向的尺寸(已包括安全间隙
_passageNormalToPath = passageNormalToPath; // 通行空间法线方向的尺寸(已包括安全间隙,默认值
_passageAlongPath = passageAlongPath; // 通行空间沿路径方向的尺寸(模型单位
_passageAcrossPath = passageAcrossPath; // 通行空间垂直于路径方向的尺寸(模型单位
_passageNormalToPath = passageNormalToPath; // 通行空间法线方向的尺寸(模型单位
// 保存垂直段和水平段的高度(用于吊装路径分段渲染)
_objectLength = passageNormalToPathVertical; // 垂直段高度
_objectHeight = passageNormalToPathHorizontal; // 水平段高度
_objectLength = passageNormalToPathVertical; // 垂直段高度(模型单位)
_objectHeight = passageNormalToPathHorizontal; // 水平段高度(模型单位)
// 参数改变时刷新所有普通路径因为RibbonLine模式也使用车辆宽度
RefreshNormalPaths();
@ -2475,25 +2529,6 @@ namespace NavisworksTransport
}
}
/// <summary>
/// 渲染车辆通行空间(矩形通道)- 使用Cuboid API简化实现
/// </summary>
/// <param name="graphics">图形上下文</param>
/// <param name="vehicleSpace">车辆通行空间标记</param>
private void RenderVehicleSpace(Graphics graphics, VehicleSpaceMarker vehicleSpace)
{
var style = GetRenderStyle(RenderStyleName.VehicleSpace);
// 设置颜色和透明度
graphics.Color(vehicleSpace.Color, vehicleSpace.Alpha);
RenderCuboidMarker(
graphics,
vehicleSpace.StartPoint,
vehicleSpace.EndPoint,
vehicleSpace.Width,
vehicleSpace.Height
);
}
/// <summary>
/// 渲染长方体标记(指定长度)
/// </summary>

View File

@ -645,6 +645,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
/// <summary>
/// 设置虚拟车辆参数由主ViewModel调用
/// 参数单位:模型单位
/// </summary>
public void SetVirtualVehicleParameters(double length, double width, double height, double safetyMargin)
{
@ -653,7 +654,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
VirtualVehicleHeight = height;
SafetyMargin = safetyMargin;
LogManager.Info($"[AnimationControlViewModel] 虚拟车辆参数已更新: {length:F1}m × {width:F1}m × {height:F1}m, 检测间隙: {safetyMargin:F2}m");
LogManager.Info($"[AnimationControlViewModel] 虚拟车辆参数已更新: {length:F1}模型单位 × {width:F1}模型单位 × {height:F1}模型单位, 检测间隙: {safetyMargin:F2}模型单位");
// 如果当前使用虚拟车辆模式,更新生成动画的可用状态
if (UseVirtualVehicle)
@ -918,20 +919,22 @@ namespace NavisworksTransport.UI.WPF.ViewModels
HasClashDetectiveResults = false;
UpdateMainStatus("碰撞检测就绪");
// 从配置读取碰撞检测参数
DetectionGap = config.Animation.DetectionGapMeters;
AnimationFrameRate = config.Animation.FrameRate;
// 🔥 从配置加载虚拟车辆尺寸(与路径编辑保持一致)
VirtualVehicleLength = config.PathEditing.VehicleLengthMeters;
VirtualVehicleWidth = config.PathEditing.VehicleWidthMeters;
VirtualVehicleHeight = config.PathEditing.VehicleHeightMeters;
// 设置动画按钮的初始状态
UpdateAnimationButtonStates();
LogManager.Info($"动画设置初始化完成 - 帧率:{SelectedFrameRate}fps, 持续时间:{AnimationDuration}秒, 检测间隙:{DetectionGap}米");
}
// 获取单位转换系数
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
// 从配置读取碰撞检测参数(转换为模型单位)
DetectionGap = config.Animation.DetectionGapMeters * metersToModelUnits;
AnimationFrameRate = config.Animation.FrameRate;
// 🔥 从配置加载虚拟车辆尺寸(与路径编辑保持一致,转换为模型单位)
VirtualVehicleLength = config.PathEditing.VehicleLengthMeters * metersToModelUnits;
VirtualVehicleWidth = config.PathEditing.VehicleWidthMeters * metersToModelUnits;
VirtualVehicleHeight = config.PathEditing.VehicleHeightMeters * metersToModelUnits;
// 设置动画按钮的初始状态
UpdateAnimationButtonStates();
LogManager.Info($"动画设置初始化完成 - 帧率:{SelectedFrameRate}fps, 持续时间:{AnimationDuration}秒, 检测间隙:{DetectionGap}模型单位"); }
/// <summary>
/// 初始化命令
@ -2679,7 +2682,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
passageAcrossPath = effectiveWidth + 2 * safetyMargin; // 旋转后宽度 + 2*间隙(垂直于路径方向)
passageNormalToPath = sizeZ + 2 * safetyMargin; // Z方向高度+ 2*间隙(法线方向,上下都加)
passageAlongPath = effectiveLength; // 旋转后长度(沿路径方向)
// 空轨路径不需要分段参数
passageNormalToPathVertical = passageNormalToPath;
passageNormalToPathHorizontal = passageNormalToPath;
LogManager.Info($"[通行空间可视化] 空轨路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): 有效长度={effectiveLength:F2}m, 有效宽度={effectiveWidth:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");

View File

@ -790,14 +790,17 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
var config = ConfigManager.Instance.Current;
// 从 PathEditing 配置加载所有参数
_gridSize = config.PathEditing.CellSizeMeters;
_vehicleLength = config.PathEditing.VehicleLengthMeters;
_vehicleWidth = config.PathEditing.VehicleWidthMeters;
_vehicleHeight = config.PathEditing.VehicleHeightMeters;
_safetyMargin = config.PathEditing.SafetyMarginMeters;
// 获取单位转换系数
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
LogManager.Info($"从配置加载参数 - 车辆: {_vehicleLength:F1}x{_vehicleWidth:F1}x{_vehicleHeight:F1}米, 安全间隙: {_safetyMargin:F2}米, 网格: {_gridSize:F1}米");
// 从 PathEditing 配置加载所有参数(转换为模型单位)
_gridSize = config.PathEditing.CellSizeMeters * metersToModelUnits;
_vehicleLength = config.PathEditing.VehicleLengthMeters * metersToModelUnits;
_vehicleWidth = config.PathEditing.VehicleWidthMeters * metersToModelUnits;
_vehicleHeight = config.PathEditing.VehicleHeightMeters * metersToModelUnits;
_safetyMargin = config.PathEditing.SafetyMarginMeters * metersToModelUnits;
LogManager.Info($"从配置加载参数 - 车辆: {_vehicleLength:F1}x{_vehicleWidth:F1}x{_vehicleHeight:F1}模型单位, 安全间隙: {_safetyMargin:F2}模型单位, 网格: {_gridSize:F1}模型单位");
}
catch (Exception ex)
{
@ -2758,7 +2761,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (PathPointRenderPlugin.Instance != null)
{
// 根据路径类型计算通行空间尺寸
double passageAcrossPath, passageNormalToPath;
double passageAcrossPath, passageNormalToPath, passageAlongPath;
PathType pathType = SelectedPathRoute?.PathType ?? PathType.Ground;
if (pathType == PathType.Aerial)
@ -2769,18 +2772,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 空轨路径:车辆水平悬挂,垂直于路径的截面包含车辆的宽度和高度
passageAcrossPath = VehicleWidth + 2 * SafetyMargin; // Y方向宽度+ 2*间隙(垂直于路径方向)
passageNormalToPath = VehicleHeight + 2 * SafetyMargin; // Z方向高度+ 2*间隙(法线方向)
passageAlongPath = VehicleLength; // X方向长度沿路径方向
}
else if (SelectedPathRoute?.AerialSubType == AerialSubType.ThreeStepHoisting)
{
// 吊装路径:车辆垂直悬挂,垂直于路径的截面包含车辆的长度和宽度
passageAcrossPath = VehicleWidth + 2 * SafetyMargin; // Y方向宽度+ 2*间隙(垂直于路径方向)
passageNormalToPath = VehicleLength + 2 * SafetyMargin; // X方向长度+ 2*间隙(法线方向)
passageAlongPath = VehicleHeight; // Z方向高度沿路径方向
}
else
{
// 默认:使用宽度和高度
passageAcrossPath = VehicleWidth + 2 * SafetyMargin;
passageNormalToPath = VehicleHeight + 2 * SafetyMargin;
passageAlongPath = VehicleLength;
}
}
else // Ground
@ -2788,10 +2794,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 地面路径:高度只有上方加间隙
passageAcrossPath = VehicleWidth + 2 * SafetyMargin; // Y方向宽度+ 2*间隙(垂直于路径方向)
passageNormalToPath = VehicleHeight + SafetyMargin; // Z方向高度+ 间隙(法线方向,只有上方)
passageAlongPath = VehicleLength; // X方向长度沿路径方向
}
// 设置通行空间参数到渲染插件
// passageAlongPath: 沿路径方向的尺寸(由路径长度决定,不需要设置)
// passageNormalToPathVertical: 垂直段的高度(物体长度 + 2×安全间隙
// passageNormalToPathHorizontal: 水平段的高度(物体高度 + 2×安全间隙
double passageNormalToPathVertical = VehicleLength + 2 * SafetyMargin;
@ -2799,10 +2805,10 @@ namespace NavisworksTransport.UI.WPF.ViewModels
PathPointRenderPlugin.Instance.SetPassageSpaceParameters(
passageAcrossPath,
passageNormalToPath,
0,
passageAlongPath,
passageNormalToPathVertical,
passageNormalToPathHorizontal);
LogManager.Debug($"[车辆参数同步] 已设置通行空间参数: 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m, 间隙={SafetyMargin:F2}m");
LogManager.Debug($"[车辆参数同步] 已设置通行空间参数: 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m, 沿路径={passageAlongPath:F2}m, 间隙={SafetyMargin:F2}m");
}
else
{