青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

eryar

PipeCAD - Plant Piping Design Software.
PlantAssistant - Translate AVEVA RVM/SP3D VUE to glTF, STEP, etc.
posts - 606, comments - 590, trackbacks - 0, articles - 0

性能提升-BVH層次包圍體

Posted on 2023-08-16 23:28 eryar 閱讀(1237) 評論(0)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

性能提升-BVH層次包圍體

eryar@163.com

Abstract.  OpenCASCADE provides BVH to achieve high performance in AIS of visualization module. To understand BVH usage will help us to understand many code of opencascade.

Key Words. BVH, Bounding Volume Hierarchy, LBVH, SAH Algorithm

1 Introduction

層次包圍體技術 (BVH) 指的是將所有包圍體分層逐次地再次包圍,獲得一個更大的包圍體,直到包圍住所有物體。實際上,它是一個樹形結構,因此可以仿照樹的結構,將兩個或三個小的包圍體包圍成一個更大的包圍體,以此類推。

BVH是一種以物體BV為基礎進行劃分的結構。它由根節點、內部節點和葉子節點組成。其中葉子節點存放物體,每個非葉子節點都有包圍體,父節點可以把子節點包圍起來。每個非葉子節點的包圍體大小,是它所包含的所有物體的包圍體的總和,所以它在空間上比較緊湊,非常適用于需要大量求相交測試的應用場景,如光線追蹤、碰撞檢測、射線相交測試之類的應用場合中。

 

BVH在OpenCASCADE中也有廣泛地應用,如開源版本中的模型快速碰撞檢測,使用類BRepExtrema_ShapeProximity. 模型選擇操作,光線跟蹤等算法中都有應用。在

https://www.cnblogs.com/opencascade/p/6804446.html

中介紹如何遍歷BVH樹,本文主要介紹BVH使用方法。

2 BVH

OpenCASCADE中的BVH是相對獨立的一個包,是作者根據論文實現的純C++版本移植過來的。在DRAW中的QA品質保證Bugs中提供了BVH的使用示例。

2.1 BVH_Set

首先要定義層次包圍盒的集合Set來構造BVH樹,從BVH_Set基類派生的集合是可以直接使用的:

如可以直接使用BVH_Triangulation,也可以直接使用BVH_BoxSet:

從這些類名中,我們可以看出在求模型間極值距離Extrema,三維可視化Graphic3d及Select3D拾取及布爾操作BOPTools中都有BVH的應用。

將元素通過Add函數添加到BVH集合后,調用BVH()函數就可以構造BVH樹。

2.2 BVH_Traverse

對于單個BVH的遍歷提供類BVH_Traverse,一般的應用場景如求距離一點P最近的模型,或者位于某個空間范圍內的所有模型。代碼如下所示:

//=======================================================================
//function : ShapeSelector
//purpose : Implement the simplest shape's selector
//=======================================================================
class ShapeSelector :
  public BVH_Traverse <Standard_Real, 3, BVH_BoxSet <Standard_Real, 3, TopoDS_Shape>, Standard_Boolean>
{
public:
  //! Constructor
  ShapeSelector() {}
  //! Sets the Box for selection
  void SetBox (const Bnd_Box& theBox)
  {
    myBox = Bnd_Tools::Bnd2BVH (theBox);
  }
  //! Returns the selected shapes
  const NCollection_List<TopoDS_Shape>& Shapes () const { return myShapes; }
public:
  //! Defines the rules for node rejection by bounding box
  virtual Standard_Boolean RejectNode (const BVH_Vec3d& theCornerMin,
                                       const BVH_Vec3d& theCornerMax,
                                       Standard_Boolean& theIsInside) const Standard_OVERRIDE
  {
    Standard_Boolean hasOverlap;
    theIsInside = myBox.Contains (theCornerMin, theCornerMax, hasOverlap);
    return !hasOverlap;
  }
  //! Defines the rules for leaf acceptance
  virtual Standard_Boolean AcceptMetric (const Standard_Boolean& theIsInside) const Standard_OVERRIDE
  {
    return theIsInside;
  }
  //! Defines the rules for leaf acceptance
  virtual Standard_Boolean Accept (const Standard_Integer theIndex,
                                   const Standard_Boolean& theIsInside) Standard_OVERRIDE
  {
    if (theIsInside || !myBox.IsOut (myBVHSet->Box (theIndex)))
    {
      myShapes.Append (myBVHSet->Element (theIndex));
      return Standard_True;
    }
    return Standard_False;
  }
protected:
  BVH_Box <Standard_Real, 3> myBox;         //!< Selection box
  NCollection_List <TopoDS_Shape> myShapes; //!< Selected shapes
};

