From 8a95820fca3ae1d1b8f61e83688ecaf7fda06a53 Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Sun, 28 Sep 2025 16:20:04 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E9=80=9A=E9=81=93?=
=?UTF-8?q?=E7=BD=91=E6=A0=BC=E7=94=9F=E6=88=90=E7=9A=84=E9=AB=98=E5=BA=A6?=
=?UTF-8?q?=E8=AE=BE=E7=BD=AE=EF=BC=8C=E8=83=BD=E5=9C=A8=E6=96=9C=E9=9D=A2?=
=?UTF-8?q?=E4=B8=8A=E7=94=9F=E6=88=90=E7=BD=91=E6=A0=BC=EF=BC=8C=E5=8F=AF?=
=?UTF-8?q?=E8=A7=86=E5=8C=96=E4=B9=9F=E5=AF=B9=E4=BA=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CLAUDE.md | 9 -
NavisworksTransportPlugin.csproj | 2 -
doc/requirement/todo_features.md | 8 +
.../Collision/ClashDetectiveIntegration.cs | 2 +-
src/Core/PathPlanningManager.cs | 11 +-
.../Properties/CategoryAttributeManager.cs | 29 +-
src/PathPlanning/AutoPathFinder.cs | 6 +-
src/PathPlanning/ChannelBasedGridBuilder.cs | 131 ++-----
src/PathPlanning/ChannelHeightDetector.cs | 2 +-
src/PathPlanning/GridCache.cs | 331 ------------------
src/PathPlanning/GridCacheKey.cs | 185 ----------
src/PathPlanning/GridMap.cs | 39 +--
src/PathPlanning/GridMapCacheKey.cs | 12 +-
src/PathPlanning/GridMapGenerator.cs | 26 +-
src/PathPlanning/VerticalScanProcessor.cs | 2 +-
.../WPF/ViewModels/ModelSettingsViewModel.cs | 4 +-
src/Utils/GeometryHelper.cs | 6 +-
17 files changed, 88 insertions(+), 717 deletions(-)
delete mode 100644 src/PathPlanning/GridCache.cs
delete mode 100644 src/PathPlanning/GridCacheKey.cs
diff --git a/CLAUDE.md b/CLAUDE.md
index 5fcc41b..d86598a 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -80,14 +80,6 @@ Eight predefined categories with inheritance from parent to child nodes:
- 门 (Doors), 电梯 (Elevators), 楼梯 (Stairs), 通道 (Channels)
- 障碍物 (Obstacles), 装卸区 (Loading Zones), 停车区 (Parking), 检查点 (Checkpoints)
-## Development Guidelines
-
-### Claude Code Work Delegation Principle
-
-- **任何具体的开发工作,全部让子代理完成** - All concrete development work must be delegated to specialized sub-agents
-- Claude Code主要负责需求理解、任务分解和工作协调,不直接进行代码编写
-- 使用专业子代理处理具体实现:`navisworks-feature-developer`、`navisworks-api-researcher`、`navisworks-ui-designer`、`technical-architect`、`project-task-manager`
-
### Language and Communication
- **使用中文进行所有交流和代码注释** - Primary language for user interaction and code documentation
@@ -203,6 +195,5 @@ public class PathClickToolPlugin : ToolPlugin { }
- **2026 Features**: Test advanced animation capabilities, enhanced collision detection, and improved model handling
- 在编码中,不要用回退或向后兼容的思路和步骤
- 程序的日志在:C:\ProgramData\Autodesk\Navisworks Manage 2026\NavisworksTransport\logs\debug.log
-- 不要搞向后兼容
- 使用agent完成任务前,一定要先用Plan模式设计好方案和任务清单,并征得我同意。
- 网格坐标代表的是网格单元的左下角,而不是中心点!
\ No newline at end of file
diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj
index 680d9b3..99521aa 100644
--- a/NavisworksTransportPlugin.csproj
+++ b/NavisworksTransportPlugin.csproj
@@ -163,8 +163,6 @@
-
-
diff --git a/doc/requirement/todo_features.md b/doc/requirement/todo_features.md
index f1158dd..1412e2e 100644
--- a/doc/requirement/todo_features.md
+++ b/doc/requirement/todo_features.md
@@ -2,6 +2,14 @@
## 功能点
+### [2025/09/28]
+
+1. [x] (优化)识别表面不平的通道,给网格正确的表面z值
+
+### [2025/09/27]
+
+1. [x] (优化)为生成的网格地图增加缓存,提高路径规划性能
+
### [2025/09/15]
1. [x] (功能)修改碰撞检测报告,增加碰撞构件的数量和清单
diff --git a/src/Core/Collision/ClashDetectiveIntegration.cs b/src/Core/Collision/ClashDetectiveIntegration.cs
index 8a97b41..a0e8f9b 100644
--- a/src/Core/Collision/ClashDetectiveIntegration.cs
+++ b/src/Core/Collision/ClashDetectiveIntegration.cs
@@ -1113,7 +1113,7 @@ namespace NavisworksTransport
var document = Application.ActiveDocument;
// 获取所有可通行的物流模型项
- var allChannelItems = CategoryAttributeManager.GetAllTraversableLogisticsItems(document);
+ var allChannelItems = CategoryAttributeManager.GetAllTraversableLogisticsItems();
if (allChannelItems.Count == 0)
{
diff --git a/src/Core/PathPlanningManager.cs b/src/Core/PathPlanningManager.cs
index 68a5101..74a07a1 100644
--- a/src/Core/PathPlanningManager.cs
+++ b/src/Core/PathPlanningManager.cs
@@ -879,7 +879,6 @@ namespace NavisworksTransport
try
{
gridMap = gridMapGenerator.GenerateFromBIM(
- document,
bounds,
gridSize,
vehicleRadius,
@@ -1125,7 +1124,7 @@ namespace NavisworksTransport
var document = Application.ActiveDocument;
if (document != null)
{
- var allLogisticsItems = CategoryAttributeManager.GetAllLogisticsItems(document);
+ var allLogisticsItems = CategoryAttributeManager.GetAllLogisticsItems();
var channelItems = CategoryAttributeManager.FilterByLogisticsType(allLogisticsItems, CategoryAttributeManager.LogisticsElementType.通道);
_walkableAreas.AddRange(channelItems);
LogManager.Info($"[SelectChannels] 通过CategoryAttributeManager直接筛选到 {channelItems.Count} 个通道");
@@ -2239,7 +2238,7 @@ namespace NavisworksTransport
LogManager.Info("[通道自动选择] 开始搜索可通行的物流模型");
// 使用CategoryAttributeManager统一接口获取物流项目
- var allLogisticsItemsCollection = CategoryAttributeManager.GetAllLogisticsItems(document);
+ var allLogisticsItemsCollection = CategoryAttributeManager.GetAllLogisticsItems();
LogManager.Info($"[通道自动选择] CategoryAttributeManager找到 {allLogisticsItemsCollection.Count} 个具有物流属性的模型项");
// 筛选出可通行的物流模型
@@ -2562,7 +2561,7 @@ namespace NavisworksTransport
if (document?.Models != null)
{
// 使用CategoryAttributeManager统一接口获取物流项目
- var logisticsItemsCollection = CategoryAttributeManager.GetAllLogisticsItems(document);
+ var logisticsItemsCollection = CategoryAttributeManager.GetAllLogisticsItems();
LogManager.WriteLog($"[搜索通道] CategoryAttributeManager找到 {logisticsItemsCollection.Count} 个物流模型");
if (logisticsItemsCollection.Count > 0)
@@ -2873,7 +2872,7 @@ namespace NavisworksTransport
var document = Application.ActiveDocument;
if (document != null)
{
- var foundChannelsCollection = CategoryAttributeManager.GetAllLogisticsItems(document);
+ var foundChannelsCollection = CategoryAttributeManager.GetAllLogisticsItems();
foreach (ModelItem item in foundChannelsCollection)
{
channelItems.Add(item);
@@ -3291,7 +3290,7 @@ namespace NavisworksTransport
// 计算网格单元格的世界中心位置
var gridPos = new NavisworksTransport.PathPlanning.GridPoint2D(x, y);
- var gridCorner = gridMap.GridToWorld3D(gridPos, cell.WorldPosition.Z);
+ var gridCorner = gridMap.GridToWorld3D(gridPos);
var gridCenter = new Point3D(
gridCorner.X + gridMap.CellSize / 2,
gridCorner.Y + gridMap.CellSize / 2,
diff --git a/src/Core/Properties/CategoryAttributeManager.cs b/src/Core/Properties/CategoryAttributeManager.cs
index d5c72b3..2c42b32 100644
--- a/src/Core/Properties/CategoryAttributeManager.cs
+++ b/src/Core/Properties/CategoryAttributeManager.cs
@@ -115,7 +115,7 @@ namespace NavisworksTransport
}
// 准备属性字典
- var properties = new System.Collections.Generic.Dictionary
+ var properties = new Dictionary
{
{ LogisticsProperties.TYPE, elementType.ToString() },
{ LogisticsProperties.TRAVERSABLE, isTraversable ? "是" : "否" },
@@ -126,7 +126,7 @@ namespace NavisworksTransport
};
// 准备内部名称字典
- var propertyInternalNames = new System.Collections.Generic.Dictionary
+ var propertyInternalNames = new Dictionary
{
{ LogisticsProperties.TYPE, elementType.ToString() + "_Internal" },
{ LogisticsProperties.TRAVERSABLE, "Traversable_Internal" },
@@ -212,22 +212,11 @@ namespace NavisworksTransport
/// 物流元素类型
/// 文档,如果为null则使用ActiveDocument
/// 指定类型的物流项目列表
- public static List GetLogisticsItemsByType(LogisticsElementType elementType, Document document = null)
+ public static List GetLogisticsItemsByType(LogisticsElementType elementType)
{
try
{
- // 如果没有提供文档,使用ActiveDocument
- if (document == null)
- document = Application.ActiveDocument;
-
- // 检查文档有效性
- if (document?.Models == null)
- {
- LogManager.Warning($"[CategoryAttributeManager] 无法获取文档模型");
- return new List();
- }
-
- // 直接使用 Search API 搜索整个文档
+ // 使用 Search API 搜索当前活动文档
using (var search = new Search())
{
// 搜索整个文档的根项及其所有后代
@@ -246,7 +235,7 @@ namespace NavisworksTransport
.EqualValue(VariantData.FromDisplayString(elementType.ToString())));
// 执行搜索并返回列表
- return search.FindAll(document, false).ToList();
+ return search.FindAll(Application.ActiveDocument, false).ToList();
}
}
catch (Exception ex)
@@ -358,7 +347,7 @@ namespace NavisworksTransport
///
/// Navisworks文档
/// 具有物流属性的模型项集合
- public static ModelItemCollection GetAllLogisticsItems(Document document)
+ public static ModelItemCollection GetAllLogisticsItems()
{
try
{
@@ -369,7 +358,7 @@ namespace NavisworksTransport
searchConditions.Clear();
var hasLogisticsCondition = SearchCondition.HasCategoryByDisplayName(LogisticsCategories.LOGISTICS);
searchConditions.Add(hasLogisticsCondition);
- return search.FindAll(document, false);
+ return search.FindAll(Application.ActiveDocument, false);
}
}
catch (Exception ex)
@@ -384,9 +373,9 @@ namespace NavisworksTransport
///
/// Navisworks文档
/// 可通行的物流模型项集合
- public static ModelItemCollection GetAllTraversableLogisticsItems(Document document)
+ public static ModelItemCollection GetAllTraversableLogisticsItems()
{
- var allLogisticsItems = GetAllLogisticsItems(document);
+ var allLogisticsItems = GetAllLogisticsItems();
return FilterTraversableItems(allLogisticsItems);
}
diff --git a/src/PathPlanning/AutoPathFinder.cs b/src/PathPlanning/AutoPathFinder.cs
index 2a31e6b..301a9a3 100644
--- a/src/PathPlanning/AutoPathFinder.cs
+++ b/src/PathPlanning/AutoPathFinder.cs
@@ -1354,12 +1354,12 @@ namespace NavisworksTransport.PathPlanning
var actualEndGridY = (int)Math.Floor(lastNode.Position.Y / cellSizeInMeters);
var actualEndGrid = new GridPoint2D(actualEndGridX, actualEndGridY);
var actualEndCell = gridMap.GetCell(actualEndGrid);
- var actualEndWorld = gridMap.GridToWorld3D(actualEndGrid, actualEndCell?.WorldPosition.Z ?? 0);
+ var actualEndWorld = gridMap.GridToWorld3D(actualEndGrid);
var originalEndCell = gridMap.GetCell(endGrid);
- var originalEndWorld = gridMap.GridToWorld3D(endGrid, originalEndCell?.WorldPosition.Z ?? 0);
+ var originalEndWorld = gridMap.GridToWorld3D(endGrid);
var startWorldCell = gridMap.GetCell(startGrid);
- var startWorld = gridMap.GridToWorld3D(startGrid, startWorldCell?.WorldPosition.Z ?? 0);
+ var startWorld = gridMap.GridToWorld3D(startGrid);
var totalDistance = CalculateDistance(startWorld, originalEndWorld);
var actualDistance = CalculateDistance(startWorld, actualEndWorld);
diff --git a/src/PathPlanning/ChannelBasedGridBuilder.cs b/src/PathPlanning/ChannelBasedGridBuilder.cs
index ae48cd8..922e34b 100644
--- a/src/PathPlanning/ChannelBasedGridBuilder.cs
+++ b/src/PathPlanning/ChannelBasedGridBuilder.cs
@@ -56,16 +56,13 @@ namespace NavisworksTransport.PathPlanning
/// 网格单元格大小
/// 当前文档
/// 通道覆盖信息
- public ChannelCoverage BuildChannelCoverage(double gridSize, Document document = null)
+ public ChannelCoverage BuildChannelCoverage(double gridSize)
{
- if (document == null)
- document = Application.ActiveDocument;
-
LogManager.Info("[通道网格构建器] 开始构建通道覆盖网格");
// 1. 获取所有通道物品
var channelItems = CategoryAttributeManager.GetLogisticsItemsByType(
- CategoryAttributeManager.LogisticsElementType.通道, document);
+ CategoryAttributeManager.LogisticsElementType.通道);
if (!channelItems.Any())
{
@@ -119,34 +116,13 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info($"[通道网格构建器] 投影通道: {channel.DisplayName}");
// 提取三角形几何
- var triangles = GeometryHelper.ExtractTrianglesOptimized(channel);
+ var triangles = GeometryHelper.ExtractTriangles(channel);
if (triangles.Count == 0)
{
LogManager.Warning($"[通道网格构建器] 未能从 '{channel.DisplayName}' 提取到三角形");
return;
}
-
- // 分析通道类型
- var channelType = AnalyzeChannelType(triangles);
-
- // 统计三角形方向分布(用于调试)
- int upFaces = 0, inclinedFaces = 0, downFaces = 0, sideFaces = 0;
- foreach (var triangle in triangles)
- {
- var normal = ComputeTriangleNormal(triangle);
- if (normal.Z > 0.7)
- upFaces++;
- else if (normal.Z > 0.2)
- inclinedFaces++;
- else if (normal.Z < -0.2)
- downFaces++;
- else
- sideFaces++;
- }
-
- LogManager.Info($"[通道网格构建器] 通道类型: {channelType}");
- LogManager.Info($"[通道网格构建器] 三角形分布: 朝上={upFaces}, 朝上斜面={inclinedFaces}, 朝下={downFaces}, 侧面={sideFaces}, 总计={triangles.Count}");
-
+
// 统一投影处理
int processedTriangles = 0;
foreach (var triangle in triangles)
@@ -154,18 +130,11 @@ namespace NavisworksTransport.PathPlanning
var normal = ComputeTriangleNormal(triangle);
// 根据法向量决定处理方式
- if (normal.Z > 0.7) // 朝上的水平面
+ if (normal.Z > 0) // 朝上的面
{
RasterizeTriangleToGrid(gridMap, triangle);
processedTriangles++;
}
- else if (normal.Z > 0.2) // 可行走的斜面(楼梯、坡道)
- {
- // 对于斜面,也进行投影,适用于楼梯等倾斜通道
- // [TODO] 斜面应该用不同的计算顶面高度方法
- RasterizeTriangleToGrid(gridMap, triangle);
- processedTriangles++;
- }
// 垂直面和朝下的面不投影
}
@@ -205,6 +174,15 @@ namespace NavisworksTransport.PathPlanning
return normal;
}
+ private double GetHeightAtPoint(Triangle3D triangle, double x, double y)
+ {
+ var normal = ComputeTriangleNormal(triangle);
+
+ // 使用平面方程计算点(x,y)在三角形平面上的Z值
+ double height = triangle.Point1.Z - (normal.X * (x - triangle.Point1.X) + normal.Y * (y - triangle.Point1.Y)) / normal.Z;
+ return height;
+ }
+
///
/// 将三角形光栅化到网格
@@ -222,9 +200,6 @@ namespace NavisworksTransport.PathPlanning
var minGrid = gridMap.WorldToGrid(new Point3D(minX, minY, 0));
var maxGrid = gridMap.WorldToGrid(new Point3D(maxX, maxY, 0));
- // 计算三角形的平均高度作为通道顶面高度
- double triangleHeight = (triangle.Point1.Z + triangle.Point2.Z + triangle.Point3.Z) / 3.0;
-
// 遍历边界框内的所有网格点
for (int x = minGrid.X; x <= maxGrid.X; x++)
{
@@ -233,13 +208,30 @@ namespace NavisworksTransport.PathPlanning
var gridPos = new GridPoint2D(x, y);
if (gridMap.IsValidGridPosition(gridPos))
{
- var worldPos = gridMap.GridToWorld3D(gridPos, 0); // 2D检测,Z坐标不重要
+ var worldPos = gridMap.GridToWorld3D(gridPos);
// 检查点是否在三角形内部
if (GeometryHelper.IsPointInTriangle2D(worldPos, triangle))
{
- // 传递实际的三角形高度
- SetCellAsChannel(gridMap, gridPos, null, triangleHeight);
+ // 计算网格中心点在三角形平面上的精确高度
+ double gridCenterHeight = GetHeightAtPoint(triangle, worldPos.X, worldPos.Y);
+
+ // 调试日志:打印生成的网格坐标和高度
+ LogManager.Debug($"[调试] 生成通道网格: ({gridPos.X}, {gridPos.Y}) 高度: {gridCenterHeight:F2}");
+
+ // 直接设置网格属性
+ var cell = new GridCell
+ {
+ IsWalkable = true,
+ CellType = CategoryAttributeManager.LogisticsElementType.通道,
+ IsInChannel = true,
+ PassableHeights = new List(),
+ ChannelType = ChannelType.Corridor,
+ WorldPosition = new Point3D(worldPos.X, worldPos.Y, gridCenterHeight),
+ RelatedModelItem = null
+ };
+ cell.Cost = cell.GetCost();
+ gridMap.Cells[gridPos.X, gridPos.Y] = cell;
}
}
}
@@ -247,17 +239,6 @@ namespace NavisworksTransport.PathPlanning
}
- ///
- /// 设置网格单元为通道类型
- ///
- /// 网格地图
- /// 网格位置
- /// 关联的模型物品
- private void SetCellAsChannel(GridMap gridMap, GridPoint2D gridPos, ModelItem relatedItem, double channelHeight = 0.0)
- {
- // 使用GridMap提供的方法设置通道单元格,传递实际高度
- gridMap.SetCellAsChannel(gridPos, ChannelType.Corridor, relatedItem, channelHeight);
- }
///
@@ -275,50 +256,6 @@ namespace NavisworksTransport.PathPlanning
};
}
- ///
- /// 分析通道几何类型
- ///
- /// 三角形列表
- /// 通道几何类型
- private ChannelGeometryType AnalyzeChannelType(List triangles)
- {
- if (triangles.Count == 0)
- return ChannelGeometryType.Complex;
-
- int upwardHorizontalCount = 0; // 朝上的水平面
- int upwardInclinedCount = 0; // 朝上的斜面
- int upwardCount = 0; // 所有朝上的面
-
- foreach (var triangle in triangles)
- {
- var normal = ComputeTriangleNormal(triangle);
-
- // 只统计朝上的面(与投影逻辑一致)
- if (normal.Z > 0.7)
- {
- upwardHorizontalCount++;
- upwardCount++;
- }
- else if (normal.Z > 0.2) // 朝上的斜面
- {
- upwardInclinedCount++;
- upwardCount++;
- }
- // 忽略朝下和侧面的三角形
- }
-
- // 基于朝上三角形的比例判断类型
- if (upwardCount == 0)
- return ChannelGeometryType.Complex;
-
- if (upwardHorizontalCount > upwardCount * 0.6)
- return ChannelGeometryType.Horizontal; // 主要是水平面
- else if (upwardInclinedCount > upwardCount * 0.3)
- return ChannelGeometryType.Inclined; // 有较多斜面
- else
- return ChannelGeometryType.Complex;
- }
-
///
/// 格式化边界框信息用于日志
///
diff --git a/src/PathPlanning/ChannelHeightDetector.cs b/src/PathPlanning/ChannelHeightDetector.cs
index 30f6b2f..4cc5c20 100644
--- a/src/PathPlanning/ChannelHeightDetector.cs
+++ b/src/PathPlanning/ChannelHeightDetector.cs
@@ -655,7 +655,7 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info($"[COM几何射线] 开始从ModelItem提取三角形几何数据: {channel.DisplayName}");
// 使用COM API提取三角形几何数据
- var triangles = GeometryHelper.ExtractTrianglesOptimized(channel);
+ var triangles = GeometryHelper.ExtractTriangles(channel);
if (triangles.Count == 0)
{
LogManager.Warning($"[COM几何射线] 未能从ModelItem提取到三角形数据: {channel.DisplayName}");
diff --git a/src/PathPlanning/GridCache.cs b/src/PathPlanning/GridCache.cs
deleted file mode 100644
index c40b7ef..0000000
--- a/src/PathPlanning/GridCache.cs
+++ /dev/null
@@ -1,331 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using Roy_T.AStar.Grids;
-
-namespace NavisworksTransport.PathPlanning
-{
- ///
- /// 缓存项,包含网格和访问时间信息
- ///
- public class GridCacheItem
- {
- ///
- /// 缓存的A*网格
- ///
- public Grid Grid { get; set; }
-
- ///
- /// 最后访问时间
- ///
- public DateTime LastAccessTime { get; set; }
-
- ///
- /// 创建时间
- ///
- public DateTime CreatedTime { get; set; }
-
- ///
- /// 访问次数
- ///
- public int AccessCount { get; set; }
-
- ///
- /// 构造函数
- ///
- public GridCacheItem(Grid grid)
- {
- Grid = grid ?? throw new ArgumentNullException(nameof(grid));
- LastAccessTime = DateTime.Now;
- CreatedTime = DateTime.Now;
- AccessCount = 1;
- }
-
- ///
- /// 记录访问
- ///
- public void RecordAccess()
- {
- LastAccessTime = DateTime.Now;
- AccessCount++;
- }
- }
-
- ///
- /// 网格缓存统计信息
- ///
- public class GridCacheStatistics
- {
- ///
- /// 缓存命中次数
- ///
- public long HitCount { get; set; }
-
- ///
- /// 缓存未命中次数
- ///
- public long MissCount { get; set; }
-
- ///
- /// 当前缓存项数量
- ///
- public int CurrentCount { get; set; }
-
- ///
- /// 最大缓存项数量
- ///
- public int MaxCapacity { get; set; }
-
- ///
- /// 被驱逐的缓存项数量
- ///
- public long EvictedCount { get; set; }
-
- ///
- /// 缓存命中率
- ///
- public double HitRate => HitCount + MissCount > 0 ? (double)HitCount / (HitCount + MissCount) : 0.0;
-
- ///
- /// 缓存使用率
- ///
- public double UsageRate => MaxCapacity > 0 ? (double)CurrentCount / MaxCapacity : 0.0;
-
- ///
- /// 重置统计信息
- ///
- public void Reset()
- {
- HitCount = 0;
- MissCount = 0;
- EvictedCount = 0;
- }
-
- ///
- /// 生成统计报告
- ///
- public string GenerateReport()
- {
- return $"网格缓存统计 - 命中率: {HitRate:P2} ({HitCount}命中/{MissCount}未命中), " +
- $"使用率: {UsageRate:P2} ({CurrentCount}/{MaxCapacity}), " +
- $"驱逐次数: {EvictedCount}";
- }
- }
-
- ///
- /// 网格缓存管理器
- /// 使用LRU策略管理A*网格缓存,支持线程安全访问
- ///
- public class GridCache
- {
- private readonly ConcurrentDictionary _cache;
- private readonly object _cleanupLock = new object();
- private readonly int _maxCapacity;
- private readonly GridCacheStatistics _statistics;
-
- ///
- /// 获取缓存统计信息
- ///
- public GridCacheStatistics Statistics => _statistics;
-
- ///
- /// 构造函数
- ///
- /// 最大缓存容量,默认20个网格
- public GridCache(int maxCapacity = 20)
- {
- if (maxCapacity <= 0)
- throw new ArgumentException("缓存容量必须大于0", nameof(maxCapacity));
-
- _maxCapacity = maxCapacity;
- _cache = new ConcurrentDictionary();
- _statistics = new GridCacheStatistics { MaxCapacity = maxCapacity };
-
- LogManager.Info($"[网格缓存] 初始化完成,最大容量: {_maxCapacity}");
- }
-
- ///
- /// 获取缓存的网格
- ///
- /// 缓存键
- /// 网格对象,如果不存在则返回null
- public Grid Get(GridCacheKey key)
- {
- if (key == null)
- return null;
-
- if (_cache.TryGetValue(key, out var item))
- {
- // 记录访问
- item.RecordAccess();
- _statistics.HitCount++;
-
- LogManager.Debug($"[网格缓存] 命中 - {key},访问次数: {item.AccessCount}");
- return item.Grid;
- }
-
- _statistics.MissCount++;
- LogManager.Debug($"[网格缓存] 未命中 - {key}");
- return null;
- }
-
- ///
- /// 添加网格到缓存
- ///
- /// 缓存键
- /// A*网格
- public void Put(GridCacheKey key, Grid grid)
- {
- if (key == null || grid == null)
- return;
-
- var item = new GridCacheItem(grid);
-
- // 添加或更新缓存项
- _cache.AddOrUpdate(key, item, (k, existing) =>
- {
- LogManager.Debug($"[网格缓存] 更新现有项 - {key}");
- return item;
- });
-
- // 更新统计信息
- _statistics.CurrentCount = _cache.Count;
-
- LogManager.Debug($"[网格缓存] 添加 - {key},当前容量: {_cache.Count}/{_maxCapacity}");
-
- // 检查是否需要清理
- if (_cache.Count > _maxCapacity)
- {
- CleanupCache();
- }
- }
-
- ///
- /// 检查缓存中是否包含指定键
- ///
- /// 缓存键
- /// 是否包含
- public bool ContainsKey(GridCacheKey key)
- {
- return key != null && _cache.ContainsKey(key);
- }
-
- ///
- /// 清除所有缓存
- ///
- public void Clear()
- {
- lock (_cleanupLock)
- {
- var count = _cache.Count;
- _cache.Clear();
- _statistics.CurrentCount = 0;
- _statistics.Reset();
-
- LogManager.Info($"[网格缓存] 清除所有缓存,共清除 {count} 项");
- }
- }
-
- ///
- /// 获取缓存的所有键
- ///
- /// 键列表
- public IList GetKeys()
- {
- return _cache.Keys.ToList();
- }
-
- ///
- /// 清理缓存,使用LRU策略移除最少使用的项
- ///
- private void CleanupCache()
- {
- lock (_cleanupLock)
- {
- // 双重检查,避免重复清理
- if (_cache.Count <= _maxCapacity)
- return;
-
- var targetCount = (int)(_maxCapacity * 0.8); // 清理到80%容量
- var itemsToRemove = _cache.Count - targetCount;
-
- LogManager.Info($"[网格缓存] 开始LRU清理,当前: {_cache.Count},目标: {targetCount},需移除: {itemsToRemove}");
-
- // 按最后访问时间排序,移除最久未访问的项
- var sortedItems = _cache
- .OrderBy(kvp => kvp.Value.LastAccessTime)
- .ThenBy(kvp => kvp.Value.AccessCount) // 相同时间的情况下,优先移除访问次数少的
- .Take(itemsToRemove)
- .ToList();
-
- int removedCount = 0;
- foreach (var item in sortedItems)
- {
- if (_cache.TryRemove(item.Key, out _))
- {
- removedCount++;
- _statistics.EvictedCount++;
- LogManager.Debug($"[网格缓存] 移除 - {item.Key},最后访问: {item.Value.LastAccessTime:yyyy-MM-dd HH:mm:ss}");
- }
- }
-
- _statistics.CurrentCount = _cache.Count;
- LogManager.Info($"[网格缓存] LRU清理完成,实际移除: {removedCount},当前容量: {_cache.Count}");
- }
- }
-
- ///
- /// 生成缓存详细报告
- ///
- /// 报告字符串
- public string GenerateDetailedReport()
- {
- var report = new System.Text.StringBuilder();
-
- report.AppendLine(_statistics.GenerateReport());
-
- if (_cache.Count > 0)
- {
- report.AppendLine($"\n当前缓存项详情:");
- var sortedItems = _cache
- .OrderByDescending(kvp => kvp.Value.LastAccessTime)
- .Take(10) // 只显示最近10项
- .ToList();
-
- foreach (var item in sortedItems)
- {
- report.AppendLine($" {item.Key} - 访问{item.Value.AccessCount}次,最后访问: {item.Value.LastAccessTime:MM-dd HH:mm:ss}");
- }
-
- if (_cache.Count > 10)
- {
- report.AppendLine($" ... 还有 {_cache.Count - 10} 项");
- }
- }
-
- return report.ToString();
- }
- }
-
- ///
- /// 全局网格缓存管理器(单例)
- ///
- public static class GlobalGridCache
- {
- private static readonly Lazy _instance = new Lazy(() => new GridCache());
-
- ///
- /// 获取全局缓存实例
- ///
- public static GridCache Instance => _instance.Value;
-
- ///
- /// 重置全局缓存(主要用于测试)
- ///
- public static void Reset()
- {
- _instance.Value.Clear();
- }
- }
-}
\ No newline at end of file
diff --git a/src/PathPlanning/GridCacheKey.cs b/src/PathPlanning/GridCacheKey.cs
deleted file mode 100644
index bfcb542..0000000
--- a/src/PathPlanning/GridCacheKey.cs
+++ /dev/null
@@ -1,185 +0,0 @@
-using System;
-using System.Security.Cryptography;
-using System.Text;
-
-namespace NavisworksTransport.PathPlanning
-{
- ///
- /// 网格缓存键,用于标识唯一的网格配置
- /// 包含所有影响网格生成的因素:网格地图内容、车辆高度、路径策略、网格尺寸
- ///
- public class GridCacheKey : IEquatable
- {
- ///
- /// 网格地图内容哈希值
- ///
- public string GridMapHash { get; set; }
-
- ///
- /// 车辆高度(模型单位)
- ///
- public double VehicleHeight { get; set; }
-
- ///
- /// 路径规划策略
- ///
- public PathStrategy Strategy { get; set; }
-
- ///
- /// 网格单元大小(模型单位)
- ///
- public double CellSize { get; set; }
-
- ///
- /// 构造函数
- ///
- /// 网格地图哈希
- /// 车辆高度
- /// 路径策略
- /// 网格尺寸
- public GridCacheKey(string gridMapHash, double vehicleHeight, PathStrategy strategy, double cellSize)
- {
- GridMapHash = gridMapHash ?? throw new ArgumentNullException(nameof(gridMapHash));
- VehicleHeight = vehicleHeight;
- Strategy = strategy;
- CellSize = cellSize;
- }
-
- ///
- /// 检查两个缓存键是否相等
- ///
- public bool Equals(GridCacheKey other)
- {
- if (other == null) return false;
- if (ReferenceEquals(this, other)) return true;
-
- return GridMapHash == other.GridMapHash &&
- Math.Abs(VehicleHeight - other.VehicleHeight) < 1e-6 &&
- Strategy == other.Strategy &&
- Math.Abs(CellSize - other.CellSize) < 1e-6;
- }
-
- ///
- /// 重写Equals方法
- ///
- public override bool Equals(object obj)
- {
- return Equals(obj as GridCacheKey);
- }
-
- ///
- /// 计算哈希码,用于Dictionary键
- ///
- public override int GetHashCode()
- {
- unchecked
- {
- int hash = 17;
- hash = hash * 23 + (GridMapHash?.GetHashCode() ?? 0);
- hash = hash * 23 + VehicleHeight.GetHashCode();
- hash = hash * 23 + Strategy.GetHashCode();
- hash = hash * 23 + CellSize.GetHashCode();
- return hash;
- }
- }
-
- ///
- /// 生成可读的字符串表示
- ///
- public override string ToString()
- {
- var hashPreview = GridMapHash != null ?
- GridMapHash.Substring(0, Math.Min(8, GridMapHash.Length)) :
- "NULL";
- return $"GridCacheKey[Hash={hashPreview}, " +
- $"Height={VehicleHeight:F2}, Strategy={Strategy}, CellSize={CellSize:F2}]";
- }
-
- ///
- /// 根据GridMap和参数生成缓存键
- ///
- /// 网格地图
- /// 车辆高度
- /// 路径策略
- /// 缓存键
- public static GridCacheKey CreateFrom(GridMap gridMap, double vehicleHeight, PathStrategy strategy)
- {
- if (gridMap == null)
- throw new ArgumentNullException(nameof(gridMap));
-
- var gridMapHash = ComputeGridMapHash(gridMap);
- return new GridCacheKey(gridMapHash, vehicleHeight, strategy, gridMap.CellSize);
- }
-
- ///
- /// 计算GridMap的内容哈希值
- /// 基于网格尺寸、单元格可通行性、高度约束等关键数据
- ///
- /// 网格地图
- /// SHA256哈希字符串
- private static string ComputeGridMapHash(GridMap gridMap)
- {
- try
- {
- using (var sha256 = SHA256.Create())
- {
- var hashBuilder = new StringBuilder();
-
- // 基础属性
- hashBuilder.Append($"W:{gridMap.Width}|H:{gridMap.Height}|CS:{gridMap.CellSize:F6}|");
- hashBuilder.Append($"OX:{gridMap.Origin.X:F6}|OY:{gridMap.Origin.Y:F6}|OZ:{gridMap.Origin.Z:F6}|");
-
- // 遍历所有网格单元
- for (int x = 0; x < gridMap.Width; x++)
- {
- for (int y = 0; y < gridMap.Height; y++)
- {
- var cell = gridMap.Cells[x, y];
-
- // 基本属性
- hashBuilder.Append($"[{x},{y}]:{(cell.IsWalkable ? "1" : "0")}|{cell.CellType}|");
-
- // 世界位置
- hashBuilder.Append($"WP:{cell.WorldPosition.X:F3},{cell.WorldPosition.Y:F3},{cell.WorldPosition.Z:F3}|");
-
- // 高度约束区间
- if (cell.PassableHeights != null && cell.PassableHeights.Count > 0)
- {
- hashBuilder.Append("PH:");
- foreach (var interval in cell.PassableHeights)
- {
- hashBuilder.Append($"{interval.MinZ:F3}-{interval.MaxZ:F3},");
- }
- hashBuilder.Append("|");
- }
- else
- {
- hashBuilder.Append("PH:NONE|");
- }
- }
- }
-
- // 计算哈希
- var hashInput = hashBuilder.ToString();
- var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(hashInput));
-
- // 转换为十六进制字符串
- var hexBuilder = new StringBuilder();
- foreach (byte b in hashBytes)
- {
- hexBuilder.Append(b.ToString("x2"));
- }
-
- return hexBuilder.ToString();
- }
- }
- catch (Exception ex)
- {
- // 如果哈希计算失败,返回基于时间戳的唯一标识
- // 这样可以确保缓存不会错误命中,但会失去缓存效果
- LogManager.Warning($"[网格哈希] 计算网格哈希失败: {ex.Message},使用时间戳标识");
- return $"HASH_FAILED_{DateTime.Now.Ticks}";
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/PathPlanning/GridMap.cs b/src/PathPlanning/GridMap.cs
index 66f1fb2..a8f0cb8 100644
--- a/src/PathPlanning/GridMap.cs
+++ b/src/PathPlanning/GridMap.cs
@@ -205,10 +205,11 @@ namespace NavisworksTransport.PathPlanning
/// 网格坐标
/// Z坐标值
/// 世界3D坐标点
- public Point3D GridToWorld3D(GridPoint2D gridPosition, double z)
+ public Point3D GridToWorld3D(GridPoint2D gridPosition)
{
var world2D = GridToWorld2D(gridPosition);
- return new Point3D(world2D.X, world2D.Y, z);
+ var cell = Cells[gridPosition.X, gridPosition.Y];
+ return new Point3D(world2D.X, world2D.Y, cell.WorldPosition.Z);
}
@@ -249,8 +250,7 @@ namespace NavisworksTransport.PathPlanning
if (!IsValidGridPosition(gridPosition))
return;
- var existingZ = Cells[gridPosition.X, gridPosition.Y].WorldPosition.Z;
- var worldPos = GridToWorld3D(gridPosition, existingZ);
+ var worldPos = GridToWorld3D(gridPosition);
var cell = new GridCell
{
IsWalkable = isWalkable,
@@ -277,37 +277,6 @@ namespace NavisworksTransport.PathPlanning
Cells[gridPosition.X, gridPosition.Y] = cell;
}
- ///
- /// 设置网格单元为通道类型 - A*改进方案新增方法
- ///
- /// 网格坐标
- /// 通道类型
- /// 关联的模型物品
- public void SetCellAsChannel(GridPoint2D gridPosition, ChannelType channelType = ChannelType.Corridor, ModelItem relatedItem = null, double channelHeight = 0.0)
- {
- if (!IsValidGridPosition(gridPosition))
- return;
-
- // 使用传入的通道高度,如果没有提供则使用现有的Z坐标或边界最大Z
- double actualZ = channelHeight > 0 ? channelHeight :
- (Cells[gridPosition.X, gridPosition.Y].WorldPosition.Z > 0 ?
- Cells[gridPosition.X, gridPosition.Y].WorldPosition.Z :
- Bounds.Max.Z);
-
- var worldPos = GridToWorld3D(gridPosition, actualZ);
- var cell = new GridCell
- {
- IsWalkable = true,
- CellType = CategoryAttributeManager.LogisticsElementType.通道,
- IsInChannel = true,
- PassableHeights = new List(),
- ChannelType = channelType,
- WorldPosition = worldPos,
- RelatedModelItem = relatedItem
- };
- cell.Cost = cell.GetCost(); // 用GetCost方法计算通道成本
- Cells[gridPosition.X, gridPosition.Y] = cell;
- }
///
/// 添加可通行高度区间到指定网格单元
diff --git a/src/PathPlanning/GridMapCacheKey.cs b/src/PathPlanning/GridMapCacheKey.cs
index a85d0a8..244a51d 100644
--- a/src/PathPlanning/GridMapCacheKey.cs
+++ b/src/PathPlanning/GridMapCacheKey.cs
@@ -125,14 +125,11 @@ namespace NavisworksTransport.PathPlanning
/// 安全间隙(米)
/// 车辆高度(米)
/// 缓存键
- public static GridMapCacheKey CreateFrom(Document document, BoundingBox3D bounds,
+ public static GridMapCacheKey CreateFrom(BoundingBox3D bounds,
double cellSize, double vehicleRadius,
double safetyMargin, double vehicleHeight)
{
- if (document == null)
- throw new ArgumentNullException(nameof(document));
-
- var channelDataHash = ComputeChannelDataHash(document);
+ var channelDataHash = ComputeChannelDataHash();
var boundsHash = ComputeBoundsHash(bounds);
return new GridMapCacheKey(channelDataHash, boundsHash, cellSize,
@@ -143,9 +140,8 @@ namespace NavisworksTransport.PathPlanning
/// 计算通道数据哈希值
/// 基于所有可通行物流构件的ID、属性、几何等信息
///
- /// Navisworks文档
/// 通道数据哈希
- private static string ComputeChannelDataHash(Document document)
+ private static string ComputeChannelDataHash()
{
try
{
@@ -154,7 +150,7 @@ namespace NavisworksTransport.PathPlanning
var hashBuilder = new StringBuilder();
// 获取所有可通行的物流模型项
- var allChannelItems = CategoryAttributeManager.GetAllTraversableLogisticsItems(document);
+ var allChannelItems = CategoryAttributeManager.GetAllTraversableLogisticsItems();
// 按InstanceGuid排序确保一致性
var sortedItems = allChannelItems.OrderBy(item => item.InstanceGuid.ToString()).ToList();
diff --git a/src/PathPlanning/GridMapGenerator.cs b/src/PathPlanning/GridMapGenerator.cs
index 0476995..b7addde 100644
--- a/src/PathPlanning/GridMapGenerator.cs
+++ b/src/PathPlanning/GridMapGenerator.cs
@@ -53,12 +53,12 @@ namespace NavisworksTransport.PathPlanning
/// 规划终点
/// 车辆高度(米)
/// 生成的网格地图
- public GridMap GenerateFromBIM(Document document, BoundingBox3D bounds, double cellSize, double vehicleRadius, double safetyMargin, Point3D planningStartPoint, Point3D planningEndPoint, double vehicleHeight)
+ public GridMap GenerateFromBIM(BoundingBox3D bounds, double cellSize, double vehicleRadius, double safetyMargin, Point3D planningStartPoint, Point3D planningEndPoint, double vehicleHeight)
{
try
{
// 生成缓存键
- var cacheKey = GridMapCacheKey.CreateFrom(document, bounds, cellSize, vehicleRadius, safetyMargin, vehicleHeight);
+ var cacheKey = GridMapCacheKey.CreateFrom(bounds, cellSize, vehicleRadius, safetyMargin, vehicleHeight);
// 尝试从缓存获取
var cachedGridMap = GlobalGridMapCache.Instance.Get(cacheKey, 5000); // 预估生成需要5秒
@@ -102,7 +102,7 @@ namespace NavisworksTransport.PathPlanning
// 1. 使用通道构建器构建基础通道覆盖网格
LogManager.Info("【生成网格地图】步骤1: 构建通道覆盖网格");
- var channelCoverage = _channelBuilder.BuildChannelCoverage(cellSizeInModelUnits, document);
+ var channelCoverage = _channelBuilder.BuildChannelCoverage(cellSizeInModelUnits);
LogManager.Info($"【生成网格地图】通道覆盖构建完成: {channelCoverage.GetStatistics()}");
LogManager.Info($"【阶段1完成】通道覆盖网格统计: {channelCoverage.GridMap.GetStatistics()}");
@@ -111,7 +111,7 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info("【生成网格地图】步骤1.5: 智能收集通道相关节点");
// 直接获取所有可通行的物流模型项
- var allChannelItems = CategoryAttributeManager.GetAllTraversableLogisticsItems(document);
+ var allChannelItems = CategoryAttributeManager.GetAllTraversableLogisticsItems();
LogManager.Info($"【生成网格地图】直接获取到 {allChannelItems.Count} 个可通行物流元素");
// 智能收集可通行模型相关节点(包括父节点、同级节点等)
@@ -120,7 +120,7 @@ namespace NavisworksTransport.PathPlanning
// 2. 直接遍历处理障碍物(包围盒检测) - 使用高性能优化版本
LogManager.Info("【生成网格地图】步骤2: 高性能包围盒遍历处理障碍物");
- ProcessObstaclesWithBoundingBoxOptimized(document, channelCoverage.GridMap, channelRelatedItems, scanHeightInModelUnits);
+ ProcessObstaclesWithBoundingBoxOptimized(channelCoverage.GridMap, channelRelatedItems, scanHeightInModelUnits);
LogManager.Info($"【阶段2完成】障碍物处理后网格统计: {channelCoverage.GridMap.GetStatistics()}");
@@ -292,8 +292,8 @@ namespace NavisworksTransport.PathPlanning
var cell = gridMap.Cells[x, y];
// 更新门网格的Z坐标为门底部位置
- var worldPos = gridMap.GridToWorld3D(gridPos, doorBottomZ);
- cell.WorldPosition = worldPos;
+ var world2D = gridMap.GridToWorld2D(gridPos);
+ cell.WorldPosition = new Point3D(world2D.X, world2D.Y, doorBottomZ);
// 将门的高度范围存储在PassableHeights中供后续使用(使用相对坐标)
if (doorHeight > 0)
@@ -407,7 +407,7 @@ namespace NavisworksTransport.PathPlanning
if (cell.CellType == CategoryAttributeManager.LogisticsElementType.通道 && cell.IsInChannel)
{
// 使用网格的实际Z坐标
- var worldPos = gridMap.GridToWorld3D(new GridPoint2D(x, y), cell.WorldPosition.Z);
+ var worldPos = gridMap.GridToWorld3D(new GridPoint2D(x, y));
// 重要修复:使用通道顶面作为垂直扫描的起点,而不是底面
// 从通道构建器的日志可知通道总边界MaxZ = 38.8,这是正确的扫描起点
@@ -942,7 +942,7 @@ namespace NavisworksTransport.PathPlanning
/// 使用Search API一次性获取所有有几何体的模型项
/// 这比逐项调用HasGeometry快得多
///
- private List GetGeometryItemsUsingSearchAPI(Document document)
+ private List GetGeometryItemsUsingSearchAPI()
{
try
{
@@ -950,7 +950,7 @@ namespace NavisworksTransport.PathPlanning
var startTime = DateTime.Now;
// 统计模型总数
- var totalModelItems = document.Models.RootItemDescendantsAndSelf.Count();
+ var totalModelItems = Application.ActiveDocument.Models.RootItemDescendantsAndSelf.Count();
LogManager.Info($"[Search API优化] 模型总数统计: {totalModelItems} 个模型项");
var search = new Search();
@@ -963,7 +963,7 @@ namespace NavisworksTransport.PathPlanning
search.Locations = SearchLocations.DescendantsAndSelf;
// 一次性获取所有有几何体的项目
- var geometryItems = search.FindAll(document, false);
+ var geometryItems = search.FindAll(Application.ActiveDocument, false);
var searchElapsed = (DateTime.Now - startTime).TotalMilliseconds;
var filteredByGeometry = totalModelItems - geometryItems.Count();
@@ -1146,7 +1146,7 @@ namespace NavisworksTransport.PathPlanning
/// 网格地图
/// 通道模型项列表
/// 扫描高度范围(模型单位)
- private void ProcessObstaclesWithBoundingBoxOptimized(Document document, GridMap gridMap, HashSet channelItems, double scanHeightInModelUnits)
+ private void ProcessObstaclesWithBoundingBoxOptimized(GridMap gridMap, HashSet channelItems, double scanHeightInModelUnits)
{
try
{
@@ -1156,7 +1156,7 @@ namespace NavisworksTransport.PathPlanning
var channelItemsSet = channelItems ?? new HashSet();
// 阶段1:Search API预筛选(一次性批量获取几何体项目)
- var geometryItems = GetGeometryItemsUsingSearchAPI(document);
+ var geometryItems = GetGeometryItemsUsingSearchAPI();
LogManager.Info($"[高性能障碍物处理] 输入统计 - 几何体项目: {geometryItems.Count}, 通道元素: {channelItemsSet.Count}");
diff --git a/src/PathPlanning/VerticalScanProcessor.cs b/src/PathPlanning/VerticalScanProcessor.cs
index 3480b89..62d15d5 100644
--- a/src/PathPlanning/VerticalScanProcessor.cs
+++ b/src/PathPlanning/VerticalScanProcessor.cs
@@ -842,7 +842,7 @@ namespace NavisworksTransport.PathPlanning
return null;
// 直接提取模型项的三角形几何数据
- var triangles = GeometryHelper.ExtractTrianglesOptimized(item);
+ var triangles = GeometryHelper.ExtractTriangles(item);
if (triangles == null || triangles.Count == 0)
{
return null;
diff --git a/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs b/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs
index 76cda16..3a4a6f2 100644
--- a/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs
+++ b/src/UI/WPF/ViewModels/ModelSettingsViewModel.cs
@@ -716,7 +716,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
// 直接使用 CategoryAttributeManager 的 API
var document = NavisApplication.ActiveDocument;
- var logisticsItems = CategoryAttributeManager.GetAllLogisticsItems(document);
+ var logisticsItems = CategoryAttributeManager.GetAllLogisticsItems();
var models = new List();
foreach (var item in logisticsItems)
@@ -1121,7 +1121,7 @@ namespace NavisworksTransport.UI.WPF.ViewModels
return;
}
- var logisticsItems = CategoryAttributeManager.GetAllLogisticsItems(document);
+ var logisticsItems = CategoryAttributeManager.GetAllLogisticsItems();
if (logisticsItems == null || logisticsItems.Count == 0)
{
diff --git a/src/Utils/GeometryHelper.cs b/src/Utils/GeometryHelper.cs
index 131b671..5bea062 100644
--- a/src/Utils/GeometryHelper.cs
+++ b/src/Utils/GeometryHelper.cs
@@ -100,7 +100,7 @@ namespace NavisworksTransport
}
// 使用优化的几何提取方法
- var triangles = ExtractTrianglesOptimized(targetItem);
+ var triangles = ExtractTriangles(targetItem);
LogManager.WriteLog($"提取到 {triangles.Count} 个三角形");
if (triangles.Count > 0)
@@ -124,11 +124,11 @@ namespace NavisworksTransport
}
///
- /// 优化的三角形提取方法
+ /// 提取三角形
///
/// 模型项
/// 三角形集合
- public static List ExtractTrianglesOptimized(ModelItem modelItem)
+ public static List ExtractTriangles(ModelItem modelItem)
{
var triangles = new List();