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

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

 

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

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

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

2 BVH

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

2.1 BVH_Set

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

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

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

將元素通過Add函數(shù)添加到BVH集合后,調用BVH()函數(shù)就可以構造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派生并重寫兩個虛函數(shù)RejectNode()和Accept(),即在RejectNode()中定義排除結點的規(guī)則,在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派生并重寫兩個虛函數(shù)RejectNode()和Accept()。

2.4 BVH_Builder

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

下面給出求兩個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

準確、穩(wěn)定、高效是高品質幾何內核的目標,我們在開發(fā)軟件時,也要時刻追求這個目標。而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>
            久久在线免费观看| 欧美日本国产一区| 国产亚洲精品久久久| 亚洲欧美日韩在线播放| 亚洲天堂成人在线观看| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ入口 | 亚洲一区二区三区高清不卡| 亚洲美女精品一区| 国产精品久久久久影院色老大 | 久久精品夜色噜噜亚洲a∨| 欧美影院午夜播放| 在线高清一区| 夜夜爽夜夜爽精品视频| 国产精品一区在线观看你懂的| 久久成人免费| 久久久久在线观看| 亚洲精品欧美日韩专区| 亚洲午夜成aⅴ人片| 国产日韩精品久久久| 欧美成人黄色小视频| 欧美三日本三级少妇三2023| 性视频1819p久久| 久久一区国产| 小处雏高清一区二区三区| 久久婷婷国产麻豆91天堂| 一本色道久久综合精品竹菊 | 亚洲狠狠婷婷| 国产精品嫩草99a| 亚洲福利在线观看| 国产女优一区| 亚洲欧洲精品成人久久奇米网| 国产精品久久久久久久久免费桃花 | 亚洲女人天堂av| 久久另类ts人妖一区二区| 99这里只有精品| 久久久久久香蕉网| 亚洲欧美日韩网| 欧美精品亚洲精品| 久久中文字幕导航| 国产精品久久久久久久久婷婷 | 蜜桃伊人久久| 国产精品丝袜白浆摸在线| 亚洲国产婷婷香蕉久久久久久99 | 欧美激情国产日韩| 久久综合色一综合色88| 国产精品大片| 亚洲人午夜精品免费| 曰韩精品一区二区| 欧美一级日韩一级| 亚洲欧美日韩中文视频| 欧美承认网站| 亚洲国产一二三| 1000部精品久久久久久久久| 亚洲一区二区三区在线观看视频| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲欧美日韩在线不卡| 亚洲欧美国产不卡| 欧美日韩一区三区| 亚洲精品国产拍免费91在线| 亚洲国产精品免费| 久久婷婷国产麻豆91天堂| 久久在线播放| 伊人狠狠色j香婷婷综合| 香蕉尹人综合在线观看| 香蕉久久夜色精品国产使用方法 | 免费亚洲一区二区| 老司机aⅴ在线精品导航| 亚洲经典一区| 亚洲经典三级| 免费看的黄色欧美网站| 欧美大学生性色视频| 最新成人在线| 欧美美女喷水视频| 一本久久综合亚洲鲁鲁五月天| 亚洲精品一区中文| 欧美日本在线播放| 日韩视频一区二区在线观看| 一区二区三区偷拍| 国产精品久久网| 欧美在线观看网站| 欧美国产日本| 夜夜嗨av一区二区三区网站四季av| 欧美精品粉嫩高潮一区二区 | 国产精品99久久久久久人| 在线一区二区日韩| 国产精品久久网站| 欧美一区二区国产| 欧美黄色成人网| 一区二区三区日韩欧美精品| 国产精品卡一卡二卡三| 校园春色综合网| 欧美激情亚洲一区| 在线一区二区三区四区| 国产日韩在线亚洲字幕中文| 久久精品首页| 日韩性生活视频| 久久国产精品一区二区三区| 亚洲国产电影| 欧美私人网站| 久久影院午夜论| 99精品国产99久久久久久福利| 性欧美1819sex性高清| 一区在线播放视频| 国产精品jizz在线观看美国 | 久热re这里精品视频在线6| 亚洲欧洲日本mm| 久久精品观看| 亚洲图片欧洲图片av| 极品少妇一区二区三区| 欧美日韩精品国产| 久久精品免费电影| 99riav久久精品riav| 六月婷婷一区| 午夜精品久久久久久久白皮肤 | 欧美日韩亚洲一区二区三区在线观看 | 久久av二区| 亚洲另类一区二区| 久久婷婷久久| 欧美亚洲一区二区在线观看| 精品av久久707| 国产精品九九| 欧美精品在欧美一区二区少妇| 久久国产乱子精品免费女 | 欧美高清视频一区二区三区在线观看| 亚洲一区激情| 一区二区三区日韩精品视频| 亚洲国产一区二区三区青草影视| 国产精品视频久久| 欧美肉体xxxx裸体137大胆| 男人的天堂亚洲在线| 久久国产精品99久久久久久老狼| 正在播放日韩| 一本色道婷婷久久欧美| 亚洲高清免费| 亚洲第一区在线| 免费一级欧美在线大片| 久久人人爽人人| 久久精品日韩欧美| 久久久久九九视频| 久久精品一本久久99精品| 欧美一区二区三区在线免费观看| 一区二区三区视频免费在线观看| 亚洲人成亚洲人成在线观看| 亚洲国产精品嫩草影院| 亚洲黄网站黄| 亚洲国产精品悠悠久久琪琪| 在线精品视频一区二区| 亚洲第一毛片| 亚洲电影中文字幕| 亚洲精品乱码久久久久久| 亚洲国产天堂久久综合网| 亚洲激情自拍| 一级日韩一区在线观看| 亚洲天天影视| 欧美亚洲视频在线看网址| 欧美在线一二三区| 久久偷看各类wc女厕嘘嘘偷窃| 久久久午夜电影| 欧美成人资源网| 亚洲国产精品99久久久久久久久| 亚洲激情国产精品| 99热免费精品在线观看| 亚洲一区二区在线免费观看| 亚洲欧美日韩第一区 | 欧美韩日一区二区| 亚洲欧洲另类国产综合| 一区二区三区 在线观看视| 亚洲午夜高清视频| 久久福利影视| 欧美大色视频| 国产精品欧美日韩| 永久555www成人免费| 一本色道久久综合狠狠躁篇的优点| 亚洲免费在线观看| 猛男gaygay欧美视频| 亚洲三级电影在线观看| 午夜精品一区二区三区电影天堂| 久久青青草原一区二区| 欧美精品一区二区高清在线观看| 国产精品红桃| 亚洲人体偷拍| 久久成人精品电影| 亚洲国产天堂久久国产91| 亚洲一区国产视频| 欧美成人有码| 国产综合色精品一区二区三区| 亚洲精品国偷自产在线99热| 欧美亚洲一级| 亚洲乱码国产乱码精品精| 久久精品国产2020观看福利| 欧美精品在线免费| 激情婷婷欧美| 午夜视频一区在线观看| 亚洲成色999久久网站| 性高湖久久久久久久久| 欧美日韩国产区| 亚洲第一精品福利| 久久久水蜜桃av免费网站| 亚洲视频图片小说| 欧美激情四色|