From 636defc9593de372e627fbf44066daac94570ec9 Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Thu, 6 Aug 2026 10:37:48 +0800
Subject: [PATCH] =?UTF-8?q?perf:=20AncestorsAndSelf=20=E5=90=8E=E5=BA=8F?=
=?UTF-8?q?=E4=BC=A0=E6=92=AD=EF=BC=88=E5=91=BD=E4=B8=AD=E8=B7=AF=E5=BE=84?=
=?UTF-8?q?=E7=A5=96=E5=85=88=E9=80=90=E5=B1=82=E4=B8=8A=E4=BC=A0=EF=BC=8C?=
=?UTF-8?q?=E6=B6=88=E9=99=A4=20K=C3=97D=20=E6=AC=A1=E6=9E=9A=E4=B8=BE?=
=?UTF-8?q?=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
TraverseAndCollect 改为返回 bool(子树是否有盒内对象):
- 命中时只 visibleSet.Add(item) 自己
- 组节点 children 循环后:任一子命中 → 自己加入 visibleSet(post-order 上传)
- 共享祖先只被加入一次,AncestorsAndSelf 枚举完全消除
验证:
- 盒内对象/隐藏节点与优化前完全一致(228/4928)✓
- Architecture.nwd:~273ms → ~265ms(命中数小时收益小;大模型命中数大时更明显)
- 集成测试 25/25
---
src/Core/SectionBoxExporter.cs | 36 +++++++++++++++++++++-------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/src/Core/SectionBoxExporter.cs b/src/Core/SectionBoxExporter.cs
index a2e54ae..5eefeb8 100644
--- a/src/Core/SectionBoxExporter.cs
+++ b/src/Core/SectionBoxExporter.cs
@@ -305,12 +305,13 @@ namespace NavisworksTransport.Core
}
///
- /// 递归遍历收集盒内对象和可见节点
+ /// 递归遍历收集盒内对象和可见节点。
+ /// 返回:本子树是否存在盒内对象(后序传播用——命中路径的祖先由父级逐层加入 visibleSet)。
///
- private void TraverseAndCollect(ModelItem item, BoundingBox3D sectionBox,
+ private bool TraverseAndCollect(ModelItem item, BoundingBox3D sectionBox,
List objectsInBox, HashSet visibleSet, bool prune)
{
- if (item == null || item.IsHidden) return;
+ if (item == null || item.IsHidden) return false;
bool hasGeometry = item.HasGeometry;
@@ -323,7 +324,7 @@ namespace NavisworksTransport.Core
var groupBox = item.BoundingBox();
if (!BoundingBoxesIntersect(groupBox, sectionBox))
{
- return;
+ return false;
}
}
@@ -338,27 +339,34 @@ namespace NavisworksTransport.Core
double sizeZ = bbox.Max.Z - bbox.Min.Z;
bool hasVolume = sizeX > 0.0001 && sizeY > 0.0001 && sizeZ > 0.0001;
- // 有体积且与剖面盒相交 → 是目标对象
+ // 有体积且与剖面盒相交 → 是目标对象(只加入自己,祖先由父级后序上传)
if (hasVolume && BoundingBoxesIntersect(bbox, sectionBox))
{
objectsInBox.Add(item);
-
- // 将该对象及其所有祖先标记为可见
- foreach (var ancestor in item.AncestorsAndSelf)
- {
- visibleSet.Add(ancestor);
- }
+ visibleSet.Add(item);
+ return true;
}
// 找到几何体,停止向下遍历(原逻辑)
- return;
+ return false;
}
- // 没有几何体,继续遍历子节点
+ // 没有几何体,继续遍历子节点;后序传播:任一子命中 → 自己是祖先,加入 visibleSet
+ bool anyChildHit = false;
foreach (var child in item.Children)
{
- TraverseAndCollect(child, sectionBox, objectsInBox, visibleSet, prune);
+ if (TraverseAndCollect(child, sectionBox, objectsInBox, visibleSet, prune))
+ {
+ anyChildHit = true;
+ }
}
+
+ if (anyChildHit)
+ {
+ visibleSet.Add(item);
+ }
+
+ return anyChildHit;
}
///