优化通行空间可视化功能,自动根据路径类型切换可视化模式,并优化相关渲染逻辑

This commit is contained in:
tian 2026-01-18 16:25:21 +08:00
parent ddf44b887f
commit bc1ad3f4c3
5 changed files with 507 additions and 24 deletions

View File

@ -292,6 +292,32 @@ msiexec /i NavisworksTransport.Setup.msi /qn /l*v install.log
## 开发约定
### 代码分析方法
**重要教训:分析可视化功能时的错误思考方式**
在分析"通行空间可视化"功能时,犯了以下错误:
1. **错误:只看方法名,不看实现**
- 搜索到 `UpdateGridVisualizationSettings()` 等方法名中包含"Grid",就误以为需要生成网格地图
- 实际上这里的"网格"指的是路径规划用的网格地图,而通行空间可视化只是改变路径的渲染风格
2. **错误:没有深入查看渲染代码**
- 虽然找到了 `PathPointRenderPlugin.cs`,但没有仔细看它的渲染逻辑
- 应该先看渲染插件如何渲染路径,发现 `PathVisualizationMode.VehicleSpace` 模式
3. **错误:被表面信息误导**
- 日志显示"[网格可视化] 无缓存网格地图",就以为需要生成网格地图
- 实际上通行空间可视化不是生成新的可视化内容,而是改变现有路径的渲染方式(从圆柱体改为高高度长方体)
**正确的分析方法应该是**
1. **先看渲染代码**:对于可视化功能,应该先看渲染插件的代码(如 `PathPointRenderPlugin.cs`
2. **理解本质**:问自己"这个功能是什么",而不是"怎么做"。通行空间可视化是"改变渲染风格",而不是"生成网格地图"
3. **查看现有实现**:如果日志中已经有相关提示(如"路径可视化模式已更改: 车辆通行空间"),说明功能已经存在,只需要在合适的时机调用
4. **不要只看方法名**:方法名可能误导,要看实际实现代码
5. **深入查看核心代码**:对于可视化、动画等功能,应该先看对应的渲染/动画管理器的代码
### 架构模式
- **MVVM模式**: WPF UI开发使用MVVM架构

View File

@ -9,7 +9,7 @@ cell_size_meters = 0.5
max_height_diff_meters = 0.35
# 车辆长度(米)
vehicle_length_meters = 1.0
vehicle_length_meters = 1.2
# 车辆宽度(米)
vehicle_width_meters = 1.0

View File

@ -1244,7 +1244,7 @@ namespace NavisworksTransport
// 地面路径使用曲线化后的路径Edges
// 空轨路径只显示控制点连线,不显示路径连线
// 吊装路径使用控制点连线,不显示路径连线
// 吊装路径使用控制点连线,不显示路径连线(除非启用通行空间可视化)
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Rail)
{
// 空轨路径:只显示控制点连线,不构建路径连线
@ -1252,8 +1252,17 @@ namespace NavisworksTransport
}
else if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Hoisting)
{
// 吊装路径:只显示控制点连线,不构建路径连线
LogManager.Debug($"[路径渲染] 吊装路径只显示控制点连线,不显示路径连线");
// 吊装路径:默认只显示控制点连线
// 但如果启用了通行空间可视化模式,则构建路径连线以显示通行空间
if (_visualizationMode == PathVisualizationMode.VehicleSpace)
{
LogManager.Debug($"[路径渲染] 吊装路径启用通行空间可视化,构建路径连线");
BuildPathLines(visualization, sortedPoints);
}
else
{
LogManager.Debug($"[路径渲染] 吊装路径只显示控制点连线,不显示路径连线");
}
}
else if (visualization.PathRoute.Edges != null && visualization.PathRoute.Edges.Count > 0)
{
@ -1327,6 +1336,14 @@ namespace NavisworksTransport
{
var edges = visualization.PathRoute.Edges;
// 处理 Edges 为空的情况(如吊装路径未经过曲线化)
if (edges == null || edges.Count == 0)
{
LogManager.Debug($"[路径渲染] Edges 为空,直接使用路径点构建直线连线");
BuildDirectPathLines(visualization, sortedPoints);
return;
}
// 1. 收集在路径上的控制点ID
var onPathPointIds = new HashSet<string>();
foreach (var edge in edges)
@ -1360,8 +1377,21 @@ namespace NavisworksTransport
if (_visualizationMode == PathVisualizationMode.VehicleSpace)
{
// VehicleSpace 模式:使用车辆高度和宽度
heightInMeters = _vehicleHeight + _safetyMargin;
widthInMeters = Math.Max(_vehicleLength, _vehicleWidth) + 2 * _safetyMargin;
// 根据路径类型调整参数
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Hoisting)
{
// 吊装路径:通行空间截面使用车辆的宽度和长度(不是高度)
heightInMeters = _vehicleLength + _safetyMargin; // Y方向使用车辆长度
widthInMeters = _vehicleWidth + 2 * _safetyMargin; // X方向使用车辆宽度
LogManager.Info($"[通行空间渲染] 吊装路径: 车辆参数(长×宽×高)={_vehicleLength:F2}×{_vehicleWidth:F2}×{_vehicleHeight:F2}m, 安全间隙={_safetyMargin:F2}m, 通行空间截面(宽×高)={widthInMeters:F2}×{heightInMeters:F2}m");
}
else
{
// 地面路径和空轨:使用最大宽度和高度
heightInMeters = _vehicleHeight + _safetyMargin;
widthInMeters = _vehicleWidth + 2 * _safetyMargin;
LogManager.Info($"[通行空间渲染] {visualization.PathRoute.PathType}路径: 车辆参数(长×宽×高)={_vehicleLength:F2}×{_vehicleWidth:F2}×{_vehicleHeight:F2}m, 安全间隙={_safetyMargin:F2}m, 通行空间截面(宽×高)={widthInMeters:F2}×{heightInMeters:F2}m");
}
var renderStyle = GetRenderStyle(RenderStyleName.VehicleSpace);
lineColor = renderStyle.Color;
lineOpacity = renderStyle.Alpha;
@ -1389,6 +1419,23 @@ namespace NavisworksTransport
double heightInModelUnits = heightInMeters * metersToModelUnits;
double widthInModelUnits = widthInMeters * metersToModelUnits;
// 计算通行空间的垂直偏移(根据路径类型)
double verticalOffset = 0;
if (_visualizationMode == PathVisualizationMode.VehicleSpace)
{
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Ground)
{
// 地面路径:路径点是地面位置,通行空间底面在地面,中心需要向上偏移半个高度
verticalOffset = heightInModelUnits / 2.0;
}
else if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Rail)
{
// 空轨路径:路径点是空轨下表面位置,通行空间顶面在空轨下表面,中心需要向下偏移半个高度
verticalOffset = -heightInModelUnits / 2.0;
}
// 吊装路径:路径点是设备中心位置,不需要偏移
}
// 3. 构建路径连线Edges包含直线段和圆弧段
foreach (var edge in edges)
{
@ -1397,10 +1444,17 @@ namespace NavisworksTransport
// 直线段检查SampledPoints是否有效
if (edge.SampledPoints != null && edge.SampledPoints.Count >= 2)
{
var startPoint = edge.SampledPoints.First();
var endPoint = edge.SampledPoints.Last();
// 根据路径类型调整起点和终点位置
var adjustedStartPoint = new Point3D(startPoint.X, startPoint.Y, startPoint.Z + verticalOffset);
var adjustedEndPoint = new Point3D(endPoint.X, endPoint.Y, endPoint.Z + verticalOffset);
var lineMarker = new LineMarker
{
StartPoint = edge.SampledPoints.First(),
EndPoint = edge.SampledPoints.Last(),
StartPoint = adjustedStartPoint,
EndPoint = adjustedEndPoint,
Color = lineColor,
Radius = GetLineRadius(),
SegmentType = PathSegmentType.Straight,
@ -1429,10 +1483,17 @@ namespace NavisworksTransport
arcLineOpacity = warningStyle.Alpha;
}
var startPoint = edge.Trajectory.Ts;
var endPoint = edge.Trajectory.Te;
// 根据路径类型调整起点和终点位置
var adjustedStartPoint = new Point3D(startPoint.X, startPoint.Y, startPoint.Z + verticalOffset);
var adjustedEndPoint = new Point3D(endPoint.X, endPoint.Y, endPoint.Z + verticalOffset);
var arcMarker = new LineMarker
{
StartPoint = edge.Trajectory.Ts,
EndPoint = edge.Trajectory.Te,
StartPoint = adjustedStartPoint,
EndPoint = adjustedEndPoint,
Color = arcLineColor,
Radius = GetLineRadius(),
SegmentType = PathSegmentType.Arc,
@ -1453,6 +1514,114 @@ namespace NavisworksTransport
}
}
/// <summary>
/// 直接使用路径点构建直线连线(用于吊装路径等未曲线化的路径)
/// </summary>
/// <param name="visualization">路径可视化对象</param>
/// <param name="sortedPoints">排序后的路径点列表</param>
private void BuildDirectPathLines(PathVisualization visualization, List<PathPoint> sortedPoints)
{
if (sortedPoints == null || sortedPoints.Count < 2)
return;
// 获取单位转换系数
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
// 根据可视化模式计算高度和宽度
double heightInMeters;
double widthInMeters;
Color lineColor;
double lineOpacity;
if (_visualizationMode == PathVisualizationMode.VehicleSpace)
{
// VehicleSpace 模式:使用车辆高度和宽度
// 根据路径类型调整参数
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Hoisting)
{
// 吊装路径:通行空间截面使用车辆的宽度和长度(不是高度)
heightInMeters = _vehicleLength + _safetyMargin; // Y方向使用车辆长度
widthInMeters = _vehicleWidth + 2 * _safetyMargin; // X方向使用车辆宽度
LogManager.Info($"[通行空间渲染] 吊装路径(直接连线): 车辆参数(长×宽×高)={_vehicleLength:F2}×{_vehicleWidth:F2}×{_vehicleHeight:F2}m, 安全间隙={_safetyMargin:F2}m, 通行空间截面(宽×高)={widthInMeters:F2}×{heightInMeters:F2}m");
}
else
{
// 地面路径和空轨:使用最大宽度和高度
heightInMeters = _vehicleHeight + _safetyMargin;
widthInMeters = _vehicleWidth + 2 * _safetyMargin;
LogManager.Info($"[通行空间渲染] {visualization.PathRoute.PathType}路径(直接连线): 车辆参数(长×宽×高)={_vehicleLength:F2}×{_vehicleWidth:F2}×{_vehicleHeight:F2}m, 安全间隙={_safetyMargin:F2}m, 通行空间截面(宽×高)={widthInMeters:F2}×{heightInMeters:F2}m");
}
var renderStyle = GetRenderStyle(RenderStyleName.VehicleSpace);
lineColor = renderStyle.Color;
lineOpacity = renderStyle.Alpha;
}
else if (_visualizationMode == PathVisualizationMode.RibbonLine)
{
// RibbonLine 模式:使用较低的带状高度
heightInMeters = GetLineRadius() / metersToModelUnits * 0.1;
widthInMeters = GetLineRadius() / metersToModelUnits * 2; // 路径宽度(转换为米)
var renderStyle = GetRenderStyle(RenderStyleName.Line);
lineColor = renderStyle.Color;
lineOpacity = renderStyle.Alpha;
}
else
{
// StandardLine 模式:不需要高度和宽度(圆柱体)
heightInMeters = 0;
widthInMeters = 0;
var renderStyle = GetRenderStyle(RenderStyleName.Line);
lineColor = renderStyle.Color;
lineOpacity = renderStyle.Alpha;
}
// 转换为模型单位
double heightInModelUnits = heightInMeters * metersToModelUnits;
double widthInModelUnits = widthInMeters * metersToModelUnits;
// 计算通行空间的垂直偏移(根据路径类型)
double verticalOffset = 0;
if (_visualizationMode == PathVisualizationMode.VehicleSpace)
{
if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Ground)
{
// 地面路径:路径点是地面位置,通行空间底面在地面,中心需要向上偏移半个高度
verticalOffset = heightInModelUnits / 2.0;
}
else if (visualization.PathRoute.PathType == NavisworksTransport.PathType.Rail)
{
// 空轨路径:路径点是空轨下表面位置,通行空间顶面在空轨下表面,中心需要向下偏移半个高度
verticalOffset = -heightInModelUnits / 2.0;
}
// 吊装路径:路径点是设备中心位置,不需要偏移
}
// 直接使用路径点构建直线连线
for (int i = 0; i < sortedPoints.Count - 1; i++)
{
var startPoint = sortedPoints[i];
var endPoint = sortedPoints[i + 1];
// 根据路径类型调整起点和终点位置
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);
var lineMarker = new LineMarker
{
StartPoint = adjustedStartPoint,
EndPoint = adjustedEndPoint,
Color = lineColor,
Radius = GetLineRadius(),
SegmentType = PathSegmentType.Straight,
FromIndex = startPoint.Index,
ToIndex = endPoint.Index,
Height = heightInModelUnits, // 根据模式设置高度
Width = widthInModelUnits, // 根据模式设置宽度
Opacity = lineOpacity // 根据模式设置透明度
};
visualization.PathLineMarkers.Add(lineMarker);
}
}
/// <summary>
/// 添加切点标记
/// </summary>
@ -2247,20 +2416,35 @@ namespace NavisworksTransport
right = new Vector3D(right.X / rightLength, right.Y / rightLength, right.Z / rightLength);
}
// 计算高度向量(垂直于方向向量和宽度向量)
var up = new Vector3D(
direction.Y * right.Z - direction.Z * right.Y,
direction.Z * right.X - direction.X * right.Z,
direction.X * right.Y - direction.Y * right.X
);
// 归一化up向量
var upLength = Math.Sqrt(up.X * up.X + up.Y * up.Y + up.Z * up.Z);
if (upLength > 0.001)
{
up = new Vector3D(up.X / upLength, up.Y / upLength, up.Z / upLength);
}
// 计算长方体的边界框和向量
var halfWidth = width / 2.0;
var halfHeight = height / 2.0;
// 计算立方体原点(起点左下角)
// 计算立方体原点(使长方体中心在起点位置
var origin = new Point3D(
startPoint.X - halfWidth * right.X,
startPoint.Y - halfWidth * right.Y,
startPoint.Z
startPoint.X - halfWidth * right.X - halfHeight * up.X,
startPoint.Y - halfWidth * right.Y - halfHeight * up.Y,
startPoint.Z - halfWidth * right.Z - halfHeight * up.Z
);
// 定义立方体的三个轴向量
var xVector = new Vector3D(direction.X * length, direction.Y * length, direction.Z * length); // 长度方向
var yVector = new Vector3D(right.X * width, right.Y * width, right.Z * width); // 宽度方向
var zVector = new Vector3D(0, 0, height); // 高度方向
var xVector = new Vector3D(direction.X * length, direction.Y * length, direction.Z * length); // 长度方向(沿路径)
var yVector = new Vector3D(right.X * width, right.Y * width, right.Z * width); // 宽度方向(垂直于路径)
var zVector = new Vector3D(up.X * height, up.Y * height, up.Z * height); // 高度方向(垂直于路径和宽度)
// 使用Cuboid API渲染长方体
graphics.Cuboid(origin, xVector, yVector, zVector, true);
@ -2333,20 +2517,35 @@ namespace NavisworksTransport
right = new Vector3D(right.X / rightLength, right.Y / rightLength, right.Z / rightLength);
}
// 计算高度向量(垂直于方向向量和宽度向量)
var up = new Vector3D(
direction.Y * right.Z - direction.Z * right.Y,
direction.Z * right.X - direction.X * right.Z,
direction.X * right.Y - direction.Y * right.X
);
// 归一化up向量
var upLength = Math.Sqrt(up.X * up.X + up.Y * up.Y + up.Z * up.Z);
if (upLength > 0.001)
{
up = new Vector3D(up.X / upLength, up.Y / upLength, up.Z / upLength);
}
// 计算长方体的边界框和向量
var halfWidth = width / 2.0;
var halfHeight = height / 2.0;
// 计算立方体原点(起点左下角)
// 计算立方体原点(使长方体中心在起点位置
var origin = new Point3D(
startPoint.X - halfWidth * right.X,
startPoint.Y - halfWidth * right.Y,
startPoint.Z
startPoint.X - halfWidth * right.X - halfHeight * up.X,
startPoint.Y - halfWidth * right.Y - halfHeight * up.Y,
startPoint.Z - halfWidth * right.Z - halfHeight * up.Z
);
// 定义立方体的三个轴向量
var xVector = new Vector3D(direction.X * length, direction.Y * length, direction.Z * length); // 使用指定长度
var yVector = new Vector3D(right.X * width, right.Y * width, right.Z * width); // 宽度方向
var zVector = new Vector3D(0, 0, height); // 高度方向
var xVector = new Vector3D(direction.X * length, direction.Y * length, direction.Z * length); // 使用指定长度(沿路径)
var yVector = new Vector3D(right.X * width, right.Y * width, right.Z * width); // 宽度方向(垂直于路径)
var zVector = new Vector3D(up.X * height, up.Y * height, up.Z * height); // 高度方向(垂直于路径和宽度)
// 使用Cuboid API渲染长方体
graphics.Cuboid(origin, xVector, yVector, zVector, true);

