修复部分墙和柱子检测不到的问题
This commit is contained in:
parent
d9c2ec8c12
commit
ccdada3aad
@ -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" />
|
||||
|
||||
|
||||
@ -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} 模型单位");
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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++;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user