主要是從類BVH_Traverse派生并重寫兩個虛函數RejectNode()和Accept(),即在RejectNode()中定義排除結點的規則,在Accept()中處理滿足條件的情況。

2.3 BVH_PairTraverse

對于兩個BVH的遍歷提供類BVH_PairTraverse,一般的應用場景有求兩個Mesh之間的最近距離,判斷兩個Mesh之間是否有碰撞等。

//=======================================================================
//function : MeshMeshDistance
//purpose : Class to compute the distance between two meshes
//=======================================================================
class MeshMeshDistance : public BVH_PairDistance<Standard_Real, 3, BVH_BoxSet<Standard_Real, 3, Triangle>>
{
public:
  //! Constructor
  MeshMeshDistance() {}
public:
  //! Defines the rules for leaf acceptance
  virtual Standard_Boolean Accept (const Standard_Integer theIndex1,
                                   const Standard_Integer theIndex2) Standard_OVERRIDE
  {
    const Triangle& aTri1 = myBVHSet1->Element (theIndex1);
    const Triangle& aTri2 = myBVHSet2->Element (theIndex2);
    Standard_Real aDistance = TriangleTriangleSqDistance (aTri1._Node1, aTri1._Node2, aTri1._Node3,
                                                          aTri2._Node1, aTri2._Node2, aTri2._Node3);
    if (aDistance < myDistance)
    {
      myDistance = aDistance;
      return Standard_True;
    }
    return Standard_False;
  }
};

主要也是從BVH_PairTraverse派生并重寫兩個虛函數RejectNode()和Accept()。

2.4 BVH_Builder

關于BVH的構造提供多種Builder,默認是使用基于SAH算法的BVH_BinnedBuilder來構造BVH樹,如果要切換不同的構造器,可以在BVH集合的構造函數中傳入一個。

下面給出求兩個Mesh之間最近距離的示例代碼:

 

 // Define BVH Builder
  opencascade::handle <BVH_LinearBuilder <Standard_Real, 3> > aLBuilder =
      new BVH_LinearBuilder <Standard_Real, 3>();
  // Create the ShapeSet
  opencascade::handle <BVH_BoxSet <Standard_Real, 3, Triangle> > aTriangleBoxSet[2];
  for (Standard_Integer i = 0; i < 2; ++i)
  {
    aTriangleBoxSet[i] = new BVH_BoxSet <Standard_Real, 3, Triangle> (aLBuilder);
    TopTools_IndexedMapOfShape aMapShapes;
    TopExp::MapShapes (aShape[i], TopAbs_FACE,   aMapShapes);
    for (Standard_Integer iS = 1; iS <= aMapShapes.Extent(); ++iS)
    {
      const TopoDS_Face& aF = TopoDS::Face (aMapShapes(iS));
      TopLoc_Location aLoc;
      const Handle(Poly_Triangulation)& aTriangulation = BRep_Tool::Triangulation(aF, aLoc);
      const int aNbTriangles = aTriangulation->NbTriangles();
      for (int iT = 1; iT <= aNbTriangles; ++iT)
      {
        const Poly_Triangle aTriangle = aTriangulation->Triangle (iT);
        // Nodes indices
        Standard_Integer id1, id2, id3;
        aTriangle.Get (id1, id2, id3);
        const gp_Pnt aP1 = aTriangulation->Node (id1).Transformed (aLoc.Transformation());
        const gp_Pnt aP2 = aTriangulation->Node (id2).Transformed (aLoc.Transformation());
        const gp_Pnt aP3 = aTriangulation->Node (id3).Transformed (aLoc.Transformation());
        BVH_Vec3d aBVHP1 (aP1.X(), aP1.Y(), aP1.Z());
        BVH_Vec3d aBVHP2 (aP2.X(), aP2.Y(), aP2.Z());
        BVH_Vec3d aBVHP3 (aP3.X(), aP3.Y(), aP3.Z());
        BVH_Box<Standard_Real, 3> aBox;
        aBox.Add (aBVHP1);
        aBox.Add (aBVHP2);
        aBox.Add (aBVHP3);
        aTriangleBoxSet[i]->Add (Triangle (aBVHP1, aBVHP2, aBVHP3), aBox);
      }
    }
    // Build BVH
    aTriangleBoxSet[i]->Build();
  }
  // Initialize selector
  MeshMeshDistance aDistTool;
  // Select the elements
  aDistTool.SetBVHSets (aTriangleBoxSet[0].get(), aTriangleBoxSet[1].get());
  Standard_Real aSqDist = aDistTool.ComputeDistance();
  if (!aDistTool.IsDone())
    std::cout << "Not Done" << std::endl;
  else
    theDI << "Distance " << sqrt (aSqDist) << "\n";

