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

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>
            亚洲精品一区中文| 欧美福利在线| 亚洲欧美美女| 欧美一区网站| 午夜视频久久久久久| 久久久久久久久伊人| 你懂的成人av| 国产精品福利在线观看网址| 国产精品一区二区三区成人| 国内视频一区| 亚洲一二区在线| 久久久www| 亚洲精品久久久蜜桃| 一区二区不卡在线视频 午夜欧美不卡在| 国产综合香蕉五月婷在线| 久久久蜜桃一区二区人| 亚洲毛片在线观看.| 国产精品第一区| 欧美一区二区三区在| 亚洲激情网址| 久热爱精品视频线路一| 国产精品一区二区久久精品| 久久九九有精品国产23| 免费一级欧美在线大片| 亚洲亚洲精品在线观看| 久久久久久久网| 日韩视频中文字幕| 欧美成人午夜激情在线| 亚洲欧美激情在线视频| 亚洲第一黄网| 亚洲韩国日本中文字幕| 欧美中文字幕不卡| 欧美精品免费看| 久久国产精品一区二区三区四区 | 午夜精品一区二区三区电影天堂| 国内精品视频一区| av成人手机在线| 六月丁香综合| 亚洲日本中文字幕免费在线不卡| 米奇777在线欧美播放| 午夜视频在线观看一区二区三区| 91久久嫩草影院一区二区| 两个人的视频www国产精品| 久久精品国产清高在天天线 | 久久av一区二区三区漫画| 日韩一区二区免费高清| 久久久另类综合| 午夜一区在线| 亚洲欧美中日韩| 国产一区免费视频| 亚洲一区二区三区精品动漫| 国产精品美女久久久| 久久成人在线| 国产精品久久久久久超碰| 欧美96在线丨欧| 欧美高清自拍一区| 蜜臀av性久久久久蜜臀aⅴ| 国产伦精品一区二区三区| 一区二区av在线| 国产精品日韩一区二区| 久久精品在线观看| 国产女人精品视频| 久久婷婷人人澡人人喊人人爽| 久久麻豆一区二区| 一色屋精品视频免费看| 亚洲国产一区二区精品专区| 欧美日韩高清一区| 性色一区二区三区| 国产精品久久久久9999高清| 日韩视频中文| 一区二区三区在线视频免费观看| 欧美激情第3页| 国产精品久久久久久久久| 一区二区三区精密机械公司| 亚洲调教视频在线观看| 久久精品国产一区二区三| 亚洲另类视频| 午夜精品久久久久久久白皮肤| 亚洲综合色丁香婷婷六月图片| 久久久久国产一区二区三区| 蜜桃av综合| 亚洲第一主播视频| 欧美精品麻豆| 亚洲一区二区毛片| 久久久av水蜜桃| 亚洲国产精品尤物yw在线观看| 欧美成人免费播放| 久久全球大尺度高清视频| 影音先锋久久久| 欧美激情一级片一区二区| 日韩午夜免费| 久久久91精品| 亚洲美女视频在线观看| 国产精品夜夜夜| 久久激情综合网| 亚洲精品美女在线| 欧美在线一级视频| 亚洲黄页视频免费观看| 国产精品成人一区二区网站软件 | 亚洲毛片在线| 久久精品2019中文字幕| 亚洲人成欧美中文字幕| 国产麻豆日韩| 免费观看30秒视频久久| 中文无字幕一区二区三区| 99国产精品久久久久久久久久| 欧美系列亚洲系列| 亚洲卡通欧美制服中文| 欧美专区在线| 99re在线精品| 国产专区欧美精品| 欧美日韩一区二区免费视频| 国产亚洲欧美一级| 欧美国产一区视频在线观看| 在线免费观看日韩欧美| 亚洲成人影音| 国产精品一香蕉国产线看观看| 亚洲欧美日韩精品久久奇米色影视| 亚洲精品视频在线| 99国产精品久久久久久久| 国产精品99久久99久久久二8 | 激情久久中文字幕| 99在线精品观看| 亚洲国产精品第一区二区| 久久国产精品一区二区三区| 一区二区三区日韩在线观看| 久久综合网色—综合色88| 美女精品网站| 99精品久久免费看蜜臀剧情介绍| 久久夜色撩人精品| 美女福利精品视频| 亚洲黄色性网站| 欧美日韩亚洲一区二区三区在线观看 | 亚洲免费在线播放| 日韩视频在线一区二区| 怡红院精品视频| 狠狠久久婷婷| 欧美1区视频| 久久青草福利网站| 欧美在线免费观看视频| 欧美一区二区三区精品 | 欧美成年视频| 老司机精品视频一区二区三区| 午夜精品免费| 在线不卡a资源高清| 国产偷国产偷亚洲高清97cao| 久久国产精彩视频| 欧美在线亚洲| 久久精品亚洲精品| 久久se精品一区精品二区| 欧美一区二区大片| 久久久91精品国产一区二区精品| 亚洲综合另类| 欧美中文在线免费| 久久精品一二三| 乱中年女人伦av一区二区| 麻豆成人在线观看| 欧美高清视频一二三区| 欧美日韩一区二区三区在线观看免 | 亚洲卡通欧美制服中文| 一区二区三区www| 亚洲男人的天堂在线| 午夜视频一区二区| 狂野欧美激情性xxxx欧美| 免费人成网站在线观看欧美高清| 欧美成人午夜影院| 欧美日韩视频在线一区二区| 国产精品久久77777| 狠狠色香婷婷久久亚洲精品| 在线观看视频日韩| 亚洲精品免费电影| 亚洲欧美一区二区激情| 久久先锋资源| 亚洲精品午夜| 久久成人免费视频| 欧美精品免费在线| 国产乱码精品一区二区三区五月婷| 国内久久精品视频| 亚洲天堂男人| 免费看的黄色欧美网站| 亚洲免费观看| 久久久99精品免费观看不卡| 欧美日韩国产精品自在自线| 国产欧美一区二区精品性| 亚洲精品影视| 久久久久国产精品麻豆ai换脸| 亚洲国产欧美国产综合一区 | 老鸭窝毛片一区二区三区| 亚洲韩国日本中文字幕| 午夜精品www| 欧美日韩在线视频一区| 欧美日韩亚洲一区三区| 国产综合色精品一区二区三区| 亚洲伦理在线| 久热这里只精品99re8久| 99热精品在线观看| 欧美sm视频| 国产亚洲福利一区| 亚洲欧美久久| 亚洲人成网站精品片在线观看|