修复部分墙和柱子检测不到的问题

This commit is contained in:
tian 2025-12-19 17:44:12 +08:00
parent d9c2ec8c12
commit ccdada3aad
4 changed files with 62 additions and 18 deletions

View File

@ -79,6 +79,12 @@
<HintPath>packages\RoyT.AStar.3.0.2\lib\netstandard2.0\Roy-T.AStar.dll</HintPath>
<Private>True</Private>
</Reference>
<!-- geometry4Sharp for 3D geometry operations -->
<Reference Include="geometry4Sharp">
<HintPath>packages\geometry4Sharp.1.0.0\lib\net462\geometry4Sharp.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
@ -88,6 +94,9 @@
<!-- A*算法问题检测测试 -->
<Compile Include="NavisworksTransport.UnitTests\AStarDebuggingTest.cs" />
<!-- 空间哈希网格测试 -->
<Compile Include="UnitTests\Core\Spatial\SpatialHashGridTest.cs" />
<!-- 测试辅助类 -->
<Compile Include="UnitTests\TestHelpers\TestViewModel.cs" />

View File

@ -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} 模型单位");
}

View File

@ -60,32 +60,65 @@ namespace NavisworksTransport.Core.Spatial
}
/// <summary>
/// 插入对象到空间哈希网格
/// 插入对象到空间哈希网格(边界框版本)
/// 对象将被插入到其边界框覆盖的所有格子中
/// </summary>
/// <param name="item">要插入的对象</param>
/// <param name="position">对象的3D位置</param>
public void Insert(T item, Vector3d position)
/// <param name="boundsMin">边界框最小点</param>
/// <param name="boundsMax">边界框最大点</param>
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<T>();
_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<T>();
_grid[gridCell] = cellList;
}
cellList.Add(item);
}
}
}
}
/// <summary>
/// 插入对象到空间哈希网格(使用 Navisworks BoundingBox3D
/// 对象将被插入到其边界框覆盖的所有格子中
/// </summary>
/// <param name="item">要插入的对象</param>
/// <param name="bounds">Navisworks 边界框</param>
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);
}
/// <summary>
/// 批量插入对象
/// </summary>
/// <param name="items">对象和位置的键值对</param>
public void InsertRange(IEnumerable<KeyValuePair<T, Vector3d>> items)
/// <param name="items">对象和边界框的键值对</param>
public void InsertRange(IEnumerable<KeyValuePair<T, (Vector3d min, Vector3d max)>> 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
/// <summary>
/// 范围查询:查找指定位置附近指定半径内的所有对象
/// 注意:由于对象可能被插入到多个格子中,使用 HashSet 自动去重
/// </summary>
/// <param name="center">查询中心位置</param>
/// <param name="radius">查询半径(模型单位)</param>
/// <param name="distanceFunc">可选的距离计算函数(用于精确过滤)</param>
/// <returns>范围内的对象列表(去重)</returns>
/// <returns>范围内的对象列表(自动去重)</returns>
public List<T> FindInRadius(
Vector3d center,
double radius,

View File

@ -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++;