From 328263e8463cda4cb3325c7bb7ad43749b43cc16 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Fri, 19 Sep 2025 18:15:02 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=89=80=E6=9C=89=E9=80=9A=E9=81=93?= =?UTF-8?q?=E9=A1=B6=E9=9D=A2=E6=9C=80=E5=B0=8F=E5=80=BC=E4=BD=9C=E4=B8=BA?= =?UTF-8?q?=E9=9A=9C=E7=A2=8D=E7=89=A9=E6=89=AB=E6=8F=8F=E5=9F=BA=E5=87=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PathPlanning/ChannelBasedGridBuilder.cs | 24 +++++++++++----- src/PathPlanning/GridMap.cs | 5 ++++ src/PathPlanning/GridMapGenerator.cs | 31 +++++++++++---------- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/PathPlanning/ChannelBasedGridBuilder.cs b/src/PathPlanning/ChannelBasedGridBuilder.cs index b1d1ef1..c1d9112 100644 --- a/src/PathPlanning/ChannelBasedGridBuilder.cs +++ b/src/PathPlanning/ChannelBasedGridBuilder.cs @@ -81,14 +81,17 @@ namespace NavisworksTransport.PathPlanning // 3. 创建网格地图 var gridMap = new GridMap(totalBounds, gridSize); - + + // 新增:跟踪最小通道顶面高度 + double minChannelTopZ = double.MaxValue; + // 4. 为每个通道生成精确投影 var processedChannels = new List(); 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 /// /// 通道物品 /// 目标网格地图 - private void ProjectChannelToGrid(ModelItem channel, GridMap gridMap) + /// 最小通道顶面高度的引用,用于跟踪所有通道中的最低顶面 + 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 /// /// 网格地图 /// 三角形 - private void RasterizeTriangleToGrid(GridMap gridMap, Triangle3D triangle) + /// 最小通道顶面高度的引用,用于跟踪所有通道中的最低顶面 + 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++) { diff --git a/src/PathPlanning/GridMap.cs b/src/PathPlanning/GridMap.cs index d7a8539..4b4d583 100644 --- a/src/PathPlanning/GridMap.cs +++ b/src/PathPlanning/GridMap.cs @@ -843,6 +843,11 @@ namespace NavisworksTransport.PathPlanning /// public BoundingBox3D TotalBounds { get; set; } + /// + /// 最低通道顶面高度,用作障碍物扫描的基准Z值 + /// + public double MinChannelTopZ { get; set; } = double.MaxValue; + /// /// 获取统计信息 /// diff --git a/src/PathPlanning/GridMapGenerator.cs b/src/PathPlanning/GridMapGenerator.cs index 3ea852c..09e8911 100644 --- a/src/PathPlanning/GridMapGenerator.cs +++ b/src/PathPlanning/GridMapGenerator.cs @@ -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调用次数 /// private Dictionary PostProcessGeometryItems( - List geometryItems, - HashSet channelItemsSet, - GridMap gridMap, - double scanHeight) + List geometryItems, + HashSet 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 /// 网格地图 /// 通道模型项列表 /// 扫描高度范围 - private void ProcessObstaclesWithBoundingBoxOptimized(Document document, GridMap gridMap, HashSet channelItems, double scanHeight) + /// 最小通道顶面高度,用作扫描基准 + private void ProcessObstaclesWithBoundingBoxOptimized(Document document, GridMap gridMap, HashSet 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 /// 检查包围盒是否在扫描高度范围内 /// /// 包围盒 - /// 网格地图 + /// 最小通道顶面高度,用作扫描基准 /// 扫描高度范围 /// 是否在高度范围内 - 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); }