View File

@ -468,6 +468,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 预计算排除列表(异步)
_ = PrecomputeCollisionExclusionsAsync(value);
// 当选择了物体时,根据路径类型打开通行空间可视化
if (value != null)
{
UpdatePassageSpaceVisualization();
}
}
}
}
@ -540,6 +546,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
var points = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList();
_pathAnimationManager?.MoveVehicleToPathStart(vModel, points);
}
// 当切换到虚拟车辆模式时,根据路径类型打开通行空间可视化
UpdatePassageSpaceVisualization();
}
catch (Exception ex)
{
@ -2386,6 +2395,211 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
/// <summary>
/// 根据路径类型更新通行空间可视化
/// 空轨和吊装路径默认打开通行空间(车辆通行空间模式),地面路径不打开
/// 根据选择的物体或虚拟车辆尺寸更新通行空间渲染
/// </summary>
private void UpdatePassageSpaceVisualization()
{
try
{
if (CurrentPathRoute == null)
{
LogManager.Debug("[通行空间可视化] 没有选择路径,跳过更新");
return;
}
// 根据路径类型决定是否打开通行空间
bool enableVehicleSpace = false;
switch (CurrentPathRoute.PathType)
{
case NavisworksTransport.PathType.Rail:
case NavisworksTransport.PathType.Hoisting:
enableVehicleSpace = true;
LogManager.Info($"[通行空间可视化] 路径类型={CurrentPathRoute.PathType},自动切换到车辆通行空间模式");
break;
case NavisworksTransport.PathType.Ground:
enableVehicleSpace = false;
LogManager.Debug($"[通行空间可视化] 路径类型={CurrentPathRoute.PathType},不切换到车辆通行空间模式");
break;
default:
LogManager.Warning($"[通行空间可视化] 未知的路径类型: {CurrentPathRoute.PathType}");
return;
}
// 设置路径可视化模式
if (enableVehicleSpace)
{
var renderPlugin = PathPointRenderPlugin.Instance;
if (renderPlugin != null)
{
// 获取车辆尺寸(米)
double vehicleLength, vehicleWidth, vehicleHeight;
if (UseVirtualVehicle)
{
// 使用虚拟车辆尺寸,但需要根据路径类型调整
if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Hoisting)
{
// 吊装路径:通行空间截面使用车辆的宽度和长度(不是高度)
vehicleWidth = VirtualVehicleWidth; // X方向
vehicleHeight = VirtualVehicleLength; // Y方向使用车辆长度
// 计算路径的Z长度差
if (CurrentPathRoute.Points.Count >= 2)
{
var startPoint = CurrentPathRoute.Points.First();
var endPoint = CurrentPathRoute.Points.Last();
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
vehicleLength = Math.Abs(endPoint.Z - startPoint.Z) / metersToModelUnits;
}
else
{
vehicleLength = VirtualVehicleLength; // fallback
}
LogManager.Info($"[通行空间可视化] 吊装路径使用虚拟车辆尺寸: 宽×高×长={vehicleWidth:F2}×{vehicleHeight:F2}×{vehicleLength:F2}m");
}
else
{
// 地面路径和空轨:使用虚拟车辆的宽度和高度
vehicleWidth = VirtualVehicleWidth; // 通行空间宽度 = 车辆宽度(垂直于路径方向)
vehicleHeight = VirtualVehicleHeight; // 通行空间高度 = 车辆高度
vehicleLength = VirtualVehicleLength; // 车辆长度(沿路径方向)
LogManager.Info($"[通行空间可视化] 地面/空轨路径使用虚拟车辆尺寸: 通行空间宽×高={vehicleWidth:F2}×{vehicleHeight:F2}m, 车辆长度={vehicleLength:F2}m");
}
}
else if (SelectedAnimatedObject != null)
{
// 使用选择物体的包围盒尺寸
try
{
var bbox = SelectedAnimatedObject.BoundingBox();
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
// 将模型单位转换为米
double sizeX = (bbox.Max.X - bbox.Min.X) / metersToModelUnits;
double sizeY = (bbox.Max.Y - bbox.Min.Y) / metersToModelUnits;
double sizeZ = (bbox.Max.Z - bbox.Min.Z) / metersToModelUnits;
// 根据路径类型确定车辆的长度、宽度、高度
if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Hoisting)
{
// 吊装路径(严格垂直路径):
// - 宽度 = X方向尺寸
// - 高度 = Y方向尺寸
// - 长度 = 路径起点到终点的Z值差
vehicleWidth = sizeX;
vehicleHeight = sizeY;
// 计算路径的Z长度差
if (CurrentPathRoute.Points.Count >= 2)
{
var startPoint = CurrentPathRoute.Points.First();
var endPoint = CurrentPathRoute.Points.Last();
vehicleLength = Math.Abs(endPoint.Z - startPoint.Z) / metersToModelUnits;
}
else
{
vehicleLength = sizeZ; // fallback
}
LogManager.Info($"[通行空间可视化] 吊装路径使用物体XY尺寸 ({SelectedAnimatedObject.DisplayName}): 宽={vehicleWidth:F2}m, 高={vehicleHeight:F2}m, 长度(路径Z差)={vehicleLength:F2}m");
}
else
{
// 地面路径和空轨(可能有坡度):
// - 物体的Z轴和路径垂直
// - 通行空间宽度 = 车辆的宽度(垂直于路径方向)
// - 通行空间高度 = 车辆的高度Z方向
// - 通行空间长度 = 由路径起点和终点决定
vehicleLength = Math.Max(sizeX, sizeY); // 车辆沿路径方向的长度
vehicleWidth = Math.Min(sizeX, sizeY); // 通行空间宽度 = 车辆的宽度(垂直于路径方向)
vehicleHeight = sizeZ; // 通行空间高度 = 车辆的高度
LogManager.Info($"[通行空间可视化] 地面/空轨路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): 通行空间宽×高={vehicleWidth:F2}×{vehicleHeight:F2}m, 车辆长度={vehicleLength:F2}m");
}
}
catch (Exception ex)
{
LogManager.Warning($"[通行空间可视化] 获取物体包围盒失败: {ex.Message},使用默认尺寸");
vehicleLength = 1.0;
vehicleWidth = 1.0;
vehicleHeight = 2.0;
}
}
else
{
// 没有选择物体,使用默认尺寸
vehicleLength = 1.0;
vehicleWidth = 1.0;
vehicleHeight = 2.0;
LogManager.Info("[通行空间可视化] 使用默认车辆尺寸: 1.0×1.0×2.0m");
}
// 获取安全间隙(从配置)
var config = Core.Config.ConfigManager.Instance?.Current;
double safetyMargin = config?.PathEditing?.SafetyMarginMeters ?? 0.05;
// 设置车辆参数到渲染插件
renderPlugin.SetVehicleParameters(vehicleLength, vehicleWidth, vehicleHeight, safetyMargin);
LogManager.Info($"[通行空间可视化] 已设置车辆参数: {vehicleLength:F2}×{vehicleWidth:F2}×{vehicleHeight:F2}m, 安全间隙: {safetyMargin:F2}m");
// 切换到车辆通行空间模式
renderPlugin.VisualizationMode = PathVisualizationMode.VehicleSpace;
LogManager.Info("[通行空间可视化] 已切换到车辆通行空间模式");
// 刷新路径可视化以应用新的尺寸
var coreRoute = PathPlanningManager.Instance?.Routes?.FirstOrDefault(r => r.Id == CurrentPathRoute.Id);
if (coreRoute != null)
{
PathPlanningManager.Instance.DrawRouteVisualization(coreRoute, isAutoPath: false);
LogManager.Info("[通行空间可视化] 已刷新路径可视化");
}
}
else
{
LogManager.Warning("[通行空间可视化] 无法获取PathPointRenderPlugin实例");
}
}
}
catch (Exception ex)
{
LogManager.Error($"[通行空间可视化] 更新失败: {ex.Message}", ex);
}
}
/// <summary>
/// 递归检查ModelItem是否包含几何体
/// </summary>

