Bounding Volume Hierarchy BVH in OpenCASCADE

eryar@163.com

Abstract. Bounding Volume Hierarchy(BVH) organizes geometric objects in the tree based on spatial relationships. Each node in the tree contains an axis-aligned bounding box of all the objects below it. Bounding volume hierarchies are used in many algorithms to support efficient operations on the sets of geometric objects, such as collision detection, ray-tracing, searching of nearest objects, and view frustum culling. The paper focus on the usage of BVH on TopoDS_Shape, and its application.

Key Words. BVH, Bounding Volume Hierarchy, Collision Detection

1.Introduction

层次包围盒(Bounding Volume Hierarchy, BVH)是一种基于物体的场景管理技术,广泛用于碰撞检测,光线追踪,视锥体物体剔除等场合。对于三维场景的实时渲染来说,BVH是最常用的数据结构。场景以层次树形结构进行组织,包含一个根节点、内部节点、叶子节点。树中的每个节点,包括叶子节点都有一个包围体,可以将其子树的所有几何体包围起来,这就是BVH名字的由来。如下图所示:

Figure 1. Simple Scene(left), BVH Scene Graph(right)

本文主要介绍OpenCASCADE中的BVH包及其应用,如碰撞检测。

2.Build BVH

在BVH包中的头文件里面找到BVH的作者:Denis BOGOLEPOV, Danila ULYANOV,在网上搜到他们的一篇论文:Real-Time SAH BVH Construction for Ray Tracing Dynamic Scenes. 因此,可知BVH中是应用SAH(Surface Area Heuristic)策略来构造BVH树的。根据BVH_BinnedBuilder头文件中的注释可知:



Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->//! Performs construction of BVH tree using binned SAH algorithm. Number
//! of bins controls BVH quality in cost of construction time (greater
//! better). For optimal results, use 32 - 48 bins. However, reasonable
//! performance is provided even for 4 - 8 bins (it is only 10-20% lower
//! in comparison with optimal settings). Note that multiple threads can
//! be used only with thread safe BVH primitive sets.

OpenCASCADE中也提供了其他的构造方法,如类BVH_LinearBuilder中使用了Spatial Morton codes方法:



Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->//! Performs fast BVH construction using LBVH building approach.
//! Algorithm uses spatial Morton codes to reduce the BVH construction
//! problem to a sorting problem (radix sort -- O(N) complexity). This
//! Linear Bounding Volume Hierarchy (LBVH) builder produces BVH trees
//! of lower quality compared to SAH-based BVH builders but it is over
//! an order of magnitude faster (up to 3M triangles per second).
//!
//! For more details see:
//! C. Lauterbach, M. Garland, S. Sengupta, D. Luebke, and D. Manocha.
//! Fast BVH construction on GPUs. Eurographics, 2009.

3.Traversal BVH

