From f5d1361146ab57f9276230a96a104fb42ced9ef7 Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Mon, 6 Oct 2025 21:31:09 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA=E2=80=9C?=
=?UTF-8?q?=E6=97=A0=E5=85=B3=E9=A1=B9=E2=80=9D=E7=9A=84=E7=89=A9=E6=B5=81?=
=?UTF-8?q?=E7=B1=BB=E5=9E=8B=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=BF=87=E6=BB=A4?=
=?UTF-8?q?=E5=A6=82=E5=9C=B0=E5=9F=BA=E3=80=81=E5=BB=BA=E7=AD=91=E7=BB=93?=
=?UTF-8?q?=E6=9E=84=E7=AD=89=E4=B8=8E=E7=89=A9=E6=B5=81=E6=97=A0=E5=85=B3?=
=?UTF-8?q?=E7=9A=84=E6=9E=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.claude/config.json | 3 +
.../Properties/CategoryAttributeManager.cs | 7 +-
src/PathPlanning/GridMapGenerator.cs | 105 +++++++++++-------
3 files changed, 73 insertions(+), 42 deletions(-)
create mode 100644 .claude/config.json
diff --git a/.claude/config.json b/.claude/config.json
new file mode 100644
index 0000000..b82eeec
--- /dev/null
+++ b/.claude/config.json
@@ -0,0 +1,3 @@
+{
+ "primaryApiKey": "api"
+}
\ No newline at end of file
diff --git a/src/Core/Properties/CategoryAttributeManager.cs b/src/Core/Properties/CategoryAttributeManager.cs
index a73479e..2e94c11 100644
--- a/src/Core/Properties/CategoryAttributeManager.cs
+++ b/src/Core/Properties/CategoryAttributeManager.cs
@@ -86,7 +86,12 @@ namespace NavisworksTransport
///
/// 停车位 - 可通行,权重0.9
///
- 停车位 = 9
+ 停车位 = 9,
+
+ ///
+ /// 无关项 - 不参与网格生成的大型构件(如地基、结构基础等)
+ ///
+ 无关项 = 10
}
///
diff --git a/src/PathPlanning/GridMapGenerator.cs b/src/PathPlanning/GridMapGenerator.cs
index 495f785..66db9d7 100644
--- a/src/PathPlanning/GridMapGenerator.cs
+++ b/src/PathPlanning/GridMapGenerator.cs
@@ -111,16 +111,27 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info("【生成网格地图】步骤1.5: 智能收集通道相关节点");
// 直接获取所有可通行的物流模型项
- var allChannelItems = CategoryAttributeManager.GetAllTraversableLogisticsItems();
- LogManager.Info($"【生成网格地图】直接获取到 {allChannelItems.Count} 个可通行物流元素");
+ var allTraversableItems = CategoryAttributeManager.GetAllTraversableLogisticsItems();
+ LogManager.Info($"【生成网格地图】直接获取到 {allTraversableItems.Count} 个可通行物流元素");
// 智能收集可通行模型相关节点(包括父节点、同级节点等)
- var channelRelatedItems = CollectChannelRelatedItems(allChannelItems.ToList());
- LogManager.Info($"【生成网格地图】智能收集到 {channelRelatedItems.Count} 个通道相关节点");
-
+ var traversableRelatedItems = CollectRelatedItems(allTraversableItems.ToList());
+ LogManager.Info($"【生成网格地图】智能收集到 {traversableRelatedItems.Count} 个可通行元素相关节点");
+
+ // 1.6. 批量获取所有"无关项"(不参与网格生成的大型构件)
+ LogManager.Info("【生成网格地图】步骤1.6: 批量获取无关项并收集相关节点");
+ var irrelevantItems = CategoryAttributeManager.GetLogisticsItemsByType(
+ CategoryAttributeManager.LogisticsElementType.无关项);
+ LogManager.Info($"【生成网格地图】直接获取到 {irrelevantItems.Count} 个无关项");
+
+ // 智能收集无关项相关节点(包括子节点等)
+ var irrelevantRelatedItems = CollectRelatedItems(irrelevantItems);
+ LogManager.Info($"【生成网格地图】智能收集到 {irrelevantRelatedItems.Count} 个无关项相关节点(将被排除)");
+ var irrelevantItemsSet = irrelevantRelatedItems; // 使用收集后的完整集合
+
// 2. 直接遍历处理障碍物(包围盒检测) - 使用高性能优化版本
LogManager.Info("【生成网格地图】步骤2: 高性能包围盒遍历处理障碍物");
- ProcessObstaclesWithBoundingBox(channelCoverage.GridMap, channelRelatedItems, scanHeightInModelUnits, channelCoverage);
+ ProcessObstaclesWithBoundingBox(channelCoverage.GridMap, traversableRelatedItems, scanHeightInModelUnits, channelCoverage, irrelevantItemsSet);
LogManager.Info($"【阶段2完成】障碍物处理后网格统计: {channelCoverage.GridMap.GetStatistics()}");
@@ -131,7 +142,7 @@ namespace NavisworksTransport.PathPlanning
// 2.6. 单独处理门元素,设置为可通行,并设置通行高度
LogManager.Info("【生成网格地图】步骤2.6: 处理门元素");
- ProcessDoorElements(channelCoverage.GridMap, allChannelItems);
+ ProcessDoorElements(channelCoverage.GridMap, allTraversableItems);
LogManager.Info($"【阶段2.6完成】门元素处理后网格统计: {channelCoverage.GridMap.GetStatistics()}");
// 3. 应用车辆尺寸膨胀(如果需要)
@@ -156,10 +167,10 @@ namespace NavisworksTransport.PathPlanning
}
// 将通道数据设置到GridMap中,供后续PathPlanningManager使用
- if (channelRelatedItems != null && channelRelatedItems.Any())
+ if (traversableRelatedItems != null && traversableRelatedItems.Any())
{
- channelCoverage.GridMap.ChannelItems = channelRelatedItems.ToList();
- LogManager.Info($"【生成网格地图】已将 {channelRelatedItems.Count} 个通道数据设置到GridMap中");
+ channelCoverage.GridMap.ChannelItems = traversableRelatedItems.ToList();
+ LogManager.Info($"【生成网格地图】已将 {traversableRelatedItems.Count} 个通道数据设置到GridMap中");
}
else if (channelCoverage.ChannelItems != null && channelCoverage.ChannelItems.Any())
{
@@ -214,12 +225,12 @@ namespace NavisworksTransport.PathPlanning
///
/// 处理门元素,将其设置为可通行网格
///
- private void ProcessDoorElements(GridMap gridMap, ICollection allChannelItems)
+ private void ProcessDoorElements(GridMap gridMap, ICollection allTraversableItems)
{
try
{
// 过滤出门类型的元素
- var doorItems = FilterDoorItems(allChannelItems);
+ var doorItems = FilterDoorItems(allTraversableItems);
LogManager.Info($"【门元素处理】找到 {doorItems.Count} 个门元素");
if (!doorItems.Any())
@@ -920,41 +931,41 @@ namespace NavisworksTransport.PathPlanning
}
///
- /// 收集通道相关节点
+ /// 收集物流项目的相关节点
/// 根据节点类型决定收集策略:几何体节点收集父节点和同级节点,集合节点收集子节点
///
- /// 通道节点列表
+ /// 物流项目节点列表
/// 包含所有相关节点的集合
- private HashSet CollectChannelRelatedItems(List channelItems)
+ private HashSet CollectRelatedItems(List items)
{
var relatedItems = new HashSet();
-
- foreach (var channelItem in channelItems)
+
+ foreach (var item in items)
{
try
{
- LogManager.Info($"[通道收集] 开始处理通道节点: '{channelItem.DisplayName}'");
-
+ LogManager.Info($"[节点收集] 开始处理节点: '{item.DisplayName}'");
+
// 使用 ModelItemAnalysisHelper 的通用方法收集相关节点
- var itemRelatedNodes = ModelItemAnalysisHelper.CollectRelatedNodes(channelItem);
-
+ var itemRelatedNodes = ModelItemAnalysisHelper.CollectRelatedNodes(item);
+
// 将结果添加到 HashSet 中
foreach (var node in itemRelatedNodes)
{
relatedItems.Add(node);
}
-
- LogManager.Info($"[通道收集] 从 '{channelItem.DisplayName}' 收集到 {itemRelatedNodes.Count} 个相关节点");
+
+ LogManager.Info($"[节点收集] 从 '{item.DisplayName}' 收集到 {itemRelatedNodes.Count} 个相关节点");
}
catch (Exception ex)
{
- LogManager.Warning($"[通道收集] 处理通道节点 '{channelItem?.DisplayName ?? "NULL"}' 时出错: {ex.Message}");
- // 出错时至少保证通道本身被添加
- relatedItems.Add(channelItem);
+ LogManager.Warning($"[节点收集] 处理节点 '{item?.DisplayName ?? "NULL"}' 时出错: {ex.Message}");
+ // 出错时至少保证节点本身被添加
+ relatedItems.Add(item);
}
}
-
- LogManager.Info($"[通道收集] 共收集到 {relatedItems.Count} 个通道相关节点");
+
+ LogManager.Info($"[节点收集] 共收集到 {relatedItems.Count} 个相关节点");
return relatedItems;
}
@@ -1088,9 +1099,10 @@ namespace NavisworksTransport.PathPlanning
///
private Dictionary PostProcessGeometryItems(
List geometryItems,
- HashSet channelItemsSet,
+ HashSet traversableItemsSet,
GridMap gridMap,
- double scanHeightInModelUnits)
+ double scanHeightInModelUnits,
+ HashSet irrelevantItemsSet)
{
LogManager.Info("[轻量级后处理] 开始处理Search API筛选结果");
var startTime = DateTime.Now;
@@ -1099,6 +1111,7 @@ namespace NavisworksTransport.PathPlanning
var totalItems = geometryItems.Count;
var apiCalls = 0;
var skippedByChannel = 0;
+ var skippedByIrrelevant = 0;
var skippedByBoundingBox = 0;
foreach (var item in geometryItems)
@@ -1111,7 +1124,7 @@ namespace NavisworksTransport.PathPlanning
HasGeometry = true,
// 快速筛除1:通道相关项目(HashSet查找,极快)
- IsChannelItem = channelItemsSet.Contains(item)
+ IsChannelItem = traversableItemsSet.Contains(item)
};
if (properties.IsChannelItem)
{
@@ -1119,13 +1132,21 @@ namespace NavisworksTransport.PathPlanning
continue; // 跳过通道项目,不进行昂贵的API调用
}
- properties.IsChildOfChannel = IsChildOfChannelItems(item, channelItemsSet);
+ properties.IsChildOfChannel = IsChildOfChannelItems(item, traversableItemsSet);
if (properties.IsChildOfChannel)
{
skippedByChannel++;
continue; // 跳过通道子项目
}
-
+
+ // 快速筛除2:无关项(不参与网格生成的大型构件)
+ properties.IsIrrelevantItem = irrelevantItemsSet.Contains(item);
+ if (properties.IsIrrelevantItem)
+ {
+ skippedByIrrelevant++;
+ continue; // 跳过无关项,避免昂贵的BoundingBox API调用
+ }
+
// 设为已知值(避免后续筛选中的判断错误)
properties.IsContainer = false; // 基于测试验证,几何体项目都不是容器
@@ -1153,7 +1174,7 @@ namespace NavisworksTransport.PathPlanning
var elapsed = (DateTime.Now - startTime).TotalMilliseconds;
LogManager.Info($"[轻量级后处理] 完成,输入 {totalItems} 项,有效结果 {itemCache.Count} 项,API调用 {apiCalls} 次,耗时: {elapsed:F1}ms");
- LogManager.Info($"[轻量级后处理] 筛除统计 - 通道相关: {skippedByChannel}, 无边界框: {skippedByBoundingBox}");
+ LogManager.Info($"[轻量级后处理] 筛除统计 - 通道相关: {skippedByChannel}, 无关项: {skippedByIrrelevant}, 无边界框: {skippedByBoundingBox}");
LogManager.Info("[轻量级后处理] 已移除全局高度预过滤,将在障碍物遍历阶段进行精确高度检查");
return itemCache;
@@ -1167,22 +1188,23 @@ namespace NavisworksTransport.PathPlanning
/// 通道模型项列表
/// 扫描高度范围(模型单位)
/// 通道覆盖信息,包含通道边界
- private void ProcessObstaclesWithBoundingBox(GridMap gridMap, HashSet channelItems, double scanHeightInModelUnits, ChannelCoverage channelCoverage)
+ /// 无关项集合(不参与网格生成的大型构件)
+ private void ProcessObstaclesWithBoundingBox(GridMap gridMap, HashSet channelItems, double scanHeightInModelUnits, ChannelCoverage channelCoverage, HashSet irrelevantItemsSet)
{
try
{
LogManager.Info("[高性能障碍物处理] 开始处理障碍物 - Search API优化版本");
var startTime = DateTime.Now;
- var channelItemsSet = channelItems ?? new HashSet();
+ var traversableItemsSet = channelItems ?? new HashSet();
// 阶段1:Search API预筛选(一次性批量获取几何体项目)
var geometryItems = GetGeometryItemsUsingSearchAPI();
- LogManager.Info($"[高性能障碍物处理] 输入统计 - 几何体项目: {geometryItems.Count}, 通道元素: {channelItemsSet.Count}");
+ LogManager.Info($"[高性能障碍物处理] 输入统计 - 几何体项目: {geometryItems.Count}, 通道元素: {traversableItemsSet.Count}");
// 阶段2:轻量级后处理(只对预筛选结果进行必要的API调用)
- var itemCache = PostProcessGeometryItems(geometryItems, channelItemsSet, gridMap, scanHeightInModelUnits);
+ var itemCache = PostProcessGeometryItems(geometryItems, traversableItemsSet, gridMap, scanHeightInModelUnits, irrelevantItemsSet);
// 阶段3:条件过滤(并行数值计算)- 使用50%CPU核心优化
LogManager.Info("[高性能障碍物处理] 阶段3: 并行条件过滤");
@@ -1490,16 +1512,16 @@ namespace NavisworksTransport.PathPlanning
/// 检查模型项是否是通道项的子项
///
/// 要检查的模型项
- /// 通道项集合
+ /// 通道项集合
/// 是否是通道项的子项
- private bool IsChildOfChannelItems(ModelItem item, HashSet channelItemsSet)
+ private bool IsChildOfChannelItems(ModelItem item, HashSet traversableItemsSet)
{
try
{
var parent = item.Parent;
while (parent != null)
{
- if (channelItemsSet.Contains(parent))
+ if (traversableItemsSet.Contains(parent))
{
return true;
}
@@ -1526,6 +1548,7 @@ namespace NavisworksTransport.PathPlanning
public BoundingBox3D BoundingBox { get; set; }
public bool IsChannelItem { get; set; }
public bool IsChildOfChannel { get; set; }
+ public bool IsIrrelevantItem { get; set; }
public bool IsInScanHeightRange { get; set; }
}