diff --git a/src/Core/PathPlanningManager.cs b/src/Core/PathPlanningManager.cs
index 1b0eb88..9f42b3e 100644
--- a/src/Core/PathPlanningManager.cs
+++ b/src/Core/PathPlanningManager.cs
@@ -58,6 +58,7 @@ namespace NavisworksTransport
private bool _showUnknownGrid = false;
private bool _showDoorGrid = false;
private GridMap _currentGridMap = null; // 保存当前网格地图用于刷新
+ private double _currentVehicleHeight = 2.0; // 保存当前车辆高度(米)用于网格刷新
private bool _isPreviewMode = false;
private int _previewInsertIndex = -1; // 保存预览点应该插入的索引位置
@@ -955,7 +956,7 @@ namespace NavisworksTransport
if (_showWalkableGrid || _showObstacleGrid || _showUnknownGrid || _showDoorGrid)
{
LogManager.Info("开始网格可视化,显示所有可通行网格单元");
- VisualizeGridCells(gridMap);
+ VisualizeGridCells(gridMap, vehicleHeight);
}
// 3. 获取通道高度数据
@@ -3336,7 +3337,7 @@ namespace NavisworksTransport
if (_currentGridMap != null && IsAnyGridVisualizationEnabled)
{
LogManager.Info("[网格可视化] 使用缓存的网格地图重新渲染");
- VisualizeGridCells(_currentGridMap);
+ VisualizeGridCells(_currentGridMap, _currentVehicleHeight);
}
else if (_currentGridMap == null)
{
@@ -3358,7 +3359,8 @@ namespace NavisworksTransport
/// 在每个可通行网格的中心绘制一个绿色小球
///
/// 要可视化的网格地图
- public void VisualizeGridCells(GridMap gridMap)
+ /// 车辆高度(米),用于判断层高是否足够
+ public void VisualizeGridCells(GridMap gridMap, double vehicleHeight = 2.0)
{
if (gridMap == null)
{
@@ -3368,9 +3370,10 @@ namespace NavisworksTransport
try
{
- // 保存当前网格地图用于后续刷新
+ // 保存当前网格地图和车辆高度用于后续刷新
_currentGridMap = gridMap;
- LogManager.Info($"[网格可视化] 开始可视化网格:{gridMap.Width}x{gridMap.Height}");
+ _currentVehicleHeight = vehicleHeight;
+ LogManager.Info($"[网格可视化] 开始可视化网格:{gridMap.Width}x{gridMap.Height}, 车辆高度:{vehicleHeight}m");
// 获取渲染插件
var renderPlugin = PathPointRenderPlugin.Instance;
@@ -3416,6 +3419,15 @@ namespace NavisworksTransport
int openSpaceCells = 0;
int doorCells = 0;
int totalVisualized = 0;
+ int multiLayerCells = 0;
+ int totalLayersVisualized = 0;
+ int heightInsufficientLayers = 0;
+
+ // 获取车辆高度(模型单位)用于判断层高是否足够
+ double vehicleHeightInModelUnits = vehicleHeight *
+ UnitsConverter.GetMetersToUnitsConversionFactor(Application.ActiveDocument.Units);
+
+ LogManager.Info($"[网格可视化] 车辆高度: {vehicleHeight}m = {vehicleHeightInModelUnits:F2}模型单位");
// 遍历所有网格单元格,根据类型分别收集
for (int x = 0; x < gridMap.Width; x++)
@@ -3424,79 +3436,168 @@ namespace NavisworksTransport
{
var cell = gridMap.Cells[x, y];
- // 计算网格单元格的世界中心位置
+ // 计算网格单元格的XY中心位置(Z坐标在多层逻辑中单独处理)
var gridPos = new NavisworksTransport.PathPlanning.GridPoint2D(x, y);
var gridCorner = gridMap.GridToWorld3D(gridPos);
- var gridCenter = new Point3D(
- gridCorner.X + gridMap.CellSize / 2,
- gridCorner.Y + gridMap.CellSize / 2,
- gridCorner.Z
- );
+ double centerX = gridCorner.X + gridMap.CellSize / 2;
+ double centerY = gridCorner.Y + gridMap.CellSize / 2;
- PathRoute targetRoute = null;
- string gridTypeName = "";
+ // 检查是否有多个高度层
+ if (cell.HeightLayers != null && cell.HeightLayers.Count > 0)
+ {
+ // 多层逻辑:遍历每一层,根据PassableHeight判断是否可通行
+ multiLayerCells++;
- // 根据网格类型和用户设置确定目标路径和名称
- if (cell.IsWalkable && cell.CellType == CategoryAttributeManager.LogisticsElementType.通道)
- {
- if (_showWalkableGrid) // 检查可通行网格开关
+ foreach (var layer in cell.HeightLayers)
{
- targetRoute = channelRoute;
- gridTypeName = "通道";
- channelCells++;
- }
- }
- else if (cell.IsWalkable && cell.CellType == CategoryAttributeManager.LogisticsElementType.门)
- {
- if (_showDoorGrid) // 检查门网格独立开关
- {
- targetRoute = doorRoute;
- gridTypeName = "门";
- doorCells++;
- }
- }
- else if (cell.IsWalkable && cell.CellType == CategoryAttributeManager.LogisticsElementType.楼板)
- {
- if (_showWalkableGrid) // 检查可通行网格开关
- {
- targetRoute = channelRoute; // 开放空间也用绿色显示
- gridTypeName = "开放";
- openSpaceCells++;
- }
- }
- else if (cell.CellType == CategoryAttributeManager.LogisticsElementType.Unknown)
- {
- if (_showUnknownGrid) // 检查未知网格开关
- {
- targetRoute = unknownRoute;
- gridTypeName = "空洞";
- unknownCells++;
- }
- }
- else if (cell.CellType == CategoryAttributeManager.LogisticsElementType.障碍物)
- {
- if (_showObstacleGrid) // 检查障碍物网格开关
- {
- targetRoute = obstacleRoute;
- gridTypeName = "障碍";
- obstacleCells++;
- }
- }
+ double layerZ = layer.Z;
+ double passableHeight = layer.PassableHeight.GetSpan();
- // 如果有对应的路径,创建并添加网格点
- if (targetRoute != null)
- {
- var gridPoint = new PathPoint
- {
- Position = gridCenter,
- Name = $"网格_{gridTypeName}({x},{y})",
- Type = PathPointType.WayPoint,
- Index = totalVisualized,
- Notes = $"GridType:{cell.CellType}"
- };
+ // 判断高度是否足够车辆通行
+ bool isHeightSufficient = passableHeight >= vehicleHeightInModelUnits;
- targetRoute.Points.Add(gridPoint);
- totalVisualized++;
+ // 调试:输出高度不足的层
+ if (!isHeightSufficient && multiLayerCells < 5) // 只输出前5个网格的详情
+ {
+ LogManager.Debug($"[高度判断] 网格({x},{y}) Layer Z={layerZ:F2}, PassableH={passableHeight:F2}, 车辆H={vehicleHeightInModelUnits:F2}, 高度足够={isHeightSufficient}");
+ }
+
+ PathRoute targetRoute = null;
+ string gridTypeName = "";
+
+ // 根据高度是否足够和网格类型决定渲染方式
+ if (isHeightSufficient)
+ {
+ // 高度足够 - 按原类型渲染
+ if (cell.CellType == CategoryAttributeManager.LogisticsElementType.通道)
+ {
+ if (_showWalkableGrid)
+ {
+ targetRoute = channelRoute;
+ gridTypeName = "通道";
+ channelCells++;
+ }
+ }
+ else if (cell.CellType == CategoryAttributeManager.LogisticsElementType.门)
+ {
+ if (_showDoorGrid)
+ {
+ targetRoute = doorRoute;
+ gridTypeName = "门";
+ doorCells++;
+ }
+ }
+ else if (cell.CellType == CategoryAttributeManager.LogisticsElementType.楼板)
+ {
+ if (_showWalkableGrid)
+ {
+ targetRoute = channelRoute;
+ gridTypeName = "开放";
+ openSpaceCells++;
+ }
+ }
+ }
+ else
+ {
+ // 高度不足 - 渲染为障碍物(灰色)
+ if (_showObstacleGrid)
+ {
+ targetRoute = obstacleRoute;
+ gridTypeName = "障碍_高度不足"; // 必须包含"障碍"关键词才能渲染为灰色
+ heightInsufficientLayers++;
+ }
+ }
+
+ // 创建该层的可视化点
+ if (targetRoute != null)
+ {
+ var gridCenter = new Point3D(centerX, centerY, layerZ);
+
+ var gridPoint = new PathPoint
+ {
+ Position = gridCenter,
+ Name = $"网格_{gridTypeName}({x},{y})_Z{layerZ:F2}",
+ Type = PathPointType.WayPoint,
+ Index = totalVisualized,
+ Notes = $"GridType:{cell.CellType}, LayerZ={layerZ:F2}, PassableH={passableHeight:F2}m"
+ };
+
+ targetRoute.Points.Add(gridPoint);
+ totalVisualized++;
+ totalLayersVisualized++;
+ }
+ }
+ }
+ else
+ {
+ // 单层逻辑:保持原有逻辑不变
+ var gridCenter = new Point3D(centerX, centerY, gridCorner.Z);
+
+ PathRoute targetRoute = null;
+ string gridTypeName = "";
+
+ // 根据网格类型和用户设置确定目标路径和名称
+ if (cell.IsWalkable && cell.CellType == CategoryAttributeManager.LogisticsElementType.通道)
+ {
+ if (_showWalkableGrid)
+ {
+ targetRoute = channelRoute;
+ gridTypeName = "通道";
+ channelCells++;
+ }
+ }
+ else if (cell.IsWalkable && cell.CellType == CategoryAttributeManager.LogisticsElementType.门)
+ {
+ if (_showDoorGrid)
+ {
+ targetRoute = doorRoute;
+ gridTypeName = "门";
+ doorCells++;
+ }
+ }
+ else if (cell.IsWalkable && cell.CellType == CategoryAttributeManager.LogisticsElementType.楼板)
+ {
+ if (_showWalkableGrid)
+ {
+ targetRoute = channelRoute;
+ gridTypeName = "开放";
+ openSpaceCells++;
+ }
+ }
+ else if (cell.CellType == CategoryAttributeManager.LogisticsElementType.Unknown)
+ {
+ if (_showUnknownGrid)
+ {
+ targetRoute = unknownRoute;
+ gridTypeName = "空洞";
+ unknownCells++;
+ }
+ }
+ else if (cell.CellType == CategoryAttributeManager.LogisticsElementType.障碍物)
+ {
+ if (_showObstacleGrid)
+ {
+ targetRoute = obstacleRoute;
+ gridTypeName = "障碍";
+ obstacleCells++;
+ }
+ }
+
+ // 如果有对应的路径,创建并添加网格点
+ if (targetRoute != null)
+ {
+ var gridPoint = new PathPoint
+ {
+ Position = gridCenter,
+ Name = $"网格_{gridTypeName}({x},{y})",
+ Type = PathPointType.WayPoint,
+ Index = totalVisualized,
+ Notes = $"GridType:{cell.CellType}"
+ };
+
+ targetRoute.Points.Add(gridPoint);
+ totalVisualized++;
+ }
}
}
}
@@ -3529,14 +3630,17 @@ namespace NavisworksTransport
// 输出统计信息
LogManager.Info($"[网格可视化] 可视化完成:");
LogManager.Info($" - 总网格单元格数:{gridMap.Width * gridMap.Height}");
+ LogManager.Info($" - 多层网格数:{multiLayerCells}");
LogManager.Info($" - 通道单元格数:{channelCells}");
LogManager.Info($" - 门单元格数:{doorCells}");
LogManager.Info($" - 开放空间单元格数:{openSpaceCells}");
LogManager.Info($" - Unknown单元格数:{unknownCells}");
LogManager.Info($" - 障碍物单元格数:{obstacleCells}");
+ LogManager.Info($" - 高度不足层数:{heightInsufficientLayers}");
LogManager.Info($" - 已可视化单元格数:{totalVisualized}");
+ LogManager.Info($" - 已可视化层数:{totalLayersVisualized}");
- RaiseStatusChanged($"网格可视化完成:显示了 {totalVisualized} 个网格单元 (通道:{channelCells}, 门:{doorCells}[50%透明], Unknown:{unknownCells}, 障碍:{obstacleCells})", PathPlanningStatusType.Success);
+ RaiseStatusChanged($"网格可视化完成:显示了 {totalVisualized} 个网格单元 (多层网格:{multiLayerCells}, 通道:{channelCells}, 门:{doorCells}[50%透明], Unknown:{unknownCells}, 障碍:{obstacleCells}, 高度不足:{heightInsufficientLayers})", PathPlanningStatusType.Success);
}
catch (Exception ex)
{
diff --git a/src/PathPlanning/GridMapGenerator.cs b/src/PathPlanning/GridMapGenerator.cs
index 3e50ca2..ab0c8f3 100644
--- a/src/PathPlanning/GridMapGenerator.cs
+++ b/src/PathPlanning/GridMapGenerator.cs
@@ -346,6 +346,7 @@ namespace NavisworksTransport.PathPlanning
int processedCount = 0;
int layerCount = 0;
+ int stairBottomLayersProcessed = 0;
for (int x = 0; x < gridMap.Width; x++)
{
@@ -354,11 +355,47 @@ namespace NavisworksTransport.PathPlanning
var cell = gridMap.Cells[x, y];
if (cell.IsWalkable && cell.HeightLayers != null && cell.HeightLayers.Count > 0)
{
+ // 检查是否是楼梯或电梯网格(有多层且包含楼梯/电梯层)
+ bool hasStairsOrElevator = cell.HeightLayers.Any(layer =>
+ layer.Type == CategoryAttributeManager.LogisticsElementType.楼梯 ||
+ layer.Type == CategoryAttributeManager.LogisticsElementType.电梯);
+
// 为每个高度层设置PassableHeight
for (int i = 0; i < cell.HeightLayers.Count; i++)
{
var layer = cell.HeightLayers[i];
- layer.PassableHeight = new HeightInterval(0, scanHeightInModelUnits);
+
+ // 特殊处理:楼梯/电梯的第0层(下方通道层)
+ if (hasStairsOrElevator && i == 0 && cell.HeightLayers.Count >= 2)
+ {
+ // Layer 0是楼梯下方的通道层
+ // PassableHeight应该是从层顶到上方楼梯底面的距离
+ var upperLayer = cell.HeightLayers[1]; // 楼梯层
+ double bottomLayerTop = layer.Z; // 下层顶部
+ double upperLayerBottom = upperLayer.Z; // 上层底部
+
+ // 计算实际可通行高度
+ double actualPassableHeight = upperLayerBottom - bottomLayerTop;
+
+ if (actualPassableHeight > 0)
+ {
+ layer.PassableHeight = new HeightInterval(0, actualPassableHeight);
+ stairBottomLayersProcessed++;
+ LogManager.Debug($"【楼梯下方高度】网格({x},{y}) Layer{i} Z={layer.Z:F2}, 上层Z={upperLayer.Z:F2}, PassableHeight={actualPassableHeight:F2}模型单位");
+ }
+ else
+ {
+ // 如果计算出负值或0,使用默认值
+ layer.PassableHeight = new HeightInterval(0, scanHeightInModelUnits);
+ LogManager.Warning($"【楼梯下方高度】网格({x},{y}) Layer{i} 计算高度异常: {actualPassableHeight:F2},使用默认值");
+ }
+ }
+ else
+ {
+ // 普通层或楼梯层本身,使用标准扫描高度
+ layer.PassableHeight = new HeightInterval(0, scanHeightInModelUnits);
+ }
+
cell.HeightLayers[i] = layer;
layerCount++;
}
@@ -370,6 +407,7 @@ namespace NavisworksTransport.PathPlanning
}
LogManager.Info($"【高度约束设置】完成,已处理 {processedCount} 个网格,{layerCount} 个高度层");
+ LogManager.Info($"【高度约束设置】其中楼梯/电梯下方层: {stairBottomLayersProcessed} 个(使用实际可通行高度)");
}
///