View File

@ -127,6 +127,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
_pathPlanningManager.SetCurrentRoute(coreRoute);
LogManager.Info($"UI路径切换已同步PathPlanningManager的CurrentRoute到 {value.Name}");
// 根据路径类型自动设置通行空间可视化
UpdatePassageSpaceVisualizationForPathType(coreRoute.PathType);
}
else
{
@ -2675,6 +2678,47 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
}
/// <summary>
/// 根据路径类型自动设置通行空间可视化
/// 空轨和吊装路径自动打开通行空间,地面路径不打开
/// </summary>
private void UpdatePassageSpaceVisualizationForPathType(PathType pathType)
{
try
{
bool enableVehicleSpace = false;
switch (pathType)
{
case PathType.Rail:
case PathType.Hoisting:
enableVehicleSpace = true;
LogManager.Info($"[路径编辑] 路径类型={pathType},自动打开通行空间可视化");
break;
case PathType.Ground:
enableVehicleSpace = false;
LogManager.Debug($"[路径编辑] 路径类型={pathType},不打开通行空间可视化");
break;
default:
LogManager.Warning($"[路径编辑] 未知的路径类型: {pathType}");
return;
}
// 设置通行空间可视化开关
if (enableVehicleSpace)
{
IsVehicleSpaceMode = true;
LogManager.Info("[路径编辑] 已自动打开通行空间可视化开关");
}
}
catch (Exception ex)
{
LogManager.Error($"[路径编辑] 设置通行空间可视化失败: {ex.Message}", ex);
}
}
/// <summary>
/// 路径可视化模式变更事件处理
/// </summary>