由类BVH_TreeBase可知,当得到BVH树后,可以取出节点索引的数组。下面给出将TopoDS_Shape的BVH树显示出来的示例代码:



Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->/*
Copyright(C) 2017 Shing Liu(eryar@163.com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

// Visual Studio 2013 & OpenCASCADE7.1.0
// 2017-04-18  20:52

#include <BRepExtrema_TriangleSet.hxx>

#include <BRepTools.hxx>
#include <BRep_Builder.hxx>

#include <TopoDS.hxx>

#include <TopExp_Explorer.hxx>

#include <BRepPrimAPI_MakeBox.hxx>

#include <BRepMesh_IncrementalMesh.hxx>

#pragma comment(lib, "TKernel.lib")
#pragma comment(lib, "TKMath.lib")

#pragma comment(lib, "TKG2d.lib")
#pragma comment(lib, "TKG3d.lib")
#pragma comment(lib, "TKGeomBase.lib")
#pragma comment(lib, "TKGeomAlgo.lib")

#pragma comment(lib, "TKBRep.lib")
#pragma comment(lib, "TKPrim.lib")
#pragma comment(lib, "TKMesh.lib")
#pragma comment(lib, "TKTopAlgo.lib")

void testBvh(const std::string& theFileName)
{
    BRep_Builder aBuilder;
    TopoDS_Compound aCompound;

TopoDS_Shape aShape;
    BRepTools::Read(aShape, theFileName.c_str(), aBuilder);

BRepExtrema_ShapeList aFaceList;
    for (TopExp_Explorer i(aShape, TopAbs_FACE); i.More(); i.Next())
    {
        aFaceList.Append(TopoDS::Face(i.Current()));
    }

aBuilder.MakeCompound(aCompound);

BRepMesh_IncrementalMesh aMesher(aShape, 1.0);

BRepExtrema_TriangleSet aTriangleSet(aFaceList);
    const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBvh = aTriangleSet.BVH();
    for (int i = 0; i < aBvh->Length(); i++)
    {
        const BVH_Vec4i& aNodeData = aBvh->NodeInfoBuffer()[i];

if (aNodeData.x() == 0)
        {
            // inner node.
            const BVH_Vec3d& aP1 = aBvh->MinPoint(aNodeData.y());
            const BVH_Vec3d& aP2 = aBvh->MaxPoint(aNodeData.y());

const BVH_Vec3d& aQ1 = aBvh->MinPoint(aNodeData.z());
            const BVH_Vec3d& aQ2 = aBvh->MaxPoint(aNodeData.z());

try
            {
                BRepPrimAPI_MakeBox aBoxMaker(gp_Pnt(aP1.x(), aP1.y(), aP1.z()),
                    gp_Pnt(aP2.x(), aP2.y(), aP2.z()));
                for (TopExp_Explorer i(aBoxMaker.Shape(), TopAbs_EDGE); i.More(); i.Next())
                {
                    aBuilder.Add(aCompound, i.Current());
                }
            }
            catch (Standard_Failure f)
            {
            }

try
            {
                BRepPrimAPI_MakeBox aBoxMaker(gp_Pnt(aQ1.x(), aQ1.y(), aQ1.z()),
                    gp_Pnt(aQ2.x(), aQ2.y(), aQ2.z()));
                for (TopExp_Explorer i(aBoxMaker.Shape(), TopAbs_EDGE); i.More(); i.Next())
                {
                    aBuilder.Add(aCompound, i.Current());
                }
            }
            catch (Standard_Failure f)
            {
            }
        }
        else
        {
            // leaves node.
            const BVH_Vec3d& aP1 = aBvh->MinPoint(i);
            const BVH_Vec3d& aP2 = aBvh->MaxPoint(i);

try
            {
                BRepPrimAPI_MakeBox aBoxMaker(gp_Pnt(aP1.x(), aP1.y(), aP1.z()),
                    gp_Pnt(aP2.x(), aP2.y(), aP2.z()));

aBuilder.Add(aCompound, aBoxMaker.Shape());
            }
            catch (Standard_Failure f)
            {
            }
        }
    }

BRepTools::Write(aCompound, "d:/bvh.brep");
}

int main(int argc, char* argv[])
{
    if (argc > 1)
    {
        testBvh(argv[1]);
    }

return 0;
}

由上述代码可知,当得到节点信息

const BVH_Vec4i& aNodeData = aBvh->NodeInfoBuffer()[i];

后,通过判断aNodeData.x()分量来确定此节点是内部节点还是叶子节点。显示OCC自带的螺旋桨模型的BVH如下图所示:

其中红色线框为内部节点,黄色实体模型是叶子节点。

4.BVH Application

BVH在OpenCASCADE中也有广泛地应用,如开源版本中的模型快速碰撞检测,使用类BRepExtrema_ShapeProximity. 模型选择操作,光线跟踪等算法中都有应用。

5.Conclusion

因为OpenCASCADE中构造BVH时依赖模型的网格三角形,所以BVH算法的应用的结果就依赖于网格化算法的质量了。如两个Topo形状碰撞检测时,网格化的质量越高,结果精度越高。如果用解析算法去对两个Topo形状做碰撞检测,也会涉及到解析算法的精度问题。

BVH结构广泛应用于碰撞检测、光线跟踪等算法中,大大提高程序性能。本文只是抛砖引玉,对BVH感兴趣的童鞋可以参考相关资料及OpenCASCADE中的代码实现,去深入学习应用。

6.References

1. Dmitry Sopin, Denis Bogolepov, Danila Ulyanov. Real-Time SAH BVH Construction for Ray Tracing Dynamic Scenes. http://graphicon.ru/html/2011/conference/gc2011Sopin.pdf

2. BVH with SAH. http://www.cnblogs.com/lookof/p/3546320.html

3. 3D游戏引擎中常见的三维场景管理方法. http://www.cnblogs.com/wangchengfeng/p/3495954.html

PDF Version: BVH in OpenCASCADE.pdf

Bounding Volume Hierarchy BVH in OpenCASCADE的更多相关文章

  1. BVH with SAH (Bounding Volume Hierarchy with Surface Area Heuristic)

      - BVH with SAH (Bounding Volume Hierarchy  with Surface Area Heuristic) -      0. Overview 包围层次盒(B ...

  2. Bounding Volume Hierarchies 加速结构

    背景   光线与物体求交是光线追踪的主要时间瓶颈.   如果不进行优化,则对每条光线,我们都需要遍历场景中的全部物体并求交.而现在想建模一个小物体的表面,往往要几千甚至几万个三角形,一个商业级产品,屏 ...

  3. Opencascade术语笔记。

    1. chamfer 倒角 vs fillet  圆角: 2.boolean operatiron(布尔操作): common(相加),fuse(相交),cut(相减): 3.depressions( ...

  4. 【Notes_9】现代图形学入门——光线追踪(基本原理)

    跟着闫令琪老师的课程学习,总结自己学习到的知识点 课程网址GAMES101 B站课程地址GAMES101 课程资料百度网盘[提取码:0000] 目录 光线追踪 为什么要光线追踪 soft shadow ...

  5. games101 - 4 - Ray Tracing

    games101 - 4 - Ray Tracing 目录 games101 - 4 - Ray Tracing 为什么需要Ray Tracing Recursive (Whitted-Style) ...

  6. PBRT笔记(2)——BVH

    BVH 构建BVH树分三步: 计算每个图元的边界信息并且存储在数组中 使用指定的方法构建树 优化树,使得树更加紧凑 //BVH边界信息,存储了图元号,包围盒以及中心点 struct BVHPrimit ...

  7. 空间划分的数据结构(网格/四叉树/八叉树/BSP树/k-d树/BVH/自定义划分)

    目录 网格 (Grid) 网格的应用 四叉树/八叉树 (Quadtree/Octree) 四叉树/八叉树的应用 BSP树 (Binary Space Partitioning Tree) 判断点在平面 ...

  8. 对pathtracing的一些个人理解

    本人水平有限,若有错误也请指正~ 上面说到pathtracing(pt)的一些优点和缺点,优点即其实现很简单,这就是大概为什么当今市面上流行的很多渲染器如今都相继采用pathtracing算法为核心进 ...

  9. 探究光线追踪技术及UE4的实现

    目录 一.光线追踪概述 1.1 光线追踪是什么 1.2 光线追踪的特点 1.3 光线追踪的历史 1.4 光线追踪的应用 二.光线追踪的原理 2.1 光线追踪的物理原理 2.2 光线追踪算法 2.3 R ...

随机推荐

  1. DGA特征挖掘

    摘自:https://paper.seebug.org/papers/Archive/drops2/%E7%94%A8%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E8%A ...

  2. 微信小程序领取卡券

    微信小程序领取卡券 标签(空格分隔): php 开发前需要准备的工作 1 小程序和公众号要有绑定 2 小程序和该公众号要绑定到同一个开发平台下 [https://open.weixin.qq.com/ ...

  3. Auto-Publishing and Monitoring APIs With Spring Boot--转

    原文地址:https://dzone.com/articles/auto-publishing-amp-monitoring-apis-with-spring-bo If you are headin ...

  4. Lua,github,nginx

    个人觉得这几种工具都是大学里,至少是前几年未曾出现于课本中或者图书馆中的.而如今确实某些公司赫然出现在招聘需求中的东西. 什么是Lua,为什么要用Lua——做手机游戏而被推广的.Lua原来早在93年就 ...

  5. 机器学习(七) PCA与梯度上升法 (下)

    五.高维数据映射为低维数据 换一个坐标轴.在新的坐标轴里面表示原来高维的数据. 低维 反向 映射为高维数据 PCA.py import numpy as np class PCA: def __ini ...

  6. <Sicily>Catch the thief

    一.题目描述 A thief has robbed a bank in city 1 and he wants to go to city N. The police know that the th ...

  7. Linux-TCP/IP, IPv4地址类别摘要

    TCP/IP分层:                 application layer                 transport layer                 internet ...

  8. SSD-tensorflow-3 重新训练模型(vgg16)

    一.修改pascalvoc_2007.py 生成自己的tfrecord文件后,修改训练数据shape——打开datasets文件夹中的pascalvoc_2007.py文件,根据自己训练数据修改:NU ...

  9. laravel 自定义全局函数

    在 app 目录下创建一个 Helpers 目录,在此目录下创建文件.这些文件就是全局函数文件.如叫:function.php 加载此文件: 1 . 在 bootstrap/autoload.php ...

  10. WPF模仿QQ登录按钮

    原文:WPF模仿QQ登录按钮 如下图,第一张是未点击时按钮样式,第二张是鼠标划过时按钮样式. 样式代码: <Style TargetType="{x:Type Button}" ...