feat: 添加通道对象排除逻辑到空间索引

修改内容:
1. 在 ClashDetectiveIntegration 中添加 IsChannelObjectPublic() 公开方法
2. SpatialIndexManager.BuildGlobalIndex() 构建索引前调用 BuildChannelObjectsCache()
3. 索引循环中过滤通道对象,避免将其加入空间索引
4. 增强日志输出,显示排除的通道对象数量

技术细节:
- 使用已有的 _channelObjectsCache 进行 O(1) 查询
- 在索引构建时过滤(一次性)而非每次查询时过滤
- 保持与旧架构相同的通道排除逻辑

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
tian 2025-10-14 12:05:05 +08:00
parent c7f6586fa9
commit f761d93676
2 changed files with 29 additions and 3 deletions

View File

@ -1098,6 +1098,16 @@ namespace NavisworksTransport
}
}
/// <summary>
/// 公开方法:检查物体是否为通道物体(供外部使用)
/// </summary>
/// <param name="item">要检查的模型对象</param>
/// <returns>如果是通道对象返回 true</returns>
public bool IsChannelObjectPublic(ModelItem item)
{
return IsChannelObject(item);
}
/// <summary>
/// 构建通道对象缓存,一次性扫描所有对象,避免重复的属性查询
/// </summary>

View File

@ -6,6 +6,9 @@ using Autodesk.Navisworks.Api;
using NavisworksTransport.Utils;
using g4; // geometry4Sharp
// 使用命名空间引用以避免类名冲突
using ClashIntegration = NavisworksTransport.ClashDetectiveIntegration;
namespace NavisworksTransport.Core.Spatial
{
/// <summary>
@ -79,12 +82,16 @@ namespace NavisworksTransport.Core.Spatial
{
_cellSize = cellSizeInModelUnits;
// 0. 构建通道对象缓存(用于排除通道)
ClashIntegration.Instance.BuildChannelObjectsCache();
ClashIntegration.BuildAllGeometryItemsCache();
// 1. 获取所有几何对象
var allItems = Application.ActiveDocument.Models.RootItemDescendantsAndSelf
.Where(item => item.HasGeometry)
.ToList();
LogManager.Info($"[空间索引] 找到 {allItems.Count} 个几何对象");
LogManager.Info($"[空间索引] 找到 {allItems.Count} 个几何对象(含通道)");
if (allItems.Count == 0)
{
@ -96,14 +103,22 @@ namespace NavisworksTransport.Core.Spatial
_globalSpatialIndex = new SpatialHashGrid<ModelItem>(cellSizeInModelUnits);
_objectPositions.Clear();
// 3. 索引所有对象
// 3. 索引所有对象(排除通道对象)
int indexedCount = 0;
int failedCount = 0;
int channelExcludedCount = 0;
foreach (var item in allItems)
{
try
{
// 排除通道对象
if (ClashIntegration.Instance.IsChannelObjectPublic(item))
{
channelExcludedCount++;
continue;
}
// 获取包围盒中心作为对象位置
var bbox = item.BoundingBox();
var center = new Vector3d(
@ -134,6 +149,7 @@ namespace NavisworksTransport.Core.Spatial
LogManager.Info("[空间索引] 构建完成");
LogManager.Info($" - 成功索引: {indexedCount} 个对象");
LogManager.Info($" - 排除通道: {channelExcludedCount} 个对象");
LogManager.Info($" - 失败: {failedCount} 个对象");
LogManager.Info($" - 格子数量: {_globalSpatialIndex.CellCount} 个");
LogManager.Info($" - 耗时: {sw.ElapsedMilliseconds} ms");