用所有通道顶面最小值作为障碍物扫描基准
This commit is contained in:
parent
1b95c37b80
commit
328263e846
@ -81,14 +81,17 @@ namespace NavisworksTransport.PathPlanning
|
||||
|
||||
// 3. 创建网格地图
|
||||
var gridMap = new GridMap(totalBounds, gridSize);
|
||||
|
||||
|
||||
// 新增:跟踪最小通道顶面高度
|
||||
double minChannelTopZ = double.MaxValue;
|
||||
|
||||
// 4. 为每个通道生成精确投影
|
||||
var processedChannels = new List<ModelItem>();
|
||||
foreach (var channel in channelItems)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProjectChannelToGrid(channel, gridMap);
|
||||
ProjectChannelToGrid(channel, gridMap, ref minChannelTopZ);
|
||||
processedChannels.Add(channel);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -98,12 +101,14 @@ namespace NavisworksTransport.PathPlanning
|
||||
}
|
||||
|
||||
LogManager.Info($"[通道网格构建器] 成功投影 {processedChannels.Count}/{channelItems.Count} 个通道");
|
||||
LogManager.Info($"[通道网格构建器] 最低通道顶面高度: {minChannelTopZ:F2}");
|
||||
|
||||
return new ChannelCoverage
|
||||
{
|
||||
GridMap = gridMap,
|
||||
ChannelItems = processedChannels,
|
||||
TotalBounds = totalBounds
|
||||
TotalBounds = totalBounds,
|
||||
MinChannelTopZ = minChannelTopZ
|
||||
};
|
||||
}
|
||||
|
||||
@ -114,7 +119,8 @@ namespace NavisworksTransport.PathPlanning
|
||||
/// </summary>
|
||||
/// <param name="channel">通道物品</param>
|
||||
/// <param name="gridMap">目标网格地图</param>
|
||||
private void ProjectChannelToGrid(ModelItem channel, GridMap gridMap)
|
||||
/// <param name="minChannelTopZ">最小通道顶面高度的引用,用于跟踪所有通道中的最低顶面</param>
|
||||
private void ProjectChannelToGrid(ModelItem channel, GridMap gridMap, ref double minChannelTopZ)
|
||||
{
|
||||
LogManager.Info($"[通道网格构建器] 投影通道: {channel.DisplayName}");
|
||||
|
||||
@ -156,13 +162,13 @@ namespace NavisworksTransport.PathPlanning
|
||||
// 根据法向量决定处理方式
|
||||
if (normal.Z > 0.7) // 朝上的水平面
|
||||
{
|
||||
RasterizeTriangleToGrid(gridMap, triangle);
|
||||
RasterizeTriangleToGrid(gridMap, triangle, ref minChannelTopZ);
|
||||
processedTriangles++;
|
||||
}
|
||||
else if (normal.Z > 0.2) // 可行走的斜面(楼梯、坡道)
|
||||
{
|
||||
// 对于斜面,也进行投影,适用于楼梯等倾斜通道
|
||||
RasterizeTriangleToGrid(gridMap, triangle);
|
||||
RasterizeTriangleToGrid(gridMap, triangle, ref minChannelTopZ);
|
||||
processedTriangles++;
|
||||
}
|
||||
// 垂直面和朝下的面不投影
|
||||
@ -210,7 +216,8 @@ namespace NavisworksTransport.PathPlanning
|
||||
/// </summary>
|
||||
/// <param name="gridMap">网格地图</param>
|
||||
/// <param name="triangle">三角形</param>
|
||||
private void RasterizeTriangleToGrid(GridMap gridMap, Triangle3D triangle)
|
||||
/// <param name="minChannelTopZ">最小通道顶面高度的引用,用于跟踪所有通道中的最低顶面</param>
|
||||
private void RasterizeTriangleToGrid(GridMap gridMap, Triangle3D triangle, ref double minChannelTopZ)
|
||||
{
|
||||
// 获取三角形的2D投影边界框
|
||||
var minX = Math.Min(triangle.Point1.X, Math.Min(triangle.Point2.X, triangle.Point3.X));
|
||||
@ -224,6 +231,9 @@ namespace NavisworksTransport.PathPlanning
|
||||
// 计算三角形的平均高度作为通道顶面高度
|
||||
double triangleHeight = (triangle.Point1.Z + triangle.Point2.Z + triangle.Point3.Z) / 3.0;
|
||||
|
||||
// 更新最小通道顶面高度
|
||||
minChannelTopZ = Math.Min(minChannelTopZ, triangleHeight);
|
||||
|
||||
// 遍历边界框内的所有网格点
|
||||
for (int x = minGrid.X; x <= maxGrid.X; x++)
|
||||
{
|
||||
|
||||
@ -843,6 +843,11 @@ namespace NavisworksTransport.PathPlanning
|
||||
/// </summary>
|
||||
public BoundingBox3D TotalBounds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最低通道顶面高度,用作障碍物扫描的基准Z值
|
||||
/// </summary>
|
||||
public double MinChannelTopZ { get; set; } = double.MaxValue;
|
||||
|
||||
/// <summary>
|
||||
/// 获取统计信息
|
||||
/// </summary>
|
||||
|
||||
@ -89,7 +89,8 @@ namespace NavisworksTransport.PathPlanning
|
||||
// 2. 直接遍历处理障碍物(包围盒检测) - 使用高性能优化版本
|
||||
LogManager.Info("【生成网格地图】步骤2: 高性能包围盒遍历处理障碍物");
|
||||
double scanHeight = vehicleHeight + safetyMargin; // 扫描高度 = 车辆高度 + 安全间隙
|
||||
ProcessObstaclesWithBoundingBoxOptimized(document, channelCoverage.GridMap, channelRelatedItems, scanHeight);
|
||||
double minChannelTopZ = channelCoverage.MinChannelTopZ; // 提取最小通道顶面高度
|
||||
ProcessObstaclesWithBoundingBoxOptimized(document, channelCoverage.GridMap, channelRelatedItems, scanHeight, minChannelTopZ);
|
||||
|
||||
LogManager.Info($"【阶段2完成】障碍物处理后网格统计: {channelCoverage.GridMap.GetStatistics()}");
|
||||
|
||||
@ -973,10 +974,11 @@ namespace NavisworksTransport.PathPlanning
|
||||
/// 大幅减少API调用次数
|
||||
/// </summary>
|
||||
private Dictionary<ModelItem, ItemProperties> PostProcessGeometryItems(
|
||||
List<ModelItem> geometryItems,
|
||||
HashSet<ModelItem> channelItemsSet,
|
||||
GridMap gridMap,
|
||||
double scanHeight)
|
||||
List<ModelItem> geometryItems,
|
||||
HashSet<ModelItem> channelItemsSet,
|
||||
GridMap gridMap,
|
||||
double scanHeight,
|
||||
double minChannelTopZ)
|
||||
{
|
||||
LogManager.Info("[轻量级后处理] 开始处理Search API筛选结果");
|
||||
var startTime = DateTime.Now;
|
||||
@ -1036,7 +1038,7 @@ namespace NavisworksTransport.PathPlanning
|
||||
}
|
||||
|
||||
// 快速计算:高度范围检查(纯数值计算,无API调用)
|
||||
properties.IsInScanHeightRange = IsInScanHeightRange(properties.BoundingBox, gridMap, scanHeight);
|
||||
properties.IsInScanHeightRange = IsInScanHeightRange(properties.BoundingBox, minChannelTopZ, scanHeight);
|
||||
if (!properties.IsInScanHeightRange)
|
||||
{
|
||||
skippedByHeight++;
|
||||
@ -1067,7 +1069,8 @@ namespace NavisworksTransport.PathPlanning
|
||||
/// <param name="gridMap">网格地图</param>
|
||||
/// <param name="channelItems">通道模型项列表</param>
|
||||
/// <param name="scanHeight">扫描高度范围</param>
|
||||
private void ProcessObstaclesWithBoundingBoxOptimized(Document document, GridMap gridMap, HashSet<ModelItem> channelItems, double scanHeight)
|
||||
/// <param name="minChannelTopZ">最小通道顶面高度,用作扫描基准</param>
|
||||
private void ProcessObstaclesWithBoundingBoxOptimized(Document document, GridMap gridMap, HashSet<ModelItem> channelItems, double scanHeight, double minChannelTopZ)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -1082,7 +1085,7 @@ namespace NavisworksTransport.PathPlanning
|
||||
LogManager.Info($"[高性能障碍物处理] 输入统计 - 几何体项目: {geometryItems.Count}, 通道元素: {channelItemsSet.Count}");
|
||||
|
||||
// 阶段2:轻量级后处理(只对预筛选结果进行必要的API调用)
|
||||
var itemCache = PostProcessGeometryItems(geometryItems, channelItemsSet, gridMap, scanHeight);
|
||||
var itemCache = PostProcessGeometryItems(geometryItems, channelItemsSet, gridMap, scanHeight, minChannelTopZ);
|
||||
|
||||
// 阶段3:条件过滤(并行数值计算)- 使用50%CPU核心优化
|
||||
LogManager.Info("[高性能障碍物处理] 阶段3: 并行条件过滤");
|
||||
@ -1351,17 +1354,17 @@ namespace NavisworksTransport.PathPlanning
|
||||
/// 检查包围盒是否在扫描高度范围内
|
||||
/// </summary>
|
||||
/// <param name="bbox">包围盒</param>
|
||||
/// <param name="gridMap">网格地图</param>
|
||||
/// <param name="minChannelTopZ">最小通道顶面高度,用作扫描基准</param>
|
||||
/// <param name="scanHeight">扫描高度范围</param>
|
||||
/// <returns>是否在高度范围内</returns>
|
||||
private bool IsInScanHeightRange(BoundingBox3D bbox, GridMap gridMap, double scanHeight)
|
||||
private bool IsInScanHeightRange(BoundingBox3D bbox, double minChannelTopZ, double scanHeight)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用通道的实际高度范围作为扫描基准
|
||||
var scanMinZ = gridMap.Bounds.Max.Z; // 通道顶面
|
||||
var scanMaxZ = gridMap.Bounds.Max.Z + scanHeight; // 从通道顶面向上扫描
|
||||
|
||||
// 使用最低通道顶面高度作为扫描基准,避免门高度干扰
|
||||
var scanMinZ = minChannelTopZ; // 最低通道顶面
|
||||
var scanMaxZ = minChannelTopZ + scanHeight; // 从最低通道顶面向上扫描
|
||||
|
||||
// 检查包围盒的Z范围是否与扫描范围有重叠
|
||||
return !(bbox.Max.Z < scanMinZ || bbox.Min.Z > scanMaxZ);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user