From ccdada3aadbfebae7d725048b3fb21a1a5c3e838 Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Fri, 19 Dec 2025 17:44:12 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86=E5=A2=99?=
=?UTF-8?q?=E5=92=8C=E6=9F=B1=E5=AD=90=E6=A3=80=E6=B5=8B=E4=B8=8D=E5=88=B0?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
NavisworksTransport.UnitTests.csproj | 9 ++++
src/Core/Animation/PathAnimationManager.cs | 3 +-
src/Core/Spatial/SpatialHashGrid.cs | 60 +++++++++++++++++-----
src/Core/Spatial/SpatialIndexManager.cs | 8 +--
4 files changed, 62 insertions(+), 18 deletions(-)
diff --git a/NavisworksTransport.UnitTests.csproj b/NavisworksTransport.UnitTests.csproj
index 77f2cd6..219f778 100644
--- a/NavisworksTransport.UnitTests.csproj
+++ b/NavisworksTransport.UnitTests.csproj
@@ -79,6 +79,12 @@
packages\RoyT.AStar.3.0.2\lib\netstandard2.0\Roy-T.AStar.dll
True
+
+
+
+ packages\geometry4Sharp.1.0.0\lib\net462\geometry4Sharp.dll
+ True
+
@@ -88,6 +94,9 @@
+
+
+
diff --git a/src/Core/Animation/PathAnimationManager.cs b/src/Core/Animation/PathAnimationManager.cs
index 8de88ad..4b8bfa2 100644
--- a/src/Core/Animation/PathAnimationManager.cs
+++ b/src/Core/Animation/PathAnimationManager.cs
@@ -446,7 +446,8 @@ namespace NavisworksTransport.Core.Animation
boundingBoxSize.Y * boundingBoxSize.Y +
boundingBoxSize.Z * boundingBoxSize.Z
);
- searchRadiusInModelUnits = objectDiagonal / 2 + _detectionGap;
+ //空间查询半径,不能设置太小,否则会漏掉周围的对象
+ searchRadiusInModelUnits = objectDiagonal + _detectionGap;
LogManager.Info($"空间查询半径: {searchRadiusInModelUnits:F2} 模型单位");
}
diff --git a/src/Core/Spatial/SpatialHashGrid.cs b/src/Core/Spatial/SpatialHashGrid.cs
index 007135d..e3090a7 100644
--- a/src/Core/Spatial/SpatialHashGrid.cs
+++ b/src/Core/Spatial/SpatialHashGrid.cs
@@ -60,32 +60,65 @@ namespace NavisworksTransport.Core.Spatial
}
///
- /// 插入对象到空间哈希网格
+ /// 插入对象到空间哈希网格(边界框版本)
+ /// 对象将被插入到其边界框覆盖的所有格子中
///
/// 要插入的对象
- /// 对象的3D位置
- public void Insert(T item, Vector3d position)
+ /// 边界框最小点
+ /// 边界框最大点
+ public void Insert(T item, Vector3d boundsMin, Vector3d boundsMax)
{
- var gridCell = _indexer.ToGrid(position);
+ // 计算边界框覆盖的格子范围
+ var minGridCell = _indexer.ToGrid(boundsMin);
+ var maxGridCell = _indexer.ToGrid(boundsMax);
- if (!_grid.TryGetValue(gridCell, out var cellList))
+ // 遍历边界框覆盖的所有格子
+ for (int x = minGridCell.x; x <= maxGridCell.x; x++)
{
- cellList = new List();
- _grid[gridCell] = cellList;
- }
+ for (int y = minGridCell.y; y <= maxGridCell.y; y++)
+ {
+ for (int z = minGridCell.z; z <= maxGridCell.z; z++)
+ {
+ var gridCell = new Vector3i(x, y, z);
- cellList.Add(item);
+ if (!_grid.TryGetValue(gridCell, out var cellList))
+ {
+ cellList = new List();
+ _grid[gridCell] = cellList;
+ }
+
+ cellList.Add(item);
+ }
+ }
+ }
}
+
+
+ ///
+ /// 插入对象到空间哈希网格(使用 Navisworks BoundingBox3D)
+ /// 对象将被插入到其边界框覆盖的所有格子中
+ ///
+ /// 要插入的对象
+ /// Navisworks 边界框
+ public void Insert(T item, Autodesk.Navisworks.Api.BoundingBox3D bounds)
+ {
+ var boundsMin = new Vector3d(bounds.Min.X, bounds.Min.Y, bounds.Min.Z);
+ var boundsMax = new Vector3d(bounds.Max.X, bounds.Max.Y, bounds.Max.Z);
+ Insert(item, boundsMin, boundsMax);
+ }
+
+
+
///
/// 批量插入对象
///
- /// 对象和位置的键值对
- public void InsertRange(IEnumerable> items)
+ /// 对象和边界框的键值对
+ public void InsertRange(IEnumerable> items)
{
foreach (var kvp in items)
{
- Insert(kvp.Key, kvp.Value);
+ Insert(kvp.Key, kvp.Value.min, kvp.Value.max);
}
}
@@ -105,11 +138,12 @@ namespace NavisworksTransport.Core.Spatial
///
/// 范围查询:查找指定位置附近指定半径内的所有对象
+ /// 注意:由于对象可能被插入到多个格子中,使用 HashSet 自动去重
///
/// 查询中心位置
/// 查询半径(模型单位)
/// 可选的距离计算函数(用于精确过滤)
- /// 范围内的对象列表(去重)
+ /// 范围内的对象列表(自动去重)
public List FindInRadius(
Vector3d center,
double radius,
diff --git a/src/Core/Spatial/SpatialIndexManager.cs b/src/Core/Spatial/SpatialIndexManager.cs
index 55683a1..495f939 100644
--- a/src/Core/Spatial/SpatialIndexManager.cs
+++ b/src/Core/Spatial/SpatialIndexManager.cs
@@ -104,7 +104,7 @@ namespace NavisworksTransport.Core.Spatial
{
try
{
- // 获取包围盒中心作为对象位置
+ // 获取包围盒
var bbox = item.BoundingBox();
var center = new Vector3d(
(bbox.Min.X + bbox.Max.X) / 2.0,
@@ -112,10 +112,10 @@ namespace NavisworksTransport.Core.Spatial
(bbox.Min.Z + bbox.Max.Z) / 2.0
);
- // 插入到空间索引
- _globalSpatialIndex.Insert(item, center);
+ // 使用边界框插入到空间索引(支持大型对象覆盖多个格子)
+ _globalSpatialIndex.Insert(item, bbox);
- // 缓存位置
+ // 缓存位置(用于快速查询)
_objectPositions[item] = center;
indexedCount++;