BambuStudio学习笔记:AABBTreeIndirect

# AABBTreeIndirect 类详解

## 目录
1. [全面概述](#全面概述)  
2. [核心数据结构](#核心数据结构)  
3. [关键成员函数](#关键成员函数)  
4. [算法实现细节](#算法实现细节)  
5. [应用场景](#应用场景)  

---

## <a id="全面概述"></a>一、全面概述

`AABBTreeIndirect` 是一个**基于隐式平衡AABB树的高性能空间查询库**,专为处理大规模三维/二维几何数据设计。核心功能包括:

- **快速射线碰撞检测**:支持单点/多点命中查询
- **最近点搜索**:高效计算点到模型表面的最短距离
- **空间范围查询**:快速检索包围盒相交或包含的几何元素
- **多精度支持**:模板化实现兼容float/double精度
- **内存优化**:采用紧凑存储结构,减少缓存失效

适用于3D打印切片、物理引擎碰撞检测、CAD模型分析等场景。

---

## <a id="核心数据结构"></a>二、核心数据结构

### 1. Tree 模板类
```cpp
template<int ANumDimensions, typename ACoordType>
class Tree
  • 模板参数
    • ANumDimensions:空间维度(2/3)
    • ACoordType:坐标类型(float/double)
成员变量
变量名类型作用描述
m_nodesstd::vector<Node>平衡树节点存储池
Node 结构体
struct Node {
    size_t idx;       // 实体索引(npos=无效, inner=内部节点)
    BoundingBox bbox; // 包含epsilon的包围盒
};
  • 状态判断方法
    • is_valid(): 是否为有效节点
    • is_inner(): 是否为内部节点
    • is_leaf(): 是否为叶子节点

2. BoundingBoxWrapper

class BoundingBoxWrapper {
    BoundingBox m_bbox; // 带SCALED_EPSILON膨胀的包围盒
    size_t m_idx;       // 原始数据索引
}
  • 作用:将Slic3r的BoundingBox适配到Eigen格式

三、关键成员函数

1. 树构建

template<typename SourceNode>
void build(std::vector<SourceNode> &&input)
  • 流程
    1. 预分配完整二叉树内存 (next_highest_power_of_2)
    2. 递归分区构建平衡树
    3. 使用QuickSelect算法进行中值分割

2. 射线查询

bool intersect_ray_first_hit(...)
  • 参数
    • origin: 射线起点
    • dir: 归一化方向向量
    • hit: 输出首个命中结果
  • 实现
    • 基于ray_box_intersect_invdir快速排除
    • 使用Möller-Trumbore算法进行三角面相交测试

3. 最近点搜索

Scalar squared_distance_to_indexed_triangle_set(...)
  • 算法
    1. 遍历AABB树排除远距离节点
    2. 使用Ericson的最近点投影算法
    3. 动态维护最小距离剪枝

4. 空间遍历

template<typename Predicate, typename Fn>
void traverse(const Tree&, Predicate&&, Fn&&)
  • 谓词示例
    • intersecting(bbox): 包围盒相交
    • within(bbox): 完全包含
  • 用途:批量检索满足空间关系的几何元素

四、算法实现细节

1. 射线-包围盒相交测试

ray_box_intersect_invdir()
  • 优化:利用方向倒数预处理
  • 原理:基于"Akenine-Möller"算法,复杂度O(1)

2. 三角形快速分区

partition_input()
  • 策略
    • 三数取中法选择pivot
    • 双指针交替扫描实现O(n)分区

3. 隐式平衡树结构

  • 寻址规则
    • 左子节点:2*idx+1
    • 右子节点:2*idx+2
  • 优势:省去指针存储,提升缓存命中率

五、应用场景

1. 支撑结构生成

// 检测喷嘴与模型的碰撞
igl::Hit hit;
if(intersect_ray_first_hit(model_tree, nozzle_tip, down_dir, hit)) {
    adjust_nozzle_height(hit.t);
}

2. 模型误差检测

// 查找间距过小的表面
vector<size_t> close_faces = all_triangles_in_radius(
    model, tree, probe_point, (0.2*0.2));
if(!close_faces.empty()) {
    flag_as_overlapping(close_faces);
}

3. 三维拾取交互

// 鼠标点击选择面片
traverse(model_tree, intersecting(click_ray), [](const Node& node){
    if(auto hit = test_triangle_intersect(node.idx))
        select_face(hit.face_id);
});

性能优化要点

  1. SIMD加速ray_box_intersect_invdir可SSE向量化
  2. 内存布局:节点连续存储减少cache miss
  3. 精度控制:动态epsilon计算适应不同尺度模型
  4. 并行构建:OpenMP加速大规模模型建树

该实现相比普通BVH树,在百万面片级模型上可实现5-10倍的查询速度提升,内存占用减少约40%。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值