3 Conclusion

準確、穩定、高效是高品質幾何內核的目標,我們在開發軟件時,也要時刻追求這個目標。而BVH層次包圍盒技術是提升性能的一種方式,理解BVH的使用,我們可以理解opencascade中快速求極值Extrema,交互選擇SelectMgr等很多代碼。甚至我們也可以參與貢獻,如將

Standard_Boolean BRepExtrema_Poly::Distance (const TopoDS_Shape& S1, const TopoDS_Shape& S2,
                                             gp_Pnt& P1, gp_Pnt& P2, Standard_Real& dist)

這個O(N^2)的改造成BVH的來對比一下性能。

 

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲高清在线播放| 一本久道综合久久精品| 久久成人免费网| 国产亚洲一区精品| 久久久91精品国产一区二区三区 | 亚洲国产99| 欧美黄色aa电影| 欧美精品一区二区在线观看| 日韩亚洲国产精品| 一区二区三区精品视频在线观看 | 男女激情久久| 99ri日韩精品视频| 亚洲一区日韩在线| 国内精品99| 亚洲欧洲一区二区三区久久| 国产精品电影观看| 欧美一区二区三区在线观看| 久久精品一二三区| 亚洲七七久久综合桃花剧情介绍| 亚洲美女尤物影院| 国产区日韩欧美| 亚洲人成亚洲人成在线观看图片 | 久久躁日日躁aaaaxxxx| 99天天综合性| 性欧美xxxx大乳国产app| 亚洲激情在线激情| 亚洲一区二区三区高清不卡| ●精品国产综合乱码久久久久| 亚洲伦理在线免费看| 国产视频欧美视频| 日韩一二三区视频| 亚洲成色www8888| 亚洲一区二区三区成人在线视频精品| 精品51国产黑色丝袜高跟鞋| 亚洲乱码国产乱码精品精天堂 | 国产欧美一区二区精品仙草咪| 女女同性女同一区二区三区91| 欧美视频在线观看 亚洲欧| 久久久久欧美精品| 欧美视频精品在线观看| 另类天堂av| 国产精品视频成人| 最新国产の精品合集bt伙计| 国产一区二区三区久久| 一区二区欧美日韩| 亚洲日本理论电影| 久久精品亚洲精品国产欧美kt∨| 亚洲综合精品| 欧美日韩国产电影| 欧美国产精品| 尤物视频一区二区| 久久av一区二区三区漫画| 亚洲午夜一级| 欧美日韩亚洲综合一区| 亚洲国产一区在线| 精品av久久久久电影| 亚洲欧美日韩一区二区在线| 在线一区二区日韩| 欧美黑人在线观看| 亚洲国产成人高清精品| 亚洲丰满在线| 久热精品视频在线| 免费在线日韩av| 在线观看三级视频欧美| 久久黄金**| 久久人人97超碰精品888 | 欧美成人久久| 亚洲国产精选| 99精品久久免费看蜜臀剧情介绍| 欧美国产日韩亚洲一区| 亚洲国产专区校园欧美| 日韩系列在线| 国产精品sss| 亚洲欧美国产视频| 久久精品视频在线| 国产有码一区二区| 久久综合伊人77777蜜臀| 欧美大色视频| 99re6热只有精品免费观看 | 欧美激情一区二区三区| 亚洲电影免费在线| 在线亚洲一区| 国产亚洲欧美一区二区| 欧美在线中文字幕| 亚洲第一在线综合网站| 99在线视频精品| 国产精品久久久久久久久久ktv| 亚洲一级黄色片| 久久婷婷国产综合尤物精品| 亚洲高清色综合| 欧美日韩1234| 欧美一区在线视频| 亚洲国产一区二区三区a毛片| 在线综合+亚洲+欧美中文字幕| 国产精品区二区三区日本| 亚洲欧美激情一区| 欧美国产第一页| 亚洲一区亚洲二区| 136国产福利精品导航网址| 欧美成人有码| 香蕉久久夜色精品国产| 欧美激情综合色| 亚洲欧美三级伦理| 亚洲国产精品一区二区www在线| 欧美精品一区二区三区在线看午夜 | 国产乱人伦精品一区二区| 久久精品视频播放| 日韩视频在线观看免费| 久久国内精品视频| 亚洲精品国精品久久99热| 国产精品午夜春色av| 欧美暴力喷水在线| 午夜久久久久久久久久一区二区| 亚洲国产乱码最新视频| 久久国内精品自在自线400部| 亚洲精品日韩激情在线电影| 国产专区综合网| 欧美视频导航| 欧美国产日韩一区| 久久久精品网| 亚洲欧美视频一区| 日韩一级免费| 亚洲国产日韩欧美综合久久| 久久国产欧美精品| 亚洲欧美日本视频在线观看| 亚洲国产精品日韩| 国产一区二区久久| 国产精品久久久久久久久| 欧美日本韩国一区| 久久中文欧美| 久久久精品动漫| 欧美一区二区三区在线看| 一区二区三区欧美成人| 亚洲精品久久久久| 欧美成人三级在线| 久热国产精品| 另类成人小视频在线| 久久亚洲美女| 久久婷婷久久一区二区三区| 久久精品夜色噜噜亚洲aⅴ| 性伦欧美刺激片在线观看| 亚洲欧美日韩人成在线播放| 亚洲综合成人在线| 亚洲视频每日更新| 亚洲欧美精品在线| 亚洲欧美国产三级| 午夜精品久久久久久99热| 亚洲欧美在线一区二区| 亚洲午夜精品国产| 亚洲欧美日韩精品| 午夜精品999| 久久久999国产| 麻豆精品视频在线| 免费亚洲婷婷| 亚洲茄子视频| 一本色道久久综合亚洲二区三区 | 欧美福利视频网站| 亚洲国产成人不卡| 日韩视频免费观看高清完整版| 亚洲卡通欧美制服中文| 正在播放欧美视频| 篠田优中文在线播放第一区| 久久久久久久久综合| 另类亚洲自拍| 欧美区视频在线观看| 国产精品qvod| 狠狠狠色丁香婷婷综合久久五月| 尤物视频一区二区| 在线一区视频| 欧美在线啊v| 欧美va日韩va| 一区二区欧美视频| 欧美自拍偷拍午夜视频| 免费在线观看日韩欧美| 欧美日韩在线观看一区二区| 国产欧美日本一区视频| 亚洲国产女人aaa毛片在线| 亚洲素人在线| 久久综合九色综合网站| 亚洲精品视频在线观看免费| 亚洲欧美日韩综合| 久热精品视频在线| 国产精品青草久久久久福利99| 一区在线免费| 亚洲欧美日韩综合| 欧美福利在线观看| 亚洲免费在线播放| 欧美精品1区| 一区二区三区无毛| 亚洲欧美日韩在线| 亚洲高清在线播放| 欧美亚洲在线视频| 欧美日韩一区二区视频在线| 在线观看国产成人av片| 性欧美video另类hd性玩具| 亚洲缚视频在线观看| 亚欧成人精品| 国产精品久久久久久福利一牛影视| 影院欧美亚洲| 久久国产精品久久国产精品|