Added const for method BVH_Builder::Build().
Added missing Standard_OVERRIDE to overridden methods.
Merged code from .lxx in BVH package directly into .hxx headers.
#include <BVH_QuadTree.hxx>
+#include <deque>
+#include <tuple>
+
//! Specialization of binary BVH tree.
template<class T, int N>
class BVH_Tree<T, N, BVH_BinaryTree> : public BVH_TreeBase<T, N>
BVH_Tree() : BVH_TreeBase<T, N>() { }
//! Sets node type to 'outer'.
- void SetOuter (const int theNodeIndex);
+ void SetOuter (const int theNodeIndex) { BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex).x() = 1; }
//! Sets node type to 'inner'.
- void SetInner (const int theNodeIndex);
+ void SetInner (const int theNodeIndex) { BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex).x() = 0; }
+
+ //! Returns index of the K-th child of the given inner node.
+ //! \tparam K the index of node child (0 or 1)
+ template<int K>
+ int Child (const int theNodeIndex) const { return BVH::Array<int, 4>::Value (this->myNodeInfoBuffer, theNodeIndex)[K + 1]; }
//! Returns index of the K-th child of the given inner node.
//! \tparam K the index of node child (0 or 1)
template<int K>
- int Child (const int theNodeIndex) const;
+ int& ChangeChild (const int theNodeIndex) { return BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex)[K + 1]; }
//! Returns index of the K-th child of the given inner node.
//! \tparam K the index of node child (0 or 1)
template<int K>
- int& Child (const int theNodeIndex);
+ int& Child (const int theNodeIndex) { return BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex)[K + 1]; }
public: //! @name methods for adding/removing tree nodes
//! Removes all nodes from the tree.
- void Clear();
+ void Clear()
+ {
+ this->myDepth = 0;
+ BVH::Array<T, N>::Clear (this->myMinPointBuffer);
+ BVH::Array<T, N>::Clear (this->myMaxPointBuffer);
+ BVH::Array<int, 4>::Clear(this->myNodeInfoBuffer);
+ }
//! Reserves internal BVH storage, so that it
//! can contain the given number of BVH nodes.
- void Reserve (const int theNbNodes);
+ void Reserve (const int theNbNodes)
+ {
+ BVH::Array<T, N>::Reserve (this->myMinPointBuffer, theNbNodes);
+ BVH::Array<T, N>::Reserve (this->myMaxPointBuffer, theNbNodes);
+ BVH::Array<int, 4>::Reserve (this->myNodeInfoBuffer, theNbNodes);
+ }
//! Adds new leaf node to the BVH.
int AddLeafNode (const BVH_VecNt& theMinPoint,
const BVH_VecNt& theMaxPoint,
const int theBegElem,
- const int theEndElem);
+ const int theEndElem)
+ {
+ BVH::Array<T, N>::Append (this->myMinPointBuffer, theMinPoint);
+ BVH::Array<T, N>::Append (this->myMaxPointBuffer, theMaxPoint);
+ BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (1, theBegElem, theEndElem, 0));
+ return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
+ }
//! Adds new inner node to the BVH.
int AddInnerNode (const BVH_VecNt& theMinPoint,
const BVH_VecNt& theMaxPoint,
const int theLftChild,
- const int theRghChild);
+ const int theRghChild)
+ {
+ BVH::Array<T, N>::Append (this->myMinPointBuffer, theMinPoint);
+ BVH::Array<T, N>::Append (this->myMaxPointBuffer, theMaxPoint);
+ BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (0, theLftChild, theRghChild, 0));
+ return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
+ }
//! Adds new leaf node to the BVH.
int AddLeafNode (const BVH_Box<T, N>& theAABB,
const int theBegElem,
- const int theEndElem);
+ const int theEndElem)
+ {
+ return AddLeafNode (theAABB.CornerMin(), theAABB.CornerMax(), theBegElem, theEndElem);
+ }
//! Adds new inner node to the BVH.
int AddInnerNode (const BVH_Box<T, N>& theAABB,
const int theLftChild,
- const int theRghChild);
+ const int theRghChild)
+ {
+ return AddInnerNode (theAABB.CornerMin(), theAABB.CornerMax(), theLftChild, theRghChild);
+ }
//! Adds new leaf node to the BVH with UNINITIALIZED bounds.
int AddLeafNode (const int theBegElem,
- const int theEndElem);
+ const int theEndElem)
+ {
+ BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (1, theBegElem, theEndElem, 0));
+ return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
+ }
//! Adds new inner node to the BVH with UNINITIALIZED bounds.
int AddInnerNode (const int theLftChild,
- const int theRghChild);
+ const int theRghChild)
+ {
+ BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (0, theLftChild, theRghChild, 0));
+ return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
+ }
public: //! @name methods specific to binary BVH
};
-#include <BVH_BinaryTree.lxx>
+namespace BVH
+{
+ //! Internal function for recursive calculation of
+ //! surface area heuristic (SAH) of the given tree.
+ template<class T, int N>
+ void EstimateSAH (const BVH_Tree<T, N, BVH_BinaryTree>* theTree, const int theNode, T theProb, T& theSAH)
+ {
+ BVH_Box<T, N> aBox (theTree->MinPoint (theNode),
+ theTree->MaxPoint (theNode));
+
+ if (theTree->IsOuter (theNode))
+ {
+ theSAH += theProb * (theTree->EndPrimitive (theNode) - theTree->BegPrimitive (theNode) + 1);
+ }
+ else
+ {
+ theSAH += theProb * static_cast<T> (2.0);
+
+ BVH_Box<T, N> aLftBox (theTree->MinPoint (theTree->template Child<0> (theNode)),
+ theTree->MaxPoint (theTree->template Child<0> (theNode)));
+
+ if (theProb > 0.0)
+ {
+ EstimateSAH (theTree, theTree->template Child<0> (theNode),
+ theProb * aLftBox.Area() / aBox.Area(), theSAH);
+ }
+
+ BVH_Box<T, N> aRghBox (theTree->MinPoint (theTree->template Child<1> (theNode)),
+ theTree->MaxPoint (theTree->template Child<1> (theNode)));
+
+ if (theProb > 0.0)
+ {
+ EstimateSAH (theTree, theTree->template Child<1> (theNode),
+ theProb * aRghBox.Area() / aBox.Area(), theSAH);
+ }
+ }
+ }
+}
+
+// =======================================================================
+// function : EstimateSAH
+// purpose :
+// =======================================================================
+template<class T, int N>
+T BVH_Tree<T, N, BVH_BinaryTree>::EstimateSAH() const
+{
+ T aSAH = static_cast<T> (0.0);
+ BVH::EstimateSAH<T, N> (this, 0, static_cast<T> (1.0), aSAH);
+ return aSAH;
+}
+
+// =======================================================================
+// function : CollapseToQuadTree
+// purpose :
+// =======================================================================
+template<class T, int N>
+BVH_Tree<T, N, BVH_QuadTree>* BVH_Tree<T, N, BVH_BinaryTree>::CollapseToQuadTree() const
+{
+ BVH_Tree<T, N, BVH_QuadTree>* aQBVH = new BVH_Tree<T, N, BVH_QuadTree>;
+
+ if (this->Length() == 0)
+ {
+ return aQBVH;
+ }
+
+ std::deque<std::pair<int, int> > aQueue (1, std::make_pair (0, 0));
+
+ for (int aNbNodes = 1; !aQueue.empty();)
+ {
+ const std::pair<int, int> aNode = aQueue.front();
+
+ BVH::Array<T, N>::Append (aQBVH->myMinPointBuffer, BVH::Array<T, N>::Value (this->myMinPointBuffer, std::get<0> (aNode)));
+ BVH::Array<T, N>::Append (aQBVH->myMaxPointBuffer, BVH::Array<T, N>::Value (this->myMaxPointBuffer, std::get<0> (aNode)));
+
+ BVH_Vec4i aNodeInfo;
+ if (this->IsOuter (std::get<0> (aNode))) // is leaf node
+ {
+ aNodeInfo = BVH_Vec4i (1 /* leaf flag */,
+ this->BegPrimitive (std::get<0> (aNode)), this->EndPrimitive (std::get<0> (aNode)), std::get<1> (aNode) /* level */);
+ }
+ else
+ {
+ NCollection_Vector<int> aGrandChildNodes;
+
+ const int aLftChild = Child<0> (std::get<0> (aNode));
+ const int aRghChild = Child<1> (std::get<0> (aNode));
+ if (this->IsOuter (aLftChild)) // is leaf node
+ {
+ aGrandChildNodes.Append (aLftChild);
+ }
+ else
+ {
+ aGrandChildNodes.Append (Child<0> (aLftChild));
+ aGrandChildNodes.Append (Child<1> (aLftChild));
+ }
+
+ if (this->IsOuter (aRghChild)) // is leaf node
+ {
+ aGrandChildNodes.Append (aRghChild);
+ }
+ else
+ {
+ aGrandChildNodes.Append (Child<0> (aRghChild));
+ aGrandChildNodes.Append (Child<1> (aRghChild));
+ }
+
+ for (int aNodeIdx = 0; aNodeIdx < aGrandChildNodes.Size(); ++aNodeIdx)
+ {
+ aQueue.push_back (std::make_pair (aGrandChildNodes (aNodeIdx), std::get<1> (aNode) + 1));
+ }
+
+ aNodeInfo = BVH_Vec4i (0 /* inner flag */,
+ aNbNodes, aGrandChildNodes.Size() - 1, std::get<1> (aNode) /* level */);
+
+ aQBVH->myDepth = Max (aQBVH->myDepth, std::get<1> (aNode) + 1);
+
+ aNbNodes += aGrandChildNodes.Size();
+ }
+
+ BVH::Array<int, 4>::Append (aQBVH->myNodeInfoBuffer, aNodeInfo);
+ aQueue.pop_front(); // node processing completed
+ }
+
+ return aQBVH;
+}
#endif // _BVH_BinaryTree_Header
+++ /dev/null
-// Created on: 2016-06-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2016 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <deque>
-#include <tuple>
-
-// =======================================================================
-// function : Child
-// purpose : Returns index of the K-th child of the given inner node
-// =======================================================================
-template<class T, int N> template<int K>
-int& BVH_Tree<T, N, BVH_BinaryTree>::Child (const int theNodeIndex)
-{
- return BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex)[K + 1];
-}
-
-// =======================================================================
-// function : Child
-// purpose : Returns index of the K-th child of the given inner node
-// =======================================================================
-template<class T, int N> template<int K>
-int BVH_Tree<T, N, BVH_BinaryTree>::Child (const int theNodeIndex) const
-{
- return BVH::Array<int, 4>::Value (this->myNodeInfoBuffer, theNodeIndex)[K + 1];
-}
-
-// =======================================================================
-// function : SetOuter
-// purpose : Sets node type to 'outer'
-// =======================================================================
-template<class T, int N>
-void BVH_Tree<T, N, BVH_BinaryTree>::SetOuter (const int theNodeIndex)
-{
- BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex).x() = 1;
-}
-
-// =======================================================================
-// function : SetOuter
-// purpose : Sets node type to 'inner'
-// =======================================================================
-template<class T, int N>
-void BVH_Tree<T, N, BVH_BinaryTree>::SetInner (const int theNodeIndex)
-{
- BVH::Array<int, 4>::ChangeValue (this->myNodeInfoBuffer, theNodeIndex).x() = 0;
-}
-
-// =======================================================================
-// function : Clear
-// purpose : Removes all BVH nodes
-// =======================================================================
-template<class T, int N>
-void BVH_Tree<T, N, BVH_BinaryTree>::Clear()
-{
- this->myDepth = 0;
-
- BVH::Array<T, N>::Clear (this->myMinPointBuffer);
- BVH::Array<T, N>::Clear (this->myMaxPointBuffer);
-
- BVH::Array<int, 4>::Clear (this->myNodeInfoBuffer);
-}
-
-// =======================================================================
-// function : AddLeafNode
-// purpose : Adds new leaf node to the BVH
-// =======================================================================
-template<class T, int N>
-int BVH_Tree<T, N, BVH_BinaryTree>::AddLeafNode (const int theBegElem,
- const int theEndElem)
-{
- BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (1, theBegElem, theEndElem, 0));
-
- return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
-}
-
-// =======================================================================
-// function : AddInnerNode
-// purpose : Adds new inner node to the BVH
-// =======================================================================
-template<class T, int N>
-int BVH_Tree<T, N, BVH_BinaryTree>::AddInnerNode (const int theLftChild,
- const int theRghChild)
-{
- BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (0, theLftChild, theRghChild, 0));
-
- return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
-}
-
-// =======================================================================
-// function : AddLeafNode
-// purpose : Adds new leaf node to the BVH
-// =======================================================================
-template<class T, int N>
-int BVH_Tree<T, N, BVH_BinaryTree>::AddLeafNode (const BVH_VecNt& theMinPoint,
- const BVH_VecNt& theMaxPoint,
- const int theBegElem,
- const int theEndElem)
-{
- BVH::Array<T, N>::Append (this->myMinPointBuffer, theMinPoint);
- BVH::Array<T, N>::Append (this->myMaxPointBuffer, theMaxPoint);
-
- BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (1, theBegElem, theEndElem, 0));
-
- return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
-}
-
-// =======================================================================
-// function : AddInnerNode
-// purpose : Adds new inner node to the BVH
-// =======================================================================
-template<class T, int N>
-int BVH_Tree<T, N, BVH_BinaryTree>::AddInnerNode (const BVH_VecNt& theMinPoint,
- const BVH_VecNt& theMaxPoint,
- const int theLftChild,
- const int theRghChild)
-{
- BVH::Array<T, N>::Append (this->myMinPointBuffer, theMinPoint);
- BVH::Array<T, N>::Append (this->myMaxPointBuffer, theMaxPoint);
-
- BVH::Array<int, 4>::Append (this->myNodeInfoBuffer, BVH_Vec4i (0, theLftChild, theRghChild, 0));
-
- return BVH::Array<int, 4>::Size (this->myNodeInfoBuffer) - 1;
-}
-
-// =======================================================================
-// function : AddLeafNode
-// purpose : Adds new leaf node to the BVH
-// =======================================================================
-template<class T, int N>
-int BVH_Tree<T, N, BVH_BinaryTree>::AddLeafNode (const BVH_Box<T, N>& theAABB,
- const int theBegElem,
- const int theEndElem)
-{
- return AddLeafNode (theAABB.CornerMin(),
- theAABB.CornerMax(),
- theBegElem,
- theEndElem);
-}
-
-// =======================================================================
-// function : AddInnerNode
-// purpose : Adds new inner node to the BVH
-// =======================================================================
-template<class T, int N>
-int BVH_Tree<T, N, BVH_BinaryTree>::AddInnerNode (const BVH_Box<T, N>& theAABB,
- const int theLftChild,
- const int theRghChild)
-{
- return AddInnerNode (theAABB.CornerMin(),
- theAABB.CornerMax(),
- theLftChild,
- theRghChild);
-}
-
-namespace BVH
-{
- //! Internal function for recursive calculation of
- //! surface area heuristic (SAH) of the given tree.
- template<class T, int N>
- void EstimateSAH (const BVH_Tree<T, N, BVH_BinaryTree>* theTree, const int theNode, T theProb, T& theSAH)
- {
- BVH_Box<T, N> aBox (theTree->MinPoint (theNode),
- theTree->MaxPoint (theNode));
-
- if (theTree->IsOuter (theNode))
- {
- theSAH += theProb * (theTree->EndPrimitive (theNode) - theTree->BegPrimitive (theNode) + 1);
- }
- else
- {
- theSAH += theProb * static_cast<T> (2.0);
-
- BVH_Box<T, N> aLftBox (theTree->MinPoint (theTree->template Child<0> (theNode)),
- theTree->MaxPoint (theTree->template Child<0> (theNode)));
-
- if (theProb > 0.0)
- {
- EstimateSAH (theTree, theTree->template Child<0> (theNode),
- theProb * aLftBox.Area() / aBox.Area(), theSAH);
- }
-
- BVH_Box<T, N> aRghBox (theTree->MinPoint (theTree->template Child<1> (theNode)),
- theTree->MaxPoint (theTree->template Child<1> (theNode)));
-
- if (theProb > 0.0)
- {
- EstimateSAH (theTree, theTree->template Child<1> (theNode),
- theProb * aRghBox.Area() / aBox.Area(), theSAH);
- }
- }
- }
-}
-
-// =======================================================================
-// function : EstimateSAH
-// purpose :
-// =======================================================================
-template<class T, int N>
-T BVH_Tree<T, N, BVH_BinaryTree>::EstimateSAH() const
-{
- T aSAH = static_cast<T> (0.0);
-
- BVH::EstimateSAH<T, N> (this, 0, static_cast<T> (1.0), aSAH);
-
- return aSAH;
-}
-
-// =======================================================================
-// function : Reserve
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Tree<T, N, BVH_BinaryTree>::Reserve (const int theNbNodes)
-{
- BVH::Array<T, N>::Reserve (this->myMinPointBuffer, theNbNodes);
- BVH::Array<T, N>::Reserve (this->myMaxPointBuffer, theNbNodes);
- BVH::Array<int, 4>::Reserve (this->myNodeInfoBuffer, theNbNodes);
-}
-
-// =======================================================================
-// function : CollapseToQuadTree
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Tree<T, N, BVH_QuadTree>* BVH_Tree<T, N, BVH_BinaryTree>::CollapseToQuadTree() const
-{
- BVH_Tree<T, N, BVH_QuadTree>* aQBVH = new BVH_Tree<T, N, BVH_QuadTree>;
-
- if (this->Length() == 0)
- {
- return aQBVH;
- }
-
- std::deque<std::pair<int, int> > aQueue (1, std::make_pair (0, 0));
-
- for (int aNbNodes = 1; !aQueue.empty();)
- {
- const std::pair<int, int> aNode = aQueue.front();
-
- BVH::Array<T, N>::Append (aQBVH->myMinPointBuffer, BVH::Array<T, N>::Value (this->myMinPointBuffer, std::get<0> (aNode)));
- BVH::Array<T, N>::Append (aQBVH->myMaxPointBuffer, BVH::Array<T, N>::Value (this->myMaxPointBuffer, std::get<0> (aNode)));
-
- BVH_Vec4i aNodeInfo;
-
- if (this->IsOuter (std::get<0> (aNode))) // is leaf node
- {
- aNodeInfo = BVH_Vec4i (1 /* leaf flag */,
- this->BegPrimitive (std::get<0> (aNode)), this->EndPrimitive (std::get<0> (aNode)), std::get<1> (aNode) /* level */);
- }
- else
- {
- NCollection_Vector<int> aGrandChildNodes;
-
- const int aLftChild = Child<0> (std::get<0> (aNode));
- const int aRghChild = Child<1> (std::get<0> (aNode));
-
- if (this->IsOuter (aLftChild)) // is leaf node
- {
- aGrandChildNodes.Append (aLftChild);
- }
- else
- {
- aGrandChildNodes.Append (Child<0> (aLftChild));
- aGrandChildNodes.Append (Child<1> (aLftChild));
- }
-
- if (this->IsOuter (aRghChild)) // is leaf node
- {
- aGrandChildNodes.Append (aRghChild);
- }
- else
- {
- aGrandChildNodes.Append (Child<0> (aRghChild));
- aGrandChildNodes.Append (Child<1> (aRghChild));
- }
-
- for (int aNodeIdx = 0; aNodeIdx < aGrandChildNodes.Size(); ++aNodeIdx)
- {
- aQueue.push_back (std::make_pair (aGrandChildNodes (aNodeIdx), std::get<1> (aNode) + 1));
- }
-
- aNodeInfo = BVH_Vec4i (0 /* inner flag */,
- aNbNodes, aGrandChildNodes.Size() - 1, std::get<1> (aNode) /* level */);
-
- aQBVH->myDepth = Max (aQBVH->myDepth, std::get<1> (aNode) + 1);
-
- aNbNodes += aGrandChildNodes.Size();
- }
-
- BVH::Array<int, 4>::Append (aQBVH->myNodeInfoBuffer, aNodeInfo);
-
- aQueue.pop_front(); // node processing completed
- }
-
- return aQBVH;
-}
#include <algorithm>
+#if defined (_WIN32) && defined (max)
+ #undef max
+#endif
+
+#include <limits>
+
//! Stores parameters of single bin (slice of AABB).
template<class T, int N>
struct BVH_Bin
BVH_BinnedBuilder (const Standard_Integer theLeafNodeSize = 5,
const Standard_Integer theMaxTreeDepth = 32,
const Standard_Boolean theDoMainSplits = 0,
- const Standard_Integer theNumOfThreads = 1);
+ const Standard_Integer theNumOfThreads = 1)
+ : BVH_QueueBuilder<T, N> (theLeafNodeSize, theMaxTreeDepth, theNumOfThreads),
+ myUseMainAxis (theDoMainSplits)
+ {
+ //
+ }
//! Releases resources of binned SAH BVH builder.
- virtual ~BVH_BinnedBuilder();
+ virtual ~BVH_BinnedBuilder() {}
protected:
//! Performs splitting of the given BVH node.
- typename BVH_QueueBuilder<T, N>::BVH_ChildNodes BuildNode (BVH_Set<T, N>* theSet,
- BVH_Tree<T, N>* theBVH,
- const Standard_Integer theNode);
+ virtual typename BVH_QueueBuilder<T, N>::BVH_ChildNodes buildNode (BVH_Set<T, N>* theSet,
+ BVH_Tree<T, N>* theBVH,
+ const Standard_Integer theNode) const Standard_OVERRIDE;
//! Arranges node primitives into bins.
- virtual void GetSubVolumes (BVH_Set<T, N>* theSet,
+ virtual void getSubVolumes (BVH_Set<T, N>* theSet,
BVH_Tree<T, N>* theBVH,
const Standard_Integer theNode,
BVH_BinVector& theBins,
- const Standard_Integer theAxis);
+ const Standard_Integer theAxis) const;
private:
};
-#include <BVH_BinnedBuilder.lxx>
+// =======================================================================
+// function : getSubVolumes
+// purpose :
+// =======================================================================
+template<class T, int N, int Bins>
+void BVH_BinnedBuilder<T, N, Bins>::getSubVolumes (BVH_Set<T, N>* theSet,
+ BVH_Tree<T, N>* theBVH,
+ const Standard_Integer theNode,
+ BVH_BinVector& theBins,
+ const Standard_Integer theAxis) const
+{
+ const T aMin = BVH::VecComp<T, N>::Get (theBVH->MinPoint (theNode), theAxis);
+ const T aMax = BVH::VecComp<T, N>::Get (theBVH->MaxPoint (theNode), theAxis);
+ const T anInverseStep = static_cast<T> (Bins) / (aMax - aMin);
+ for (Standard_Integer anIdx = theBVH->BegPrimitive (theNode); anIdx <= theBVH->EndPrimitive (theNode); ++anIdx)
+ {
+ typename BVH_Set<T, N>::BVH_BoxNt aBox = theSet->Box (anIdx);
+ Standard_Integer aBinIndex = BVH::IntFloor<T> ((theSet->Center (anIdx, theAxis) - aMin) * anInverseStep);
+ if (aBinIndex < 0)
+ {
+ aBinIndex = 0;
+ }
+ else if (aBinIndex >= Bins)
+ {
+ aBinIndex = Bins - 1;
+ }
+
+ theBins[aBinIndex].Count++;
+ theBins[aBinIndex].Box.Combine (aBox);
+ }
+}
+
+namespace BVH
+{
+ template<class T, int N>
+ Standard_Integer SplitPrimitives (BVH_Set<T, N>* theSet,
+ const BVH_Box<T, N>& theBox,
+ const Standard_Integer theBeg,
+ const Standard_Integer theEnd,
+ const Standard_Integer theBin,
+ const Standard_Integer theAxis,
+ const Standard_Integer theBins)
+ {
+ const T aMin = BVH::VecComp<T, N>::Get (theBox.CornerMin(), theAxis);
+ const T aMax = BVH::VecComp<T, N>::Get (theBox.CornerMax(), theAxis);
+
+ const T anInverseStep = static_cast<T> (theBins) / (aMax - aMin);
+
+ Standard_Integer aLftIdx (theBeg);
+ Standard_Integer aRghIdx (theEnd);
+
+ do
+ {
+ while (BVH::IntFloor<T> ((theSet->Center (aLftIdx, theAxis) - aMin) * anInverseStep) <= theBin && aLftIdx < theEnd)
+ {
+ ++aLftIdx;
+ }
+ while (BVH::IntFloor<T> ((theSet->Center (aRghIdx, theAxis) - aMin) * anInverseStep) > theBin && aRghIdx > theBeg)
+ {
+ --aRghIdx;
+ }
+
+ if (aLftIdx <= aRghIdx)
+ {
+ if (aLftIdx != aRghIdx)
+ {
+ theSet->Swap (aLftIdx, aRghIdx);
+ }
+
+ ++aLftIdx;
+ --aRghIdx;
+ }
+ } while (aLftIdx <= aRghIdx);
+
+ return aLftIdx;
+ }
+
+ template<class T, int N>
+ struct BVH_AxisSelector
+ {
+ typedef typename BVH::VectorType<T, N>::Type BVH_VecNt;
+ static Standard_Integer MainAxis (const BVH_VecNt& theSize)
+ {
+ if (theSize.y() > theSize.x())
+ {
+ return theSize.y() > theSize.z() ? 1 : 2;
+ }
+ else
+ {
+ return theSize.z() > theSize.x() ? 2 : 0;
+ }
+ }
+ };
+
+ template<class T>
+ struct BVH_AxisSelector<T, 2>
+ {
+ typedef typename BVH::VectorType<T, 2>::Type BVH_VecNt;
+ static Standard_Integer MainAxis (const BVH_VecNt& theSize)
+ {
+ return theSize.x() > theSize.y() ? 0 : 1;
+ }
+ };
+}
+
+// =======================================================================
+// function : buildNode
+// purpose :
+// =======================================================================
+template<class T, int N, int Bins>
+typename BVH_QueueBuilder<T, N>::BVH_ChildNodes BVH_BinnedBuilder<T, N, Bins>::buildNode (BVH_Set<T, N>* theSet,
+ BVH_Tree<T, N>* theBVH,
+ const Standard_Integer theNode) const
+{
+ const Standard_Integer aNodeBegPrimitive = theBVH->BegPrimitive (theNode);
+ const Standard_Integer aNodeEndPrimitive = theBVH->EndPrimitive (theNode);
+ if (aNodeEndPrimitive - aNodeBegPrimitive < BVH_Builder<T, N>::myLeafNodeSize)
+ {
+ return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes(); // node does not require partitioning
+ }
+
+ const BVH_Box<T, N> anAABB (theBVH->MinPoint (theNode),
+ theBVH->MaxPoint (theNode));
+ const typename BVH_Box<T, N>::BVH_VecNt aSize = anAABB.Size();
+
+ // Parameters for storing best split
+ Standard_Integer aMinSplitAxis = -1;
+ Standard_Integer aMinSplitIndex = 0;
+ Standard_Integer aMinSplitNumLft = 0;
+ Standard_Integer aMinSplitNumRgh = 0;
+
+ BVH_Box<T, N> aMinSplitBoxLft;
+ BVH_Box<T, N> aMinSplitBoxRgh;
+
+ Standard_Real aMinSplitCost = std::numeric_limits<Standard_Real>::max();
+ const Standard_Integer aMainAxis = BVH::BVH_AxisSelector<T, N>::MainAxis (aSize);
+
+ // Find best split
+ for (Standard_Integer anAxis = myUseMainAxis ? aMainAxis : 0; anAxis <= (myUseMainAxis ? aMainAxis : Min (N - 1, 2)); ++anAxis)
+ {
+ if (BVH::VecComp<T, N>::Get (aSize, anAxis) <= BVH::THE_NODE_MIN_SIZE)
+ {
+ continue;
+ }
+
+ BVH_BinVector aBinVector;
+ getSubVolumes (theSet, theBVH, theNode, aBinVector, anAxis);
+
+ BVH_SplitPlanes aSplitPlanes;
+ for (Standard_Integer aLftSplit = 1, aRghSplit = Bins - 1; aLftSplit < Bins; ++aLftSplit, --aRghSplit)
+ {
+ aSplitPlanes[aLftSplit].LftVoxel.Count = aSplitPlanes[aLftSplit - 1].LftVoxel.Count + aBinVector[aLftSplit - 1].Count;
+ aSplitPlanes[aRghSplit].RghVoxel.Count = aSplitPlanes[aRghSplit + 1].RghVoxel.Count + aBinVector[aRghSplit + 0].Count;
+
+ aSplitPlanes[aLftSplit].LftVoxel.Box = aSplitPlanes[aLftSplit - 1].LftVoxel.Box;
+ aSplitPlanes[aRghSplit].RghVoxel.Box = aSplitPlanes[aRghSplit + 1].RghVoxel.Box;
+
+ aSplitPlanes[aLftSplit].LftVoxel.Box.Combine (aBinVector[aLftSplit - 1].Box);
+ aSplitPlanes[aRghSplit].RghVoxel.Box.Combine (aBinVector[aRghSplit + 0].Box);
+ }
+
+ // Choose the best split (with minimum SAH cost)
+ for (Standard_Integer aSplit = 1; aSplit < Bins; ++aSplit)
+ {
+ // Simple SAH evaluation
+ Standard_Real aCost =
+ (static_cast<Standard_Real> (aSplitPlanes[aSplit].LftVoxel.Box.Area()) /* / S(N) */) * aSplitPlanes[aSplit].LftVoxel.Count
+ + (static_cast<Standard_Real> (aSplitPlanes[aSplit].RghVoxel.Box.Area()) /* / S(N) */) * aSplitPlanes[aSplit].RghVoxel.Count;
+
+ if (aCost <= aMinSplitCost)
+ {
+ aMinSplitCost = aCost;
+ aMinSplitAxis = anAxis;
+ aMinSplitIndex = aSplit;
+ aMinSplitBoxLft = aSplitPlanes[aSplit].LftVoxel.Box;
+ aMinSplitBoxRgh = aSplitPlanes[aSplit].RghVoxel.Box;
+ aMinSplitNumLft = aSplitPlanes[aSplit].LftVoxel.Count;
+ aMinSplitNumRgh = aSplitPlanes[aSplit].RghVoxel.Count;
+ }
+ }
+ }
+
+ theBVH->SetInner (theNode);
+ Standard_Integer aMiddle = -1;
+ if (aMinSplitNumLft == 0 || aMinSplitNumRgh == 0 || aMinSplitAxis == -1) // case of objects with the same center
+ {
+ aMinSplitBoxLft.Clear();
+ aMinSplitBoxRgh.Clear();
+
+ aMiddle = std::max (aNodeBegPrimitive + 1,
+ static_cast<Standard_Integer> ((aNodeBegPrimitive + aNodeEndPrimitive) / 2.f));
+
+ aMinSplitNumLft = aMiddle - aNodeBegPrimitive;
+ for (Standard_Integer anIndex = aNodeBegPrimitive; anIndex < aMiddle; ++anIndex)
+ {
+ aMinSplitBoxLft.Combine (theSet->Box (anIndex));
+ }
+
+ aMinSplitNumRgh = aNodeEndPrimitive - aMiddle + 1;
+ for (Standard_Integer anIndex = aNodeEndPrimitive; anIndex >= aMiddle; --anIndex)
+ {
+ aMinSplitBoxRgh.Combine (theSet->Box (anIndex));
+ }
+ }
+ else
+ {
+ aMiddle = BVH::SplitPrimitives<T, N> (theSet,
+ anAABB,
+ aNodeBegPrimitive,
+ aNodeEndPrimitive,
+ aMinSplitIndex - 1,
+ aMinSplitAxis,
+ Bins);
+ }
+
+ typedef typename BVH_QueueBuilder<T, N>::BVH_PrimitiveRange Range;
+ return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes (aMinSplitBoxLft,
+ aMinSplitBoxRgh,
+ Range (aNodeBegPrimitive, aMiddle - 1),
+ Range (aMiddle, aNodeEndPrimitive));
+}
#endif // _BVH_BinnedBuilder_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// =======================================================================
-// function : BVH_BinnedBuilder
-// purpose :
-// =======================================================================
-template<class T, int N, int Bins>
-BVH_BinnedBuilder<T, N, Bins>::BVH_BinnedBuilder (const Standard_Integer theLeafNodeSize,
- const Standard_Integer theMaxTreeDepth,
- const Standard_Boolean theDoMainSplits,
- const Standard_Integer theNumOfThreads)
-: BVH_QueueBuilder<T, N> (theLeafNodeSize,
- theMaxTreeDepth,
- theNumOfThreads),
- myUseMainAxis (theDoMainSplits)
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_BinnedBuilder
-// purpose :
-// =======================================================================
-template<class T, int N, int Bins>
-BVH_BinnedBuilder<T, N, Bins>::~BVH_BinnedBuilder()
-{
- //
-}
-
-// =======================================================================
-// function : GetSubVolumes
-// purpose :
-// =======================================================================
-template<class T, int N, int Bins>
-void BVH_BinnedBuilder<T, N, Bins>::GetSubVolumes (BVH_Set<T, N>* theSet,
- BVH_Tree<T, N>* theBVH,
- const Standard_Integer theNode,
- BVH_BinVector& theBins,
- const Standard_Integer theAxis)
-{
- const T aMin = BVH::VecComp<T, N>::Get (theBVH->MinPoint (theNode), theAxis);
- const T aMax = BVH::VecComp<T, N>::Get (theBVH->MaxPoint (theNode), theAxis);
-
- const T anInverseStep = static_cast<T> (Bins) / (aMax - aMin);
-
- for (Standard_Integer anIdx = theBVH->BegPrimitive (theNode); anIdx <= theBVH->EndPrimitive (theNode); ++anIdx)
- {
- typename BVH_Set<T, N>::BVH_BoxNt aBox = theSet->Box (anIdx);
-
- Standard_Integer aBinIndex = BVH::IntFloor<T> (
- (theSet->Center (anIdx, theAxis) - aMin) * anInverseStep);
-
- if (aBinIndex < 0)
- {
- aBinIndex = 0;
- }
- else if (aBinIndex >= Bins)
- {
- aBinIndex = Bins - 1;
- }
-
- theBins[aBinIndex].Count++;
- theBins[aBinIndex].Box.Combine (aBox);
- }
-}
-
-namespace BVH
-{
- // =======================================================================
- // function : SplitPrimitives
- // purpose :
- // =======================================================================
- template<class T, int N>
- Standard_Integer SplitPrimitives (BVH_Set<T, N>* theSet,
- const BVH_Box<T, N>& theBox,
- const Standard_Integer theBeg,
- const Standard_Integer theEnd,
- const Standard_Integer theBin,
- const Standard_Integer theAxis,
- const Standard_Integer theBins)
- {
- const T aMin = BVH::VecComp<T, N>::Get (theBox.CornerMin(), theAxis);
- const T aMax = BVH::VecComp<T, N>::Get (theBox.CornerMax(), theAxis);
-
- const T anInverseStep = static_cast<T> (theBins) / (aMax - aMin);
-
- Standard_Integer aLftIdx (theBeg);
- Standard_Integer aRghIdx (theEnd);
-
- do
- {
- while (BVH::IntFloor<T> ((theSet->Center (aLftIdx, theAxis) - aMin) * anInverseStep) <= theBin && aLftIdx < theEnd)
- {
- ++aLftIdx;
- }
- while (BVH::IntFloor<T> ((theSet->Center (aRghIdx, theAxis) - aMin) * anInverseStep) > theBin && aRghIdx > theBeg)
- {
- --aRghIdx;
- }
-
- if (aLftIdx <= aRghIdx)
- {
- if (aLftIdx != aRghIdx)
- {
- theSet->Swap (aLftIdx, aRghIdx);
- }
-
- ++aLftIdx;
- --aRghIdx;
- }
- } while (aLftIdx <= aRghIdx);
-
- return aLftIdx;
- }
-}
-
-#if defined (_WIN32) && defined (max)
- #undef max
-#endif
-
-#include <limits>
-
-namespace BVH
-{
- template<class T, int N>
- struct BVH_AxisSelector
- {
- typedef typename BVH::VectorType<T, N>::Type BVH_VecNt;
-
- // =======================================================================
- // function : MainAxis
- // purpose :
- // =======================================================================
- static Standard_Integer MainAxis (const BVH_VecNt& theSize)
- {
- if (theSize.y() > theSize.x())
- {
- return theSize.y() > theSize.z() ? 1 : 2;
- }
- else
- {
- return theSize.z() > theSize.x() ? 2 : 0;
- }
- }
- };
-
- template<class T>
- struct BVH_AxisSelector<T, 2>
- {
- typedef typename BVH::VectorType<T, 2>::Type BVH_VecNt;
-
- // =======================================================================
- // function : MainAxis
- // purpose :
- // =======================================================================
- static Standard_Integer MainAxis (const BVH_VecNt& theSize)
- {
- return theSize.x() > theSize.y() ? 0 : 1;
- }
- };
-}
-
-// =======================================================================
-// function : BuildNode
-// purpose :
-// =======================================================================
-template<class T, int N, int Bins>
-typename BVH_QueueBuilder<T, N>::BVH_ChildNodes BVH_BinnedBuilder<T, N, Bins>::BuildNode (BVH_Set<T, N>* theSet,
- BVH_Tree<T, N>* theBVH,
- const Standard_Integer theNode)
-{
- const Standard_Integer aNodeBegPrimitive = theBVH->BegPrimitive (theNode);
- const Standard_Integer aNodeEndPrimitive = theBVH->EndPrimitive (theNode);
-
- if (aNodeEndPrimitive - aNodeBegPrimitive < BVH_Builder<T, N>::myLeafNodeSize)
- {
- return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes(); // node does not require partitioning
- }
-
- const BVH_Box<T, N> anAABB (theBVH->MinPoint (theNode),
- theBVH->MaxPoint (theNode));
-
- const typename BVH_Box<T, N>::BVH_VecNt aSize = anAABB.Size();
-
- // Parameters for storing best split
- Standard_Integer aMinSplitAxis = -1;
- Standard_Integer aMinSplitIndex = 0;
- Standard_Integer aMinSplitNumLft = 0;
- Standard_Integer aMinSplitNumRgh = 0;
-
- BVH_Box<T, N> aMinSplitBoxLft;
- BVH_Box<T, N> aMinSplitBoxRgh;
-
- Standard_Real aMinSplitCost = std::numeric_limits<Standard_Real>::max();
-
- const Standard_Integer aMainAxis = BVH::BVH_AxisSelector<T, N>::MainAxis (aSize);
-
- // Find best split
- for (Standard_Integer anAxis = myUseMainAxis ? aMainAxis : 0; anAxis <= (myUseMainAxis ? aMainAxis : Min (N - 1, 2)); ++anAxis)
- {
- if (BVH::VecComp<T, N>::Get (aSize, anAxis) <= BVH::THE_NODE_MIN_SIZE)
- {
- continue;
- }
-
- BVH_BinVector aBinVector;
- GetSubVolumes (theSet, theBVH, theNode, aBinVector, anAxis);
-
- BVH_SplitPlanes aSplitPlanes;
- for (Standard_Integer aLftSplit = 1, aRghSplit = Bins - 1; aLftSplit < Bins; ++aLftSplit, --aRghSplit)
- {
- aSplitPlanes[aLftSplit].LftVoxel.Count = aSplitPlanes[aLftSplit - 1].LftVoxel.Count + aBinVector[aLftSplit - 1].Count;
- aSplitPlanes[aRghSplit].RghVoxel.Count = aSplitPlanes[aRghSplit + 1].RghVoxel.Count + aBinVector[aRghSplit + 0].Count;
-
- aSplitPlanes[aLftSplit].LftVoxel.Box = aSplitPlanes[aLftSplit - 1].LftVoxel.Box;
- aSplitPlanes[aRghSplit].RghVoxel.Box = aSplitPlanes[aRghSplit + 1].RghVoxel.Box;
-
- aSplitPlanes[aLftSplit].LftVoxel.Box.Combine (aBinVector[aLftSplit - 1].Box);
- aSplitPlanes[aRghSplit].RghVoxel.Box.Combine (aBinVector[aRghSplit + 0].Box);
- }
-
- // Choose the best split (with minimum SAH cost)
- for (Standard_Integer aSplit = 1; aSplit < Bins; ++aSplit)
- {
- // Simple SAH evaluation
- Standard_Real aCost =
- (static_cast<Standard_Real> (aSplitPlanes[aSplit].LftVoxel.Box.Area()) /* / S(N) */) * aSplitPlanes[aSplit].LftVoxel.Count
- + (static_cast<Standard_Real> (aSplitPlanes[aSplit].RghVoxel.Box.Area()) /* / S(N) */) * aSplitPlanes[aSplit].RghVoxel.Count;
-
- if (aCost <= aMinSplitCost)
- {
- aMinSplitCost = aCost;
- aMinSplitAxis = anAxis;
- aMinSplitIndex = aSplit;
- aMinSplitBoxLft = aSplitPlanes[aSplit].LftVoxel.Box;
- aMinSplitBoxRgh = aSplitPlanes[aSplit].RghVoxel.Box;
- aMinSplitNumLft = aSplitPlanes[aSplit].LftVoxel.Count;
- aMinSplitNumRgh = aSplitPlanes[aSplit].RghVoxel.Count;
- }
- }
- }
-
- theBVH->SetInner (theNode);
-
- Standard_Integer aMiddle = -1;
-
- if (aMinSplitNumLft == 0 || aMinSplitNumRgh == 0 || aMinSplitAxis == -1) // case of objects with the same center
- {
- aMinSplitBoxLft.Clear();
- aMinSplitBoxRgh.Clear();
-
- aMiddle = std::max (aNodeBegPrimitive + 1,
- static_cast<Standard_Integer> ((aNodeBegPrimitive + aNodeEndPrimitive) / 2.f));
-
- aMinSplitNumLft = aMiddle - aNodeBegPrimitive;
-
- for (Standard_Integer anIndex = aNodeBegPrimitive; anIndex < aMiddle; ++anIndex)
- {
- aMinSplitBoxLft.Combine (theSet->Box (anIndex));
- }
-
- aMinSplitNumRgh = aNodeEndPrimitive - aMiddle + 1;
-
- for (Standard_Integer anIndex = aNodeEndPrimitive; anIndex >= aMiddle; --anIndex)
- {
- aMinSplitBoxRgh.Combine (theSet->Box (anIndex));
- }
- }
- else
- {
- aMiddle = BVH::SplitPrimitives<T, N> (theSet,
- anAABB,
- aNodeBegPrimitive,
- aNodeEndPrimitive,
- aMinSplitIndex - 1,
- aMinSplitAxis,
- Bins);
- }
-
- typedef typename BVH_QueueBuilder<T, N>::BVH_PrimitiveRange Range;
-
- return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes (aMinSplitBoxLft,
- aMinSplitBoxRgh,
- Range (aNodeBegPrimitive, aMiddle - 1),
- Range (aMiddle, aNodeEndPrimitive));
-}
#define _BVH_Box_Header
#include <BVH_Types.hxx>
+#include <Standard_ShortReal.hxx>
#include <limits>
public:
//! Clears bounding box.
- void Clear();
+ void Clear() { myIsInited = Standard_False; }
//! Is bounding box valid?
- Standard_Boolean IsValid() const;
+ Standard_Boolean IsValid() const { return myIsInited; }
//! Appends new point to the bounding box.
- void Add (const BVH_VecNt& thePoint);
+ void Add (const BVH_VecNt& thePoint)
+ {
+ if (!myIsInited)
+ {
+ myMinPoint = thePoint;
+ myMaxPoint = thePoint;
+ myIsInited = Standard_True;
+ }
+ else
+ {
+ myMinPoint = myMinPoint.cwiseMin (thePoint);
+ myMaxPoint = myMaxPoint.cwiseMax (thePoint);
+ }
+ }
//! Combines bounding box with another one.
- void Combine (const BVH_Box& theVolume);
+ void Combine (const BVH_Box& theBox);
//! Returns minimum point of bounding box.
- const BVH_VecNt& CornerMin() const;
+ const BVH_VecNt& CornerMin() const { return myMinPoint; }
//! Returns maximum point of bounding box.
- const BVH_VecNt& CornerMax() const;
+ const BVH_VecNt& CornerMax() const { return myMaxPoint; }
//! Returns minimum point of bounding box.
- BVH_VecNt& CornerMin();
+ BVH_VecNt& CornerMin() { return myMinPoint; }
//! Returns maximum point of bounding box.
- BVH_VecNt& CornerMax();
+ BVH_VecNt& CornerMax() { return myMaxPoint; }
//! Returns surface area of bounding box.
//! If the box is degenerated into line, returns the perimeter instead.
T Area() const;
//! Returns diagonal of bounding box.
- BVH_VecNt Size() const;
+ BVH_VecNt Size() const { return myMaxPoint - myMinPoint; }
//! Returns center of bounding box.
- BVH_VecNt Center() const;
+ BVH_VecNt Center() const { return (myMinPoint + myMaxPoint) * static_cast<T> (0.5); }
//! Returns center of bounding box along the given axis.
T Center (const Standard_Integer theAxis) const;
};
}
-#include <BVH_Box.lxx>
+// =======================================================================
+// function : Combine
+// purpose :
+// =======================================================================
+template<class T, int N>
+void BVH_Box<T, N>::Combine (const BVH_Box& theBox)
+{
+ if (theBox.myIsInited)
+ {
+ if (!myIsInited)
+ {
+ myMinPoint = theBox.myMinPoint;
+ myMaxPoint = theBox.myMaxPoint;
+ myIsInited = Standard_True;
+ }
+ else
+ {
+ BVH::BoxMinMax<T, N>::CwiseMin (myMinPoint, theBox.myMinPoint);
+ BVH::BoxMinMax<T, N>::CwiseMax (myMaxPoint, theBox.myMaxPoint);
+ }
+ }
+}
+
+// =======================================================================
+// function : Area
+// purpose :
+// =======================================================================
+template<class T, int N>
+T BVH_Box<T, N>::Area() const
+{
+ return !myIsInited ? static_cast<T> (0.0) : BVH::SurfaceCalculator<T, N>::Area (myMaxPoint - myMinPoint);
+}
+
+// =======================================================================
+// function : Center
+// purpose :
+// =======================================================================
+template<class T, int N>
+T BVH_Box<T, N>::Center (const Standard_Integer theAxis) const
+{
+ return BVH::CenterAxis<T, N>::Center (*this, theAxis);
+}
#endif // _BVH_Box_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <Standard_ShortReal.hxx>
-
-// =======================================================================
-// function : Clear
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Box<T, N>::Clear()
-{
- myIsInited = Standard_False;
-}
-
-// =======================================================================
-// function : Clear
-// purpose :
-// =======================================================================
-template<class T, int N>
-Standard_Boolean BVH_Box<T, N>::IsValid() const
-{
- return myIsInited;
-}
-
-// =======================================================================
-// function : Add
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Box<T, N>::Add (const BVH_VecNt& thePoint)
-{
- if (!myIsInited)
- {
- myMinPoint = thePoint;
- myMaxPoint = thePoint;
-
- myIsInited = Standard_True;
- }
- else
- {
- myMinPoint = myMinPoint.cwiseMin (thePoint);
- myMaxPoint = myMaxPoint.cwiseMax (thePoint);
- }
-}
-
-// =======================================================================
-// function : Combine
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Box<T, N>::Combine (const BVH_Box& theBox)
-{
- if (theBox.myIsInited)
- {
- if (!myIsInited)
- {
- myMinPoint = theBox.myMinPoint;
- myMaxPoint = theBox.myMaxPoint;
-
- myIsInited = Standard_True;
- }
- else
- {
- BVH::BoxMinMax<T, N>::CwiseMin (myMinPoint, theBox.myMinPoint);
- BVH::BoxMinMax<T, N>::CwiseMax (myMaxPoint, theBox.myMaxPoint);
- }
- }
-}
-
-// =======================================================================
-// function : Area
-// purpose :
-// =======================================================================
-template<class T, int N>
-T BVH_Box<T, N>::Area() const
-{
- return !myIsInited ? static_cast<T> (0.0) :
- BVH::SurfaceCalculator<T, N>::Area (myMaxPoint - myMinPoint);
-}
-
-// =======================================================================
-// function : CornerMin
-// purpose :
-// =======================================================================
-template<class T, int N>
-const typename BVH_Box<T, N>::BVH_VecNt& BVH_Box<T, N>::CornerMin() const
-{
- return myMinPoint;
-}
-
-// =======================================================================
-// function : CornerMax
-// purpose :
-// =======================================================================
-template<class T, int N>
-const typename BVH_Box<T, N>::BVH_VecNt& BVH_Box<T, N>::CornerMax() const
-{
- return myMaxPoint;
-}
-
-// =======================================================================
-// function : CornerMin
-// purpose :
-// =======================================================================
-template<class T, int N>
-typename BVH_Box<T, N>::BVH_VecNt& BVH_Box<T, N>::CornerMin()
-{
- return myMinPoint;
-}
-
-// =======================================================================
-// function : CornerMax
-// purpose :
-// =======================================================================
-template<class T, int N>
-typename BVH_Box<T, N>::BVH_VecNt& BVH_Box<T, N>::CornerMax()
-{
- return myMaxPoint;
-}
-
-// =======================================================================
-// function : Size
-// purpose :
-// =======================================================================
-template<class T, int N>
-typename BVH_Box<T, N>::BVH_VecNt BVH_Box<T, N>::Size() const
-{
- return myMaxPoint - myMinPoint;
-}
-
-// =======================================================================
-// function : Center
-// purpose :
-// =======================================================================
-template<class T, int N>
-typename BVH_Box<T, N>::BVH_VecNt BVH_Box<T, N>::Center() const
-{
- return (myMinPoint + myMaxPoint) * static_cast<T> (0.5);
-}
-
-// =======================================================================
-// function : Center
-// purpose :
-// =======================================================================
-template<class T, int N>
-T BVH_Box<T, N>::Center (const Standard_Integer theAxis) const
-{
- return BVH::CenterAxis<T, N>::Center (*this, theAxis);
-}
//! Creates new abstract BVH builder.
BVH_Builder (const Standard_Integer theLeafNodeSize,
- const Standard_Integer theMaxTreeDepth);
+ const Standard_Integer theMaxTreeDepth)
+ : myMaxTreeDepth (theMaxTreeDepth),
+ myLeafNodeSize (theLeafNodeSize) {}
//! Releases resources of BVH builder.
- virtual ~BVH_Builder();
+ virtual ~BVH_Builder() {}
//! Builds BVH using specific algorithm.
virtual void Build (BVH_Set<T, N>* theSet,
BVH_Tree<T, N>* theBVH,
- const BVH_Box<T, N>& theBox) = 0;
+ const BVH_Box<T, N>& theBox) const = 0;
protected:
//! Updates depth of constructed BVH tree.
- void UpdateDepth (BVH_Tree<T, N>* theBVH,
- const Standard_Integer theLevel)
+ void updateDepth (BVH_Tree<T, N>* theBVH,
+ const Standard_Integer theLevel) const
{
if (theLevel > theBVH->myDepth)
{
};
-#include <BVH_Builder.lxx>
-
#endif // _BVH_Builder_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// =======================================================================
-// function : BVH_Builder
-// purpose : Creates abstract BVH builder
-// =======================================================================
-template<class T, int N>
-BVH_Builder<T, N>::BVH_Builder (const Standard_Integer theLeafNodeSize,
- const Standard_Integer theMaxTreeDepth)
-: myMaxTreeDepth (theMaxTreeDepth),
- myLeafNodeSize (theLeafNodeSize)
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_Builder
-// purpose : Releases resources of BVH builder
-// =======================================================================
-template<class T, int N>
-BVH_Builder<T, N>::~BVH_Builder()
-{
- //
-}
#include <BVH_ObjectSet.hxx>
#include <BVH_Builder.hxx>
+#include <BVH_BinnedBuilder.hxx>
//! BVH geometry as a set of abstract geometric objects
//! organized with bounding volume hierarchy (BVH).
public:
//! Creates uninitialized BVH geometry.
- BVH_Geometry();
+ BVH_Geometry()
+ : myIsDirty (Standard_False),
+ myBVH (new BVH_Tree<T, N>())
+ {
+ // Set default builder - binned SAH split
+ myBuilder = new BVH_BinnedBuilder<T, N, 32> (1 /* primitive per leaf */);
+ }
//! Releases resources of BVH geometry.
- virtual ~BVH_Geometry();
+ virtual ~BVH_Geometry()
+ {
+ myBVH.Nullify();
+ myBuilder.Nullify();
+ }
public:
//! Marks geometry as outdated.
- virtual void MarkDirty();
+ virtual void MarkDirty() { myIsDirty = Standard_True; }
//! Returns AABB of the given object.
using BVH_ObjectSet<T, N>::Box;
//! Returns AABB of the whole geometry.
- virtual BVH_Box<T, N> Box() const;
+ virtual BVH_Box<T, N> Box() const Standard_OVERRIDE
+ {
+ if (myIsDirty)
+ {
+ myBox = BVH_Set<T, N>::Box();
+ }
+ return myBox;
+ }
//! Returns BVH tree (and builds it if necessary).
- virtual const NCollection_Handle<BVH_Tree<T, N> >& BVH();
+ virtual const NCollection_Handle<BVH_Tree<T, N> >& BVH()
+ {
+ if (myIsDirty)
+ {
+ Update();
+ }
+ return myBVH;
+ }
//! Returns the method (builder) used to construct BVH.
- virtual const NCollection_Handle<BVH_Builder<T, N> >& Builder() const;
+ virtual const NCollection_Handle<BVH_Builder<T, N> >& Builder() const { return myBuilder; }
//! Sets the method (builder) used to construct BVH.
- virtual void SetBuilder (NCollection_Handle<BVH_Builder<T, N> >& theBuilder);
+ virtual void SetBuilder (const NCollection_Handle<BVH_Builder<T, N> >& theBuilder) { myBuilder = theBuilder; }
protected:
//! Updates internal geometry state.
- virtual void Update();
+ virtual void Update()
+ {
+ if (myIsDirty)
+ {
+ myBuilder->Build (this, myBVH.operator->(), Box());
+ myIsDirty = Standard_False;
+ }
+ }
protected:
};
-#include <BVH_Geometry.lxx>
-
#endif // _BVH_Geometry_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <BVH_BinnedBuilder.hxx>
-
-// =======================================================================
-// function : BVH_Geometry
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Geometry<T, N>::BVH_Geometry()
-: myIsDirty (Standard_False),
- myBVH (new BVH_Tree<T, N>())
-{
- // Set default builder - binned SAH split
- myBuilder = new BVH_BinnedBuilder<T, N, 32> (1 /* primitive per leaf */);
-}
-
-// =======================================================================
-// function : ~BVH_Geometry
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Geometry<T, N>::~BVH_Geometry()
-{
- myBVH.Nullify();
- myBuilder.Nullify();
-}
-
-// =======================================================================
-// function : MarkDirty
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Geometry<T, N>::MarkDirty()
-{
- myIsDirty = Standard_True;
-}
-
-// =======================================================================
-// function : Box
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Box<T, N> BVH_Geometry<T, N>::Box() const
-{
- if (!myIsDirty)
- {
- return myBox;
- }
-
- myBox = BVH_Set<T, N>::Box();
- return myBox;
-}
-
-// =======================================================================
-// function : BVH
-// purpose :
-// =======================================================================
-template<class T, int N>
-const NCollection_Handle<BVH_Tree<T, N> >& BVH_Geometry<T, N>::BVH()
-{
- if (myIsDirty)
- {
- Update();
- }
-
- return myBVH;
-}
-
-// =======================================================================
-// function : Update
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Geometry<T, N>::Update()
-{
- if (!myIsDirty)
- {
- return;
- }
-
- myBuilder->Build (this, myBVH.operator->(), Box());
-
- myIsDirty = Standard_False;
-}
-
-// =======================================================================
-// function : Builder
-// purpose :
-// =======================================================================
-template<class T, int N>
-const NCollection_Handle<BVH_Builder<T, N> >& BVH_Geometry<T, N>::Builder() const
-{
- return myBuilder;
-}
-
-// =======================================================================
-// function : SetBuilder
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Geometry<T, N>::SetBuilder (NCollection_Handle<BVH_Builder<T, N> >& theBuilder)
-{
- myBuilder = theBuilder;
-}
#define _BVH_LinearBuilder_Header
#include <BVH_RadixSorter.hxx>
+#include <Standard_Assert.hxx>
//! Performs fast BVH construction using LBVH building approach.
//! Algorithm uses spatial Morton codes to reduce the BVH construction
virtual ~BVH_LinearBuilder();
//! Builds BVH.
- void Build (BVH_Set<T, N>* theSet,
- BVH_Tree<T, N>* theBVH,
- const BVH_Box<T, N>& theBox);
+ virtual void Build (BVH_Set<T, N>* theSet,
+ BVH_Tree<T, N>* theBVH,
+ const BVH_Box<T, N>& theBox) const Standard_OVERRIDE;
protected:
- typedef NCollection_Array1<BVH_EncodedLink>::iterator LinkIterator;
+ typedef NCollection_Array1<BVH_EncodedLink>::iterator LinkIterator;
protected:
//! Emits hierarchy from sorted Morton codes.
- Standard_Integer EmitHierachy (BVH_Tree<T, N>* theBVH,
+ Standard_Integer emitHierachy (BVH_Tree<T, N>* theBVH,
+ const NCollection_Array1<BVH_EncodedLink>& theEncodedLinks,
const Standard_Integer theBit,
const Standard_Integer theShift,
const Standard_Integer theStart,
- const Standard_Integer theFinal);
+ const Standard_Integer theFinal) const;
//! Returns index of the first element which does not compare less than the given one.
- Standard_Integer LowerBound (Standard_Integer theStart,
+ Standard_Integer lowerBound (const NCollection_Array1<BVH_EncodedLink>& theEncodedLinks,
+ Standard_Integer theStart,
Standard_Integer theFinal,
- Standard_Integer theDigit);
+ Standard_Integer theDigit) const;
-protected:
+};
- //! Tool object to perform radix sort of BVH primitives.
- NCollection_Handle<BVH_RadixSorter<T, N> > myRadixSorter;
+// =======================================================================
+// function : BVH_LinearBuilder
+// purpose :
+// =======================================================================
+template<class T, int N>
+BVH_LinearBuilder<T, N>::BVH_LinearBuilder (const Standard_Integer theLeafNodeSize,
+ const Standard_Integer theMaxTreeDepth)
+: BVH_Builder<T, N> (theLeafNodeSize,
+ theMaxTreeDepth)
+{
+ //
+}
-};
+// =======================================================================
+// function : ~BVH_LinearBuilder
+// purpose :
+// =======================================================================
+template<class T, int N>
+BVH_LinearBuilder<T, N>::~BVH_LinearBuilder()
+{
+ //
+}
+
+// =======================================================================
+// function : lowerBound
+// purpose : Returns index of first element greater than the given one
+// =======================================================================
+template<class T, int N>
+Standard_Integer BVH_LinearBuilder<T, N>::lowerBound (const NCollection_Array1<BVH_EncodedLink>& theEncodedLinks,
+ Standard_Integer theStart,
+ Standard_Integer theFinal,
+ Standard_Integer theDigit) const
+{
+ Standard_Integer aNbPrims = theFinal - theStart;
+ while (aNbPrims > 0)
+ {
+ const Standard_Integer aStep = aNbPrims / 2;
+ if (theEncodedLinks.Value (theStart + aStep).first & (1 << theDigit))
+ {
+ aNbPrims = aStep;
+ }
+ else
+ {
+ theStart += aStep + 1;
+ aNbPrims -= aStep + 1;
+ }
+ }
+
+ return theStart;
+}
+
+// =======================================================================
+// function : emitHierachy
+// purpose : Emits hierarchy from sorted Morton codes
+// =======================================================================
+template<class T, int N>
+Standard_Integer BVH_LinearBuilder<T, N>::emitHierachy (BVH_Tree<T, N>* theBVH,
+ const NCollection_Array1<BVH_EncodedLink>& theEncodedLinks,
+ const Standard_Integer theBit,
+ const Standard_Integer theShift,
+ const Standard_Integer theStart,
+ const Standard_Integer theFinal) const
+{
+ if (theFinal - theStart > BVH_Builder<T, N>::myLeafNodeSize)
+ {
+ const Standard_Integer aPosition = theBit < 0 ?
+ (theStart + theFinal) / 2 : lowerBound (theEncodedLinks, theStart, theFinal, theBit);
+ if (aPosition == theStart || aPosition == theFinal)
+ {
+ return emitHierachy (theBVH, theEncodedLinks, theBit - 1, theShift, theStart, theFinal);
+ }
+
+ // Build inner node
+ const Standard_Integer aNode = theBVH->AddInnerNode (0, 0);
+ const Standard_Integer aRghNode = theShift + aPosition - theStart;
+
+ const Standard_Integer aLftChild = emitHierachy (theBVH, theEncodedLinks, theBit - 1, theShift, theStart, aPosition);
+ const Standard_Integer aRghChild = emitHierachy (theBVH, theEncodedLinks, theBit - 1, aRghNode, aPosition, theFinal);
+
+ theBVH->NodeInfoBuffer()[aNode].y() = aLftChild;
+ theBVH->NodeInfoBuffer()[aNode].z() = aRghChild;
+ return aNode;
+ }
+ else
+ {
+ // Build leaf node
+ return theBVH->AddLeafNode (theShift, theShift + theFinal - theStart - 1);
+ }
+}
+
+namespace BVH
+{
+ //! Calculates bounding boxes (AABBs) for the given BVH tree.
+ template<class T, int N>
+ Standard_Integer UpdateBounds (BVH_Set<T, N>* theSet, BVH_Tree<T, N>* theTree, const Standard_Integer theNode = 0)
+ {
+ const BVH_Vec4i aData = theTree->NodeInfoBuffer()[theNode];
+ if (aData.x() == 0)
+ {
+ const Standard_Integer aLftChild = theTree->NodeInfoBuffer()[theNode].y();
+ const Standard_Integer aRghChild = theTree->NodeInfoBuffer()[theNode].z();
+
+ const Standard_Integer aLftDepth = UpdateBounds (theSet, theTree, aLftChild);
+ const Standard_Integer aRghDepth = UpdateBounds (theSet, theTree, aRghChild);
+
+ typename BVH_Box<T, N>::BVH_VecNt aLftMinPoint = theTree->MinPointBuffer()[aLftChild];
+ typename BVH_Box<T, N>::BVH_VecNt aLftMaxPoint = theTree->MaxPointBuffer()[aLftChild];
+ typename BVH_Box<T, N>::BVH_VecNt aRghMinPoint = theTree->MinPointBuffer()[aRghChild];
+ typename BVH_Box<T, N>::BVH_VecNt aRghMaxPoint = theTree->MaxPointBuffer()[aRghChild];
+
+ BVH::BoxMinMax<T, N>::CwiseMin (aLftMinPoint, aRghMinPoint);
+ BVH::BoxMinMax<T, N>::CwiseMax (aLftMaxPoint, aRghMaxPoint);
+
+ theTree->MinPointBuffer()[theNode] = aLftMinPoint;
+ theTree->MaxPointBuffer()[theNode] = aLftMaxPoint;
+ return Max (aLftDepth, aRghDepth) + 1;
+ }
+ else
+ {
+ typename BVH_Box<T, N>::BVH_VecNt& aMinPoint = theTree->MinPointBuffer()[theNode];
+ typename BVH_Box<T, N>::BVH_VecNt& aMaxPoint = theTree->MaxPointBuffer()[theNode];
+ for (Standard_Integer aPrimIdx = aData.y(); aPrimIdx <= aData.z(); ++aPrimIdx)
+ {
+ const BVH_Box<T, N> aBox = theSet->Box (aPrimIdx);
+ if (aPrimIdx == aData.y())
+ {
+ aMinPoint = aBox.CornerMin();
+ aMaxPoint = aBox.CornerMax();
+ }
+ else
+ {
+ BVH::BoxMinMax<T, N>::CwiseMin (aMinPoint, aBox.CornerMin());
+ BVH::BoxMinMax<T, N>::CwiseMax (aMaxPoint, aBox.CornerMax());
+ }
+ }
+ }
+ return 0;
+ }
+
+#ifdef HAVE_TBB
+
+ //! TBB task for parallel bounds updating.
+ template<class T, int N>
+ class UpdateBoundTask: public tbb::task
+ {
+
+ BVH_Set<T, N>* mySet; //!< Set of geometric objects
+ BVH_Tree<T, N>* myBVH; //!< BVH tree built over the set
+ Standard_Integer myNode; //!< BVH node to update bounding box
+ Standard_Integer myLevel; //!< Level of the processed BVH node
+ Standard_Integer* myHeight; //!< Height of the processed BVH node
+
+ public:
+
+ //! Creates new TBB parallel bound update task.
+ UpdateBoundTask (BVH_Set<T, N>* theSet,
+ BVH_Tree<T, N>* theBVH,
+ Standard_Integer theNode,
+ Standard_Integer theLevel,
+ Standard_Integer* theHeight)
+ : mySet (theSet), myBVH (theBVH), myNode (theNode), myLevel (theLevel), myHeight (theHeight) {}
+
+ //! Executes the task.
+ tbb::task* execute()
+ {
+ if (myBVH->IsOuter (myNode) || myLevel > 2)
+ {
+ *myHeight = BVH::UpdateBounds (mySet, myBVH, myNode);
+ }
+ else
+ {
+ Standard_Integer aLftHeight = 0;
+ Standard_Integer aRghHeight = 0;
+
+ const Standard_Integer aLftChild = myBVH->NodeInfoBuffer()[myNode].y();
+ const Standard_Integer aRghChild = myBVH->NodeInfoBuffer()[myNode].z();
+
+ Standard_Integer aCount = 1;
+ tbb::task_list aList;
+ if (!myBVH->IsOuter (aLftChild))
+ {
+ ++aCount;
+ aList.push_back (*new ( allocate_child() )
+ UpdateBoundTask (mySet, myBVH, aLftChild, myLevel + 1, &aLftHeight));
+ }
+ else
+ {
+ aLftHeight = BVH::UpdateBounds (mySet, myBVH, aLftChild);
+ }
+
+ if (!myBVH->IsOuter (aRghChild))
+ {
+ ++aCount;
+ aList.push_back (*new( allocate_child() )
+ UpdateBoundTask (mySet, myBVH, aRghChild, myLevel + 1, &aRghHeight));
+ }
+ else
+ {
+ aRghHeight = BVH::UpdateBounds (mySet, myBVH, aRghChild);
+ }
+
+ if (aCount > 1)
+ {
+ set_ref_count (aCount);
+ spawn_and_wait_for_all (aList);
+ }
+
+ typename BVH_Box<T, N>::BVH_VecNt aLftMinPoint = myBVH->MinPointBuffer()[aLftChild];
+ typename BVH_Box<T, N>::BVH_VecNt aLftMaxPoint = myBVH->MaxPointBuffer()[aLftChild];
+ typename BVH_Box<T, N>::BVH_VecNt aRghMinPoint = myBVH->MinPointBuffer()[aRghChild];
+ typename BVH_Box<T, N>::BVH_VecNt aRghMaxPoint = myBVH->MaxPointBuffer()[aRghChild];
+
+ BVH::BoxMinMax<T, N>::CwiseMin (aLftMinPoint, aRghMinPoint);
+ BVH::BoxMinMax<T, N>::CwiseMax (aLftMaxPoint, aRghMaxPoint);
+
+ myBVH->MinPointBuffer()[myNode] = aLftMinPoint;
+ myBVH->MaxPointBuffer()[myNode] = aLftMaxPoint;
+
+ *myHeight = Max (aLftHeight, aRghHeight) + 1;
+ }
+ return NULL;
+ }
+ };
+
+#endif
+}
+
+// =======================================================================
+// function : Build
+// purpose :
+// =======================================================================
+template<class T, int N>
+void BVH_LinearBuilder<T, N>::Build (BVH_Set<T, N>* theSet,
+ BVH_Tree<T, N>* theBVH,
+ const BVH_Box<T, N>& theBox) const
+{
+ Standard_STATIC_ASSERT (N == 3 || N == 4);
+ const Standard_Integer aSetSize = theSet->Size();
+ if (theBVH == NULL || aSetSize == 0)
+ {
+ return;
+ }
+
+ theBVH->Clear();
+
+ // Step 0 -- Initialize parameter of virtual grid
+ BVH_RadixSorter<T, N> aRadixSorter (theBox);
+
+ // Step 1 - Perform radix sorting of primitive set
+ aRadixSorter.Perform (theSet);
+
+ // Step 2 -- Emitting BVH hierarchy from sorted Morton codes
+ emitHierachy (theBVH, aRadixSorter.EncodedLinks(), 29, 0, 0, theSet->Size());
+
+ // Step 3 -- Compute bounding boxes of BVH nodes
+ theBVH->MinPointBuffer().resize (theBVH->NodeInfoBuffer().size());
+ theBVH->MaxPointBuffer().resize (theBVH->NodeInfoBuffer().size());
+
+ Standard_Integer aHeight = 0;
+
+#ifdef HAVE_TBB
+
+ // Note: Although TBB tasks are allocated using placement
+ // new, we do not need to delete them explicitly
+ BVH::UpdateBoundTask<T, N>& aRootTask = *new ( tbb::task::allocate_root() )
+ BVH::UpdateBoundTask<T, N> (theSet, theBVH, 0, 0, &aHeight);
+
+ tbb::task::spawn_root_and_wait (aRootTask);
+
+#else
+
+ aHeight = BVH::UpdateBounds (theSet, theBVH, 0);
+
+#endif
-#include <BVH_LinearBuilder.lxx>
+ BVH_Builder<T, N>::updateDepth (theBVH, aHeight);
+}
#endif // _BVH_LinearBuilder_Header
+++ /dev/null
-// Created on: 2014-09-11
-// Created by: Danila ULYANOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <Standard_Assert.hxx>
-
-// =======================================================================
-// function : BVH_LinearBuilder
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_LinearBuilder<T, N>::BVH_LinearBuilder (const Standard_Integer theLeafNodeSize,
- const Standard_Integer theMaxTreeDepth)
-: BVH_Builder<T, N> (theLeafNodeSize,
- theMaxTreeDepth)
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_LinearBuilder
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_LinearBuilder<T, N>::~BVH_LinearBuilder()
-{
- //
-}
-
-// =======================================================================
-// function : LowerBound
-// purpose : Returns index of first element greater than the given one
-// =======================================================================
-template<class T, int N>
-Standard_Integer BVH_LinearBuilder<T, N>::LowerBound (Standard_Integer theStart,
- Standard_Integer theFinal,
- Standard_Integer theDigit)
-{
- Standard_Integer aNbPrims = theFinal - theStart;
-
- while (aNbPrims > 0)
- {
- const Standard_Integer aStep = aNbPrims / 2;
-
- if (myRadixSorter->EncodedLinks().Value (theStart + aStep).first & (1 << theDigit))
- {
- aNbPrims = aStep;
- }
- else
- {
- theStart += aStep + 1;
- aNbPrims -= aStep + 1;
- }
- }
-
- return theStart;
-}
-
-// =======================================================================
-// function : EmitHierachy
-// purpose : Emits hierarchy from sorted Morton codes
-// =======================================================================
-template<class T, int N>
-Standard_Integer BVH_LinearBuilder<T, N>::EmitHierachy (BVH_Tree<T, N>* theBVH,
- const Standard_Integer theBit,
- const Standard_Integer theShift,
- const Standard_Integer theStart,
- const Standard_Integer theFinal)
-{
- if (theFinal - theStart > BVH_Builder<T, N>::myLeafNodeSize)
- {
- const Standard_Integer aPosition = theBit < 0 ?
- (theStart + theFinal) / 2 : LowerBound (theStart, theFinal, theBit);
-
- if (aPosition == theStart || aPosition == theFinal)
- {
- return EmitHierachy (theBVH, theBit - 1, theShift, theStart, theFinal);
- }
-
- // Build inner node
- const Standard_Integer aNode = theBVH->AddInnerNode (0, 0);
-
- const Standard_Integer aRghNode = theShift + aPosition - theStart;
-
- const Standard_Integer aLftChild = EmitHierachy (theBVH, theBit - 1, theShift, theStart, aPosition);
- const Standard_Integer aRghChild = EmitHierachy (theBVH, theBit - 1, aRghNode, aPosition, theFinal);
-
- theBVH->NodeInfoBuffer()[aNode].y() = aLftChild;
- theBVH->NodeInfoBuffer()[aNode].z() = aRghChild;
-
- return aNode;
- }
- else
- {
- // Build leaf node
- return theBVH->AddLeafNode (theShift, theShift + theFinal - theStart - 1);
- }
-}
-
-namespace BVH
-{
- //! Calculates bounding boxes (AABBs) for the given BVH tree.
- template<class T, int N>
- Standard_Integer UpdateBounds (BVH_Set<T, N>* theSet, BVH_Tree<T, N>* theTree, const Standard_Integer theNode = 0)
- {
- const BVH_Vec4i aData = theTree->NodeInfoBuffer()[theNode];
-
- if (aData.x() == 0)
- {
- const Standard_Integer aLftChild = theTree->NodeInfoBuffer()[theNode].y();
- const Standard_Integer aRghChild = theTree->NodeInfoBuffer()[theNode].z();
-
- const Standard_Integer aLftDepth = UpdateBounds (theSet, theTree, aLftChild);
- const Standard_Integer aRghDepth = UpdateBounds (theSet, theTree, aRghChild);
-
- typename BVH_Box<T, N>::BVH_VecNt aLftMinPoint = theTree->MinPointBuffer()[aLftChild];
- typename BVH_Box<T, N>::BVH_VecNt aLftMaxPoint = theTree->MaxPointBuffer()[aLftChild];
- typename BVH_Box<T, N>::BVH_VecNt aRghMinPoint = theTree->MinPointBuffer()[aRghChild];
- typename BVH_Box<T, N>::BVH_VecNt aRghMaxPoint = theTree->MaxPointBuffer()[aRghChild];
-
- BVH::BoxMinMax<T, N>::CwiseMin (aLftMinPoint, aRghMinPoint);
- BVH::BoxMinMax<T, N>::CwiseMax (aLftMaxPoint, aRghMaxPoint);
-
- theTree->MinPointBuffer()[theNode] = aLftMinPoint;
- theTree->MaxPointBuffer()[theNode] = aLftMaxPoint;
-
- return Max (aLftDepth, aRghDepth) + 1;
- }
- else
- {
- typename BVH_Box<T, N>::BVH_VecNt& aMinPoint = theTree->MinPointBuffer()[theNode];
- typename BVH_Box<T, N>::BVH_VecNt& aMaxPoint = theTree->MaxPointBuffer()[theNode];
-
- for (Standard_Integer aPrimIdx = aData.y(); aPrimIdx <= aData.z(); ++aPrimIdx)
- {
- const BVH_Box<T, N> aBox = theSet->Box (aPrimIdx);
-
- if (aPrimIdx == aData.y())
- {
- aMinPoint = aBox.CornerMin();
- aMaxPoint = aBox.CornerMax();
- }
- else
- {
- BVH::BoxMinMax<T, N>::CwiseMin (aMinPoint, aBox.CornerMin());
- BVH::BoxMinMax<T, N>::CwiseMax (aMaxPoint, aBox.CornerMax());
- }
- }
- }
-
- return 0;
- }
-
-#ifdef HAVE_TBB
-
- //! TBB task for parallel bounds updating.
- template<class T, int N>
- class UpdateBoundTask: public tbb::task
- {
- //! Set of geometric objects.
- BVH_Set<T, N>* mySet;
-
- //! BVH tree built over the set.
- BVH_Tree<T, N>* myBVH;
-
- //! BVH node to update bounding box.
- Standard_Integer myNode;
-
- //! Level of the processed BVH node.
- Standard_Integer myLevel;
-
- //! Height of the processed BVH node.
- Standard_Integer* myHeight;
-
- public:
-
- //! Creates new TBB parallel bound update task.
- UpdateBoundTask (BVH_Set<T, N>* theSet,
- BVH_Tree<T, N>* theBVH,
- Standard_Integer theNode,
- Standard_Integer theLevel,
- Standard_Integer* theHeight)
- : mySet (theSet),
- myBVH (theBVH),
- myNode (theNode),
- myLevel (theLevel),
- myHeight (theHeight)
- {
- //
- }
-
- //! Executes the task.
- tbb::task* execute()
- {
- if (myBVH->IsOuter (myNode) || myLevel > 2)
- {
- *myHeight = BVH::UpdateBounds (mySet, myBVH, myNode);
- }
- else
- {
- Standard_Integer aLftHeight = 0;
- Standard_Integer aRghHeight = 0;
-
- tbb::task_list aList;
-
- const Standard_Integer aLftChild = myBVH->NodeInfoBuffer()[myNode].y();
- const Standard_Integer aRghChild = myBVH->NodeInfoBuffer()[myNode].z();
-
- Standard_Integer aCount = 1;
-
- if (!myBVH->IsOuter (aLftChild))
- {
- ++aCount;
- aList.push_back (*new ( allocate_child() )
- UpdateBoundTask (mySet, myBVH, aLftChild, myLevel + 1, &aLftHeight));
- }
- else
- {
- aLftHeight = BVH::UpdateBounds (mySet, myBVH, aLftChild);
- }
-
- if (!myBVH->IsOuter (aRghChild))
- {
- ++aCount;
- aList.push_back (*new( allocate_child() )
- UpdateBoundTask (mySet, myBVH, aRghChild, myLevel + 1, &aRghHeight));
- }
- else
- {
- aRghHeight = BVH::UpdateBounds (mySet, myBVH, aRghChild);
- }
-
- if (aCount > 1)
- {
- set_ref_count (aCount);
- spawn_and_wait_for_all (aList);
- }
-
- typename BVH_Box<T, N>::BVH_VecNt aLftMinPoint = myBVH->MinPointBuffer()[aLftChild];
- typename BVH_Box<T, N>::BVH_VecNt aLftMaxPoint = myBVH->MaxPointBuffer()[aLftChild];
- typename BVH_Box<T, N>::BVH_VecNt aRghMinPoint = myBVH->MinPointBuffer()[aRghChild];
- typename BVH_Box<T, N>::BVH_VecNt aRghMaxPoint = myBVH->MaxPointBuffer()[aRghChild];
-
- BVH::BoxMinMax<T, N>::CwiseMin (aLftMinPoint, aRghMinPoint);
- BVH::BoxMinMax<T, N>::CwiseMax (aLftMaxPoint, aRghMaxPoint);
-
- myBVH->MinPointBuffer()[myNode] = aLftMinPoint;
- myBVH->MaxPointBuffer()[myNode] = aLftMaxPoint;
-
- *myHeight = Max (aLftHeight, aRghHeight) + 1;
- }
-
- return NULL;
- }
- };
-
-#endif
-}
-
-// =======================================================================
-// function : Build
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_LinearBuilder<T, N>::Build (BVH_Set<T, N>* theSet,
- BVH_Tree<T, N>* theBVH,
- const BVH_Box<T, N>& theBox)
-{
- Standard_STATIC_ASSERT (N == 3 || N == 4);
- const Standard_Integer aSetSize = theSet->Size();
- if (theBVH == NULL || aSetSize == 0)
- {
- return;
- }
-
- theBVH->Clear();
-
- // Step 0 -- Initialize parameter of virtual grid
- myRadixSorter = new BVH_RadixSorter<T, N> (theBox);
-
- // Step 1 - Perform radix sorting of primitive set
- myRadixSorter->Perform (theSet);
-
- // Step 2 -- Emitting BVH hierarchy from sorted Morton codes
- EmitHierachy (theBVH, 29, 0, 0, theSet->Size());
-
- // Step 3 -- Compute bounding boxes of BVH nodes
- theBVH->MinPointBuffer().resize (theBVH->NodeInfoBuffer().size());
- theBVH->MaxPointBuffer().resize (theBVH->NodeInfoBuffer().size());
-
- Standard_Integer aHeight = 0;
-
-#ifdef HAVE_TBB
-
- // Note: Although TBB tasks are allocated using placement
- // new, we do not need to delete them explicitly
- BVH::UpdateBoundTask<T, N>& aRootTask = *new ( tbb::task::allocate_root() )
- BVH::UpdateBoundTask<T, N> (theSet, theBVH, 0, 0, &aHeight);
-
- tbb::task::spawn_root_and_wait (aRootTask);
-
-#else
-
- aHeight = BVH::UpdateBounds (theSet, theBVH, 0);
-
-#endif
-
- BVH_Builder<T, N>::UpdateDepth (theBVH, aHeight);
-}
public:
//! Creates new abstract geometric object.
- BVH_Object();
+ BVH_Object() : myIsDirty (Standard_False) {}
//! Releases resources of geometric object.
virtual ~BVH_Object() = 0;
virtual BVH_Box<T, N> Box() const = 0;
//! Returns properties of the geometric object.
- virtual const NCollection_Handle<BVH_Properties>& Properties() const;
+ virtual const NCollection_Handle<BVH_Properties>& Properties() const { return myProperties; }
//! Sets properties of the geometric object.
- virtual void SetProperties (const NCollection_Handle<BVH_Properties>& theProperties);
+ virtual void SetProperties (const NCollection_Handle<BVH_Properties>& theProperties) { myProperties = theProperties; }
//! Marks object state as outdated (needs BVH rebuilding).
- virtual void MarkDirty();
+ virtual void MarkDirty() { myIsDirty = Standard_True; }
protected:
};
-#include <BVH_Object.lxx>
+// =======================================================================
+// function : ~BVH_Object
+// purpose :
+// =======================================================================
+template<class T, int N>
+BVH_Object<T, N>::~BVH_Object()
+{
+ //
+}
#endif // _BVH_Object_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// =======================================================================
-// function : BVH_Object
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Object<T, N>::BVH_Object()
-: myIsDirty (Standard_False)
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_Object
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Object<T, N>::~BVH_Object()
-{
- //
-}
-
-// =======================================================================
-// function : Properties
-// purpose :
-// =======================================================================
-template<class T, int N>
-const NCollection_Handle<BVH_Properties>& BVH_Object<T, N>::Properties() const
-{
- return myProperties;
-}
-
-// =======================================================================
-// function : SetProperties
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Object<T, N>::SetProperties (const NCollection_Handle<BVH_Properties>& theProperties)
-{
- myProperties = theProperties;
-}
-
-// =======================================================================
-// function : MarkDirty
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Object<T, N>::MarkDirty()
-{
- myIsDirty = Standard_True;
-}
public:
//! Creates new set of geometric objects.
- BVH_ObjectSet();
+ BVH_ObjectSet() {}
//! Releases resources of set of geometric objects.
- virtual ~BVH_ObjectSet();
+ virtual ~BVH_ObjectSet() {}
public:
//! Removes all geometric objects.
- virtual void Clear();
+ virtual void Clear()
+ {
+ for (typename BVH_ObjectList::Iterator anObjectIter (myObjects); anObjectIter.More(); anObjectIter.Next())
+ {
+ anObjectIter.ChangeValue().Nullify();
+ }
+ myObjects.Clear();
+ }
//! Returns reference to the array of geometric objects.
- BVH_ObjectList& Objects();
+ BVH_ObjectList& Objects() { return myObjects; }
//! Returns reference to the array of geometric objects.
- const BVH_ObjectList& Objects() const;
+ const BVH_ObjectList& Objects() const { return myObjects; }
public:
//! Return total number of objects.
- virtual Standard_Integer Size() const;
+ virtual Standard_Integer Size() const Standard_OVERRIDE { return myObjects.Size(); }
//! Returns AABB of entire set of objects.
using BVH_Set<T, N>::Box;
//! Returns AABB of the given object.
- virtual BVH_Box<T, N> Box (const Standard_Integer theIndex) const;
+ virtual BVH_Box<T, N> Box (const Standard_Integer theIndex) const Standard_OVERRIDE { return myObjects.Value (theIndex)->Box(); }
//! Returns centroid position along the given axis.
- virtual T Center (const Standard_Integer theIndex, const Standard_Integer theAxis) const;
+ virtual T Center (const Standard_Integer theIndex, const Standard_Integer theAxis) const Standard_OVERRIDE
+ {
+ // Note: general implementation, not optimal
+ return BVH::CenterAxis<T, N>::Center (myObjects.Value (theIndex)->Box(), theAxis);
+ }
//! Performs transposing the two given objects in the set.
- virtual void Swap (const Standard_Integer theIndex1, const Standard_Integer theIndex2);
+ virtual void Swap (const Standard_Integer theIndex1, const Standard_Integer theIndex2) Standard_OVERRIDE
+ {
+ std::swap (myObjects.ChangeValue (theIndex1),
+ myObjects.ChangeValue (theIndex2));
+ }
protected:
};
-#include <BVH_ObjectSet.lxx>
-
#endif // _BVH_ObjectSet_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// =======================================================================
-// function : BVH_ObjectSet
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_ObjectSet<T, N>::BVH_ObjectSet()
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_ObjectSet
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_ObjectSet<T, N>::~BVH_ObjectSet()
-{
- //
-}
-
-// =======================================================================
-// function : Clears all geometric objects
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_ObjectSet<T, N>::Clear()
-{
- for (Standard_Integer anObjectIdx = 0; anObjectIdx < myObjects.Size(); ++anObjectIdx)
- {
- myObjects.ChangeValue (anObjectIdx).Nullify();
- }
- myObjects.Clear();
-}
-
-// =======================================================================
-// function : Objects
-// purpose :
-// =======================================================================
-template<class T, int N>
-typename BVH_ObjectSet<T, N>::BVH_ObjectList& BVH_ObjectSet<T, N>::Objects()
-{
- return myObjects;
-}
-
-// =======================================================================
-// function : Objects
-// purpose :
-// =======================================================================
-template<class T, int N>
-const typename BVH_ObjectSet<T, N>::BVH_ObjectList& BVH_ObjectSet<T, N>::Objects() const
-{
- return myObjects;
-}
-
-// =======================================================================
-// function : Size
-// purpose :
-// =======================================================================
-template<class T, int N>
-Standard_Integer BVH_ObjectSet<T, N>::Size() const
-{
- return myObjects.Size();
-}
-
-// =======================================================================
-// function : Box
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Box<T, N> BVH_ObjectSet<T, N>::Box (const Standard_Integer theIndex) const
-{
- return myObjects.Value (theIndex)->Box();
-}
-
-// =======================================================================
-// function : Center
-// purpose :
-// =======================================================================
-template<class T, int N>
-T BVH_ObjectSet<T, N>::Center (const Standard_Integer theIndex,
- const Standard_Integer theAxis) const
-{
- // Note: general implementation, not optimal
- return BVH::CenterAxis<T, N>::Center (myObjects.Value (theIndex)->Box(), theAxis);
-}
-
-// =======================================================================
-// function : Swap
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_ObjectSet<T, N>::Swap (const Standard_Integer theIndex1,
- const Standard_Integer theIndex2)
-{
- std::swap (myObjects.ChangeValue (theIndex1),
- myObjects.ChangeValue (theIndex2));
-}
#include <BVH_Object.hxx>
#include <BVH_Builder.hxx>
+#include <BVH_BinnedBuilder.hxx>
//! Set of abstract geometric primitives organized with bounding
//! volume hierarchy (BVH). Unlike an object set, this collection
static const Standard_Integer MaxTreeDepth = 32;
//! Creates set of abstract primitives.
- BVH_PrimitiveSet();
+ BVH_PrimitiveSet()
+ : myBVH (new BVH_Tree<T, N>())
+ {
+ // Set default builder - binned SAH split
+ myBuilder = new BVH_BinnedBuilder<T, N, 48> (5, MaxTreeDepth);
+ }
//! Releases resources of set of abstract primitives.
- virtual ~BVH_PrimitiveSet();
+ virtual ~BVH_PrimitiveSet()
+ {
+ myBVH.Nullify();
+ myBuilder.Nullify();
+ }
public:
//! Returns AABB of primitive set.
- virtual BVH_Box<T, N> Box() const;
+ virtual BVH_Box<T, N> Box() const Standard_OVERRIDE
+ {
+ if (BVH_Object<T, N>::myIsDirty)
+ {
+ myBox = BVH_Set<T, N>::Box();
+ }
+ return myBox;
+ }
//! Returns BVH tree (and builds it if necessary).
- virtual const NCollection_Handle<BVH_Tree<T, N> >& BVH();
+ virtual const NCollection_Handle<BVH_Tree<T, N> >& BVH()
+ {
+ if (BVH_Object<T, N>::myIsDirty)
+ {
+ Update();
+ }
+ return myBVH;
+ }
//! Returns the method (builder) used to construct BVH.
- virtual const NCollection_Handle<BVH_Builder<T, N> >& Builder() const;
+ virtual const NCollection_Handle<BVH_Builder<T, N> >& Builder() const { return myBuilder; }
//! Sets the method (builder) used to construct BVH.
- virtual void SetBuilder (NCollection_Handle<BVH_Builder<T, N> >& theBuilder);
+ virtual void SetBuilder (const NCollection_Handle<BVH_Builder<T, N> >& theBuilder) { myBuilder = theBuilder; }
protected:
//! Updates BVH of primitive set.
- virtual void Update();
+ virtual void Update()
+ {
+ if (BVH_Object<T, N>::myIsDirty)
+ {
+ myBuilder->Build (this, myBVH.operator->(), Box());
+ BVH_Object<T, N>::myIsDirty = Standard_False;
+ }
+ }
protected:
};
-#include <BVH_PrimitiveSet.lxx>
-
#endif // _BVH_PrimitiveSet_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <BVH_BinnedBuilder.hxx>
-
-// =======================================================================
-// function : BVH_PrimitiveSet
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_PrimitiveSet<T, N>::BVH_PrimitiveSet()
-: myBVH (new BVH_Tree<T, N>())
-{
- // Set default builder - binned SAH split
- myBuilder = new BVH_BinnedBuilder<T, N, 48> (5, MaxTreeDepth);
-}
-
-// =======================================================================
-// function : ~BVH_PrimitiveSet
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_PrimitiveSet<T, N>::~BVH_PrimitiveSet()
-{
- myBVH.Nullify();
- myBuilder.Nullify();
-}
-
-// =======================================================================
-// function : BVH
-// purpose :
-// =======================================================================
-template<class T, int N>
-const NCollection_Handle<BVH_Tree<T, N> >& BVH_PrimitiveSet<T, N>::BVH()
-{
- if (BVH_Object<T, N>::myIsDirty)
- {
- Update();
- }
-
- return myBVH;
-}
-
-// =======================================================================
-// function : Box
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Box<T, N> BVH_PrimitiveSet<T, N>::Box() const
-{
- if (!BVH_Object<T, N>::myIsDirty)
- {
- return myBox;
- }
-
- myBox = BVH_Set<T, N>::Box();
- return myBox;
-}
-
-// =======================================================================
-// function : Update
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_PrimitiveSet<T, N>::Update()
-{
- if (!BVH_Object<T, N>::myIsDirty)
- {
- return;
- }
-
- myBuilder->Build (this, myBVH.operator->(), Box());
- BVH_Object<T, N>::myIsDirty = Standard_False;
-}
-
-// =======================================================================
-// function : Builder
-// purpose :
-// =======================================================================
-template<class T, int N>
-const NCollection_Handle<BVH_Builder<T, N> >& BVH_PrimitiveSet<T, N>::Builder() const
-{
- return myBuilder;
-}
-
-// =======================================================================
-// function : SetBuilder
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_PrimitiveSet<T, N>::SetBuilder (NCollection_Handle<BVH_Builder<T, N> >& theBuilder)
-{
- myBuilder = theBuilder;
-}
public:
//! Creates new identity transformation.
- BVH_Transform();
+ BVH_Transform() {}
//! Creates new transformation with specified matrix.
- BVH_Transform (const BVH_MatNt& theTransform);
+ BVH_Transform (const BVH_MatNt& theTransform) : myTransform (theTransform) {}
//! Releases resources of transformation properties.
- virtual ~BVH_Transform();
+ virtual ~BVH_Transform() {}
//! Returns transformation matrix.
- const BVH_MatNt& Transform() const;
+ const BVH_MatNt& Transform() const { return myTransform; }
//! Sets new transformation matrix.
void SetTransform (const BVH_MatNt& theTransform);
//! Returns inversed transformation matrix.
- const BVH_MatNt& Inversed() const;
+ const BVH_MatNt& Inversed() const { return myTransformInversed; }
//! Applies transformation matrix to bounding box.
BVH_Box<T, N> Apply (const BVH_Box<T, N>& theBox) const;
};
-#include <BVH_Properties.lxx>
+namespace BVH
+{
+ template<class T, int N> struct MatrixOp
+ {
+ // Not implemented
+ };
+
+ template<class T> struct MatrixOp<T, 4>
+ {
+ typedef typename BVH::MatrixType<T, 4>::Type BVH_Mat4t;
+
+ static void Inverse (const BVH_Mat4t& theIn,
+ BVH_Mat4t& theOut)
+ {
+ theIn.Inverted (theOut);
+ }
+
+ typedef typename BVH::VectorType<T, 4>::Type BVH_Vec4t;
+
+ static BVH_Vec4t Multiply (const BVH_Mat4t& theMat,
+ const BVH_Vec4t& theVec)
+ {
+ BVH_Vec4t aOut = theMat * theVec;
+ return aOut * static_cast<T> (1.0 / aOut.w());
+ }
+ };
+
+ template<class T, int N>
+ struct UnitVector
+ {
+ // Not implemented
+ };
+
+ template<class T>
+ struct UnitVector<T, 2>
+ {
+ typedef typename BVH::VectorType<T, 2>::Type BVH_Vec2t;
+ static BVH_Vec2t DX() { return BVH_Vec2t (static_cast<T> (1.0), static_cast<T> (0.0)); }
+ static BVH_Vec2t DY() { return BVH_Vec2t (static_cast<T> (0.0), static_cast<T> (1.0)); }
+ static BVH_Vec2t DZ() { return BVH_Vec2t (static_cast<T> (0.0), static_cast<T> (0.0)); }
+ };
+
+ template<class T>
+ struct UnitVector<T, 3>
+ {
+ typedef typename BVH::VectorType<T, 3>::Type BVH_Vec3t;
+ static BVH_Vec3t DX() { return BVH_Vec3t (static_cast<T> (1.0), static_cast<T> (0.0), static_cast<T> (0.0)); }
+ static BVH_Vec3t DY() { return BVH_Vec3t (static_cast<T> (0.0), static_cast<T> (1.0), static_cast<T> (0.0)); }
+ static BVH_Vec3t DZ() { return BVH_Vec3t (static_cast<T> (0.0), static_cast<T> (0.0), static_cast<T> (1.0)); }
+ };
+
+ template<class T>
+ struct UnitVector<T, 4>
+ {
+ typedef typename BVH::VectorType<T, 4>::Type BVH_Vec4t;
+ static BVH_Vec4t DX() { return BVH_Vec4t (static_cast<T> (1.0), static_cast<T> (0.0), static_cast<T> (0.0), static_cast<T> (0.0)); }
+ static BVH_Vec4t DY() { return BVH_Vec4t (static_cast<T> (0.0), static_cast<T> (1.0), static_cast<T> (0.0), static_cast<T> (0.0)); }
+ static BVH_Vec4t DZ() { return BVH_Vec4t (static_cast<T> (0.0), static_cast<T> (0.0), static_cast<T> (1.0), static_cast<T> (0.0)); }
+ };
+}
+
+// =======================================================================
+// function : SetTransform
+// purpose :
+// =======================================================================
+template<class T, int N>
+void BVH_Transform<T, N>::SetTransform (const BVH_MatNt& theTransform)
+{
+ myTransform = theTransform;
+ BVH::MatrixOp<T, N>::Inverse (myTransform, myTransformInversed);
+}
+
+// =======================================================================
+// function : Apply
+// purpose :
+// =======================================================================
+template<class T, int N>
+BVH_Box<T, N> BVH_Transform<T, N>::Apply (const BVH_Box<T, N>& theBox) const
+{
+ typename BVH_Box<T, N>::BVH_VecNt aSize = theBox.Size();
+
+ BVH_Box<T, N> aBox;
+ for (Standard_Integer aX = 0; aX <= 1; ++aX)
+ {
+ for (Standard_Integer aY = 0; aY <= 1; ++aY)
+ {
+ for (Standard_Integer aZ = 0; aZ <= 1; ++aZ)
+ {
+ typename BVH_Box<T, N>::BVH_VecNt aCorner = theBox.CornerMin() +
+ BVH::UnitVector<T, N>::DX() * aSize * static_cast<T> (aX) +
+ BVH::UnitVector<T, N>::DY() * aSize * static_cast<T> (aY) +
+ BVH::UnitVector<T, N>::DZ() * aSize * static_cast<T> (aZ);
+
+ aBox.Add (BVH::MatrixOp<T, N>::Multiply (myTransform, aCorner));
+ }
+ }
+ }
+
+ return aBox;
+}
#endif // _BVH_Properties_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// =======================================================================
-// function : BVH_Transform
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Transform<T, N>::BVH_Transform()
-{
- //
-}
-
-// =======================================================================
-// function : BVH_Transform
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Transform<T, N>::BVH_Transform (const BVH_MatNt& theTransform)
-: myTransform (theTransform)
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_Transform
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Transform<T, N>::~BVH_Transform()
-{
- //
-}
-
-// =======================================================================
-// function : Transform
-// purpose :
-// =======================================================================
-template<class T, int N>
-const typename BVH_Transform<T, N>::BVH_MatNt& BVH_Transform<T, N>::Transform() const
-{
- return myTransform;
-}
-
-namespace BVH
-{
- template<class T, int N> struct MatrixOp
- {
- // Not implemented
- };
-
- template<class T> struct MatrixOp<T, 4>
- {
- typedef typename BVH::MatrixType<T, 4>::Type BVH_Mat4t;
-
- static void Inverse (const BVH_Mat4t& theIn,
- BVH_Mat4t& theOut)
- {
- theIn.Inverted (theOut);
- }
-
- typedef typename BVH::VectorType<T, 4>::Type BVH_Vec4t;
-
- static BVH_Vec4t Multiply (const BVH_Mat4t& theMat,
- const BVH_Vec4t& theVec)
- {
- BVH_Vec4t aOut = theMat * theVec;
- return aOut * static_cast<T> (1.0 / aOut.w());
- }
- };
-}
-
-// =======================================================================
-// function : SetTransform
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Transform<T, N>::SetTransform (const BVH_MatNt& theTransform)
-{
- myTransform = theTransform;
- BVH::MatrixOp<T, N>::Inverse (myTransform, myTransformInversed);
-}
-
-// =======================================================================
-// function : Inversed
-// purpose :
-// =======================================================================
-template<class T, int N>
-const typename BVH_Transform<T, N>::BVH_MatNt& BVH_Transform<T, N>::Inversed() const
-{
- return myTransformInversed;
-}
-
-namespace BVH
-{
- template<class T, int N>
- struct UnitVector
- {
- // Not implemented
- };
-
- template<class T>
- struct UnitVector<T, 2>
- {
- typedef typename BVH::VectorType<T, 2>::Type BVH_Vec2t;
-
- static BVH_Vec2t DX()
- {
- return BVH_Vec2t (static_cast<T> (1.0),
- static_cast<T> (0.0));
- }
-
- static BVH_Vec2t DY()
- {
- return BVH_Vec2t (static_cast<T> (0.0),
- static_cast<T> (1.0));
- }
-
- static BVH_Vec2t DZ()
- {
- return BVH_Vec2t (static_cast<T> (0.0),
- static_cast<T> (0.0));
- }
- };
-
- template<class T>
- struct UnitVector<T, 3>
- {
- typedef typename BVH::VectorType<T, 3>::Type BVH_Vec3t;
-
- static BVH_Vec3t DX()
- {
- return BVH_Vec3t (static_cast<T> (1.0),
- static_cast<T> (0.0),
- static_cast<T> (0.0));
- }
-
- static BVH_Vec3t DY()
- {
- return BVH_Vec3t (static_cast<T> (0.0),
- static_cast<T> (1.0),
- static_cast<T> (0.0));
- }
-
- static BVH_Vec3t DZ()
- {
- return BVH_Vec3t (static_cast<T> (0.0),
- static_cast<T> (0.0),
- static_cast<T> (1.0));
- }
- };
-
- template<class T>
- struct UnitVector<T, 4>
- {
- typedef typename BVH::VectorType<T, 4>::Type BVH_Vec4t;
-
- static BVH_Vec4t DX()
- {
- return BVH_Vec4t (static_cast<T> (1.0),
- static_cast<T> (0.0),
- static_cast<T> (0.0),
- static_cast<T> (0.0));
- }
-
- static BVH_Vec4t DY()
- {
- return BVH_Vec4t (static_cast<T> (0.0),
- static_cast<T> (1.0),
- static_cast<T> (0.0),
- static_cast<T> (0.0));
- }
-
- static BVH_Vec4t DZ()
- {
- return BVH_Vec4t (static_cast<T> (0.0),
- static_cast<T> (0.0),
- static_cast<T> (1.0),
- static_cast<T> (0.0));
- }
- };
-}
-
-// =======================================================================
-// function : Apply
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Box<T, N> BVH_Transform<T, N>::Apply (const BVH_Box<T, N>& theBox) const
-{
- typename BVH_Box<T, N>::BVH_VecNt aSize = theBox.Size();
-
- BVH_Box<T, N> aBox;
- for (Standard_Integer aX = 0; aX <= 1; ++aX)
- {
- for (Standard_Integer aY = 0; aY <= 1; ++aY)
- {
- for (Standard_Integer aZ = 0; aZ <= 1; ++aZ)
- {
- typename BVH_Box<T, N>::BVH_VecNt aCorner = theBox.CornerMin() +
- BVH::UnitVector<T, N>::DX() * aSize * static_cast<T> (aX) +
- BVH::UnitVector<T, N>::DY() * aSize * static_cast<T> (aY) +
- BVH::UnitVector<T, N>::DZ() * aSize * static_cast<T> (aZ);
-
- aBox.Add (BVH::MatrixOp<T, N>::Multiply (myTransform, aCorner));
- }
- }
- }
-
- return aBox;
-}
//! Returns index of the K-th child of the given inner node.
//! \tparam K the index of node child (from 0 to 3)
template<int K>
- int Child (const int theNodeIndex) const;
+ int Child (const int theNodeIndex) const
+ {
+ return BVH::Array<int, 4>::Value (this->myNodeInfoBuffer, theNodeIndex).y() + K;
+ }
};
-#include <BVH_QuadTree.lxx>
-
#endif // _BVH_QuadTree_Header
+++ /dev/null
-// Created on: 2016-06-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2016 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// =======================================================================
-// function : Child
-// purpose : Returns index of the K-th child of the given inner node
-// =======================================================================
-template<class T, int N> template<int K>
-int BVH_Tree<T, N, BVH_QuadTree>::Child (const int theNodeIndex) const
-{
- return BVH::Array<int, 4>::Value (this->myNodeInfoBuffer, theNodeIndex).y() + K;
-}
//! Creates new BVH queue based builder.
BVH_QueueBuilder (const Standard_Integer theLeafNodeSize,
const Standard_Integer theMaxTreeDepth,
- const Standard_Integer theNumOfThreads = 1);
+ const Standard_Integer theNumOfThreads = 1)
+ : BVH_Builder<T, N> (theLeafNodeSize,
+ theMaxTreeDepth),
+ myNumOfThreads (theNumOfThreads) {}
//! Releases resources of BVH queue based builder.
virtual ~BVH_QueueBuilder() = 0;
//! Builds BVH using specific algorithm.
virtual void Build (BVH_Set<T, N>* theSet,
BVH_Tree<T, N>* theBVH,
- const BVH_Box<T, N>& theBox);
+ const BVH_Box<T, N>& theBox) const Standard_OVERRIDE;
protected:
public:
//! Creates new BVH build thread.
- BVH_TypedBuildTool (BVH_Set<T, N>* theSet,
- BVH_Tree<T, N>* theBVH,
- BVH_Builder<T, N>* theAlgo)
+ BVH_TypedBuildTool (BVH_Set<T, N>* theSet,
+ BVH_Tree<T, N>* theBVH,
+ BVH_BuildQueue& theBuildQueue,
+ const BVH_QueueBuilder<T, N>* theAlgo)
: mySet (theSet),
- myBVH (theBVH)
+ myBVH (theBVH),
+ myBuildQueue (&theBuildQueue),
+ myAlgo (theAlgo)
{
- myAlgo = dynamic_cast<BVH_QueueBuilder<T, N>* > (theAlgo);
-
- Standard_ASSERT_RAISE (myAlgo != NULL,
- "Error! BVH builder should be queue based");
+ Standard_ASSERT_RAISE (myAlgo != NULL, "Error! BVH builder should be queue based");
}
//! Performs splitting of the given BVH node.
- virtual void Perform (const Standard_Integer theNode)
+ virtual void Perform (const Standard_Integer theNode) Standard_OVERRIDE
{
- const typename BVH_QueueBuilder<T, N>::BVH_ChildNodes aChildren = myAlgo->BuildNode (mySet, myBVH, theNode);
-
- myAlgo->AddChildren (myBVH, theNode, aChildren);
+ const typename BVH_QueueBuilder<T, N>::BVH_ChildNodes aChildren = myAlgo->buildNode (mySet, myBVH, theNode);
+ myAlgo->addChildren (myBVH, *myBuildQueue, theNode, aChildren);
}
protected:
- //! Primitive set to build BVH.
- BVH_Set<T, N>* mySet;
-
- //! Output BVH tree for the set.
- BVH_Tree<T, N>* myBVH;
+ BVH_Set<T, N>* mySet; //!< Primitive set to build BVH
+ BVH_Tree<T, N>* myBVH; //!< Output BVH tree for the set
+ BVH_BuildQueue* myBuildQueue;
+ const BVH_QueueBuilder<T, N>* myAlgo; //!< Queue based BVH builder to use
- //! Queue based BVH builder to use.
- BVH_QueueBuilder<T, N>* myAlgo;
};
protected:
//! Performs splitting of the given BVH node.
- virtual typename BVH_QueueBuilder<T, N>::BVH_ChildNodes BuildNode (BVH_Set<T, N>* theSet,
+ virtual typename BVH_QueueBuilder<T, N>::BVH_ChildNodes buildNode (BVH_Set<T, N>* theSet,
BVH_Tree<T, N>* theBVH,
- const Standard_Integer theNode) = 0;
+ const Standard_Integer theNode) const = 0;
//! Processes child nodes of the splitted BVH node.
- virtual void AddChildren (BVH_Tree<T, N>* theBVH,
- const Standard_Integer theNode,
- const BVH_ChildNodes& theSubNodes);
+ virtual void addChildren (BVH_Tree<T, N>* theBVH,
+ BVH_BuildQueue& theBuildQueue,
+ const Standard_Integer theNode,
+ const BVH_ChildNodes& theSubNodes) const;
protected:
- BVH_BuildQueue myBuildQueue; //!< Queue to manage BVH node building tasks
-
Standard_Integer myNumOfThreads; //!< Number of threads used to build BVH
};
-#include <BVH_QueueBuilder.lxx>
+// =======================================================================
+// function : addChildren
+// purpose :
+// =======================================================================
+template<class T, int N>
+void BVH_QueueBuilder<T, N>::addChildren (BVH_Tree<T, N>* theBVH,
+ BVH_BuildQueue& theBuildQueue,
+ const Standard_Integer theNode,
+ const typename BVH_QueueBuilder<T, N>::BVH_ChildNodes& theSubNodes) const
+{
+ Standard_Integer aChildren[] = { -1, -1 };
+ if (!theSubNodes.IsValid())
+ {
+ return;
+ }
+
+ // Add child nodes
+ {
+ Standard_Mutex::Sentry aSentry (theBuildQueue.myMutex);
+
+ for (Standard_Integer anIdx = 0; anIdx < 2; ++anIdx)
+ {
+ aChildren[anIdx] = theBVH->AddLeafNode (theSubNodes.Boxes[anIdx],
+ theSubNodes.Ranges[anIdx].Start,
+ theSubNodes.Ranges[anIdx].Final);
+ }
+
+ BVH_Builder<T, N>::updateDepth (theBVH, theBVH->Level (theNode) + 1);
+ }
+
+ // Set parameters of child nodes and generate new tasks
+ for (Standard_Integer anIdx = 0; anIdx < 2; ++anIdx)
+ {
+ const Standard_Integer aChildIndex = aChildren[anIdx];
+
+ theBVH->Level (aChildIndex) = theBVH->Level (theNode) + 1;
+
+ (anIdx == 0 ? theBVH->template Child<0> (theNode)
+ : theBVH->template Child<1> (theNode)) = aChildIndex;
+
+ // Check to see if the child node must be split
+ const Standard_Boolean isLeaf = theSubNodes.NbPrims (anIdx) <= BVH_Builder<T, N>::myLeafNodeSize
+ || theBVH->Level (aChildIndex) >= BVH_Builder<T, N>::myMaxTreeDepth;
+
+ if (!isLeaf)
+ {
+ theBuildQueue.Enqueue (aChildIndex);
+ }
+ }
+}
+
+// =======================================================================
+// function : Build
+// purpose : Builds BVH using specific algorithm
+// =======================================================================
+template<class T, int N>
+void BVH_QueueBuilder<T, N>::Build (BVH_Set<T, N>* theSet,
+ BVH_Tree<T, N>* theBVH,
+ const BVH_Box<T, N>& theBox) const
+{
+ Standard_ASSERT_RETURN (theBVH != NULL,
+ "Error! BVH tree to construct is NULL", );
+
+ theBVH->Clear();
+ const Standard_Integer aSetSize = theSet->Size();
+ if (aSetSize == 0)
+ {
+ return;
+ }
+
+ const Standard_Integer aRoot = theBVH->AddLeafNode (theBox, 0, aSetSize - 1);
+ if (theSet->Size() == 1)
+ {
+ return;
+ }
+
+ BVH_BuildQueue aBuildQueue;
+ aBuildQueue.Enqueue (aRoot);
+
+ BVH_TypedBuildTool aBuildTool (theSet, theBVH, aBuildQueue, this);
+ if (myNumOfThreads > 1)
+ {
+ // Reserve the maximum possible number of nodes in the BVH
+ theBVH->Reserve (2 * aSetSize - 1);
+
+ NCollection_Vector<Handle(BVH_BuildThread)> aThreads;
+
+ // Run BVH build threads
+ for (Standard_Integer aThreadIndex = 0; aThreadIndex < myNumOfThreads; ++aThreadIndex)
+ {
+ aThreads.Append (new BVH_BuildThread (aBuildTool, aBuildQueue));
+ aThreads.Last()->Run();
+ }
+
+ // Wait until all threads finish their work
+ for (Standard_Integer aThreadIndex = 0; aThreadIndex < myNumOfThreads; ++aThreadIndex)
+ {
+ aThreads.ChangeValue (aThreadIndex)->Wait();
+ }
+
+ // Free unused memory
+ theBVH->Reserve (theBVH->Length());
+ }
+ else
+ {
+ BVH_BuildThread aThread (aBuildTool, aBuildQueue);
+
+ // Execute thread function inside current thread
+ aThread.execute();
+ }
+}
+
+// =======================================================================
+// function : ~BVH_QueueBuilder
+// purpose :
+// =======================================================================
+template<class T, int N>
+BVH_QueueBuilder<T, N>::~BVH_QueueBuilder()
+{
+ //
+}
#endif // _BVH_QueueBuilder_Header
+++ /dev/null
-// Created on: 2014-09-15
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <NCollection_Vector.hxx>
-
-// =======================================================================
-// function : BVH_QueueBuilder
-// purpose : Creates new BVH queue based builder
-// =======================================================================
-template<class T, int N>
-BVH_QueueBuilder<T, N>::BVH_QueueBuilder (const Standard_Integer theLeafNodeSize,
- const Standard_Integer theMaxTreeDepth,
- const Standard_Integer theNumOfThreads)
-: BVH_Builder<T, N> (theLeafNodeSize,
- theMaxTreeDepth),
- myNumOfThreads (theNumOfThreads)
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_QueueBuilder
-// purpose : Releases resources of BVH queue based builder
-// =======================================================================
-template<class T, int N>
-BVH_QueueBuilder<T, N>::~BVH_QueueBuilder()
-{
- //
-}
-
-// =======================================================================
-// function : AddChildren
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_QueueBuilder<T, N>::AddChildren (BVH_Tree<T, N>* theBVH,
- const Standard_Integer theNode,
- const typename BVH_QueueBuilder<T, N>::BVH_ChildNodes& theSubNodes)
-{
- Standard_Integer aChildren[] = { -1, -1 };
-
- if (!theSubNodes.IsValid())
- {
- return;
- }
-
- // Add child nodes
- {
- Standard_Mutex::Sentry aSentry (myBuildQueue.myMutex);
-
- for (Standard_Integer anIdx = 0; anIdx < 2; ++anIdx)
- {
- aChildren[anIdx] = theBVH->AddLeafNode (theSubNodes.Boxes[anIdx],
- theSubNodes.Ranges[anIdx].Start,
- theSubNodes.Ranges[anIdx].Final);
- }
-
- BVH_Builder<T, N>::UpdateDepth (theBVH, theBVH->Level (theNode) + 1);
- }
-
- // Set parameters of child nodes and generate new tasks
- for (Standard_Integer anIdx = 0; anIdx < 2; ++anIdx)
- {
- const Standard_Integer aChildIndex = aChildren[anIdx];
-
- theBVH->Level (aChildIndex) = theBVH->Level (theNode) + 1;
-
- (anIdx == 0 ? theBVH->template Child<0> (theNode)
- : theBVH->template Child<1> (theNode)) = aChildIndex;
-
- // Check to see if the child node must be split
- const Standard_Boolean isLeaf = theSubNodes.NbPrims (anIdx) <= BVH_Builder<T, N>::myLeafNodeSize
- || theBVH->Level (aChildIndex) >= BVH_Builder<T, N>::myMaxTreeDepth;
-
- if (!isLeaf)
- {
- myBuildQueue.Enqueue (aChildIndex);
- }
- }
-}
-
-// =======================================================================
-// function : Build
-// purpose : Builds BVH using specific algorithm
-// =======================================================================
-template<class T, int N>
-void BVH_QueueBuilder<T, N>::Build (BVH_Set<T, N>* theSet,
- BVH_Tree<T, N>* theBVH,
- const BVH_Box<T, N>& theBox)
-{
- Standard_ASSERT_RETURN (theBVH != NULL,
- "Error! BVH tree to construct is NULL", );
-
- theBVH->Clear();
- const Standard_Integer aSetSize = theSet->Size();
- if (aSetSize == 0)
- {
- return;
- }
-
- const Standard_Integer aRoot = theBVH->AddLeafNode (theBox, 0, aSetSize - 1);
- if (theSet->Size() == 1)
- {
- return;
- }
-
- myBuildQueue.Enqueue (aRoot);
-
- BVH_TypedBuildTool aBuildTool (theSet, theBVH, this);
-
- if (myNumOfThreads > 1)
- {
- // Reserve the maximum possible number of nodes in the BVH
- theBVH->Reserve (2 * aSetSize - 1);
-
- NCollection_Vector<Handle(BVH_BuildThread)> aThreads;
-
- // Run BVH build threads
- for (Standard_Integer aThreadIndex = 0; aThreadIndex < myNumOfThreads; ++aThreadIndex)
- {
- aThreads.Append (new BVH_BuildThread (aBuildTool, myBuildQueue));
- aThreads.Last()->Run();
- }
-
- // Wait until all threads finish their work
- for (Standard_Integer aThreadIndex = 0; aThreadIndex < myNumOfThreads; ++aThreadIndex)
- {
- aThreads.ChangeValue (aThreadIndex)->Wait();
- }
-
- // Free unused memory
- theBVH->Reserve (theBVH->Length());
- }
- else
- {
- BVH_BuildThread aThread (aBuildTool, myBuildQueue);
-
- // Execute thread function inside current thread
- aThread.execute();
- }
-}
BVH_QuickSorter (const Standard_Integer theAxis = 0) : myAxis (theAxis) { }
//! Sorts the set.
- virtual void Perform (BVH_Set<T, N>* theSet);
+ virtual void Perform (BVH_Set<T, N>* theSet) Standard_OVERRIDE
+ {
+ Perform (theSet, 0, theSet->Size() - 1);
+ }
//! Sorts the given (inclusive) range in the set.
- virtual void Perform (BVH_Set<T, N>* theSet, const Standard_Integer theStart, const Standard_Integer theFinal);
+ virtual void Perform (BVH_Set<T, N>* theSet, const Standard_Integer theStart, const Standard_Integer theFinal) Standard_OVERRIDE
+ {
+ Standard_Integer aLft = theStart;
+ Standard_Integer aRgh = theFinal;
+
+ T aPivot = theSet->Center ((aRgh + aLft) / 2, myAxis);
+ while (aLft < aRgh)
+ {
+ while (theSet->Center (aLft, myAxis) < aPivot && aLft < theFinal)
+ {
+ ++aLft;
+ }
+
+ while (theSet->Center (aRgh, myAxis) > aPivot && aRgh > theStart)
+ {
+ --aRgh;
+ }
+
+ if (aLft <= aRgh)
+ {
+ if (aLft != aRgh)
+ {
+ theSet->Swap (aLft, aRgh);
+ }
+ ++aLft;
+ --aRgh;
+ }
+ }
+
+ if (aRgh > theStart)
+ {
+ Perform (theSet, theStart, aRgh);
+ }
+
+ if (aLft < theFinal)
+ {
+ Perform (theSet, aLft, theFinal);
+ }
+ }
protected:
};
-#include <BVH_QuickSorter.lxx>
-
#endif // _BVH_QuickSorter_Header
+++ /dev/null
-// Created on: 2016-04-13
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2016 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// =======================================================================
-// function : Perform
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_QuickSorter<T, N>::Perform (BVH_Set<T, N>* theSet)
-{
- Perform (theSet, 0, theSet->Size() - 1);
-}
-
-// =======================================================================
-// function : Perform
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_QuickSorter<T, N>::Perform (BVH_Set<T, N>* theSet, const Standard_Integer theStart, const Standard_Integer theFinal)
-{
- Standard_Integer aLft = theStart;
- Standard_Integer aRgh = theFinal;
-
- T aPivot = theSet->Center ((aRgh + aLft) / 2, myAxis);
-
- while (aLft < aRgh)
- {
- while (theSet->Center (aLft, myAxis) < aPivot && aLft < theFinal)
- {
- ++aLft;
- }
-
- while (theSet->Center (aRgh, myAxis) > aPivot && aRgh > theStart)
- {
- --aRgh;
- }
-
- if (aLft <= aRgh)
- {
- if (aLft != aRgh)
- {
- theSet->Swap (aLft, aRgh);
- }
-
- ++aLft;
- --aRgh;
- }
- }
-
- if (aRgh > theStart)
- {
- Perform (theSet, theStart, aRgh);
- }
-
- if (aLft < theFinal)
- {
- Perform (theSet, aLft, theFinal);
- }
-}
#include <BVH_Sorter.hxx>
#include <BVH_Builder.hxx>
-
#include <NCollection_Handle.hxx>
#include <NCollection_Array1.hxx>
+#include <algorithm>
+
+#ifdef HAVE_TBB
+ // On Windows, function TryEnterCriticalSection has appeared in Windows NT
+ // and is surrounded by #ifdef in MS VC++ 7.1 headers.
+ // Thus to use it we need to define appropriate macro saying that we will
+ // run on Windows NT 4.0 at least
+ #if defined(_WIN32) && !defined(_WIN32_WINNT)
+ #define _WIN32_WINNT 0x0501
+ #endif
+
+ #include <tbb/parallel_invoke.h>
+#endif
+
//! Pair of Morton code and primitive ID.
typedef std::pair<Standard_Integer, Standard_Integer> BVH_EncodedLink;
BVH_RadixSorter (const BVH_Box<T, N>& theBox) : myBox (theBox) { }
//! Sorts the set.
- virtual void Perform (BVH_Set<T, N>* theSet);
+ virtual void Perform (BVH_Set<T, N>* theSet) Standard_OVERRIDE { Perform (theSet, 0, theSet->Size() - 1); }
//! Sorts the given (inclusive) range in the set.
- virtual void Perform (BVH_Set<T, N>* theSet, const Standard_Integer theStart, const Standard_Integer theFinal);
+ virtual void Perform (BVH_Set<T, N>* theSet, const Standard_Integer theStart, const Standard_Integer theFinal) Standard_OVERRIDE;
//! Returns Morton codes assigned to BVH primitives.
const NCollection_Array1<BVH_EncodedLink>& EncodedLinks() const { return *myEncodedLinks; }
};
-#include <BVH_RadixSorter.lxx>
+namespace BVH
+{
+ // Radix sort STL predicate for 32-bit integer.
+ struct BitPredicate
+ {
+ Standard_Integer myBit;
+
+ //! Creates new radix sort predicate.
+ BitPredicate (const Standard_Integer theBit) : myBit (theBit) {}
+
+ //! Returns predicate value.
+ bool operator() (const BVH_EncodedLink theLink) const
+ {
+ const Standard_Integer aMask = 1 << myBit;
+ return !(theLink.first & aMask); // 0-bit to the left side
+ }
+ };
+
+ //! STL compare tool used in binary search algorithm.
+ struct BitComparator
+ {
+ Standard_Integer myBit;
+
+ //! Creates new STL comparator.
+ BitComparator (const Standard_Integer theBit) : myBit (theBit) {}
+
+ //! Checks left value for the given bit.
+ bool operator() (BVH_EncodedLink theLink1, BVH_EncodedLink /*theLink2*/)
+ {
+ return !(theLink1.first & (1 << myBit));
+ }
+ };
+
+ //! Tool object for sorting link array using radix sort algorithm.
+ class RadixSorter
+ {
+ public:
+
+ typedef NCollection_Array1<BVH_EncodedLink>::iterator LinkIterator;
+
+ private:
+
+ //! TBB functor class to run sorting.
+ struct Functor
+ {
+ LinkIterator myStart; //!< Start element of exclusive sorting range
+ LinkIterator myFinal; //!< Final element of exclusive sorting range
+ Standard_Integer myDigit; //!< Bit number used for partition operation
+
+ //! Creates new sorting functor.
+ Functor (LinkIterator theStart, LinkIterator theFinal, Standard_Integer theDigit)
+ : myStart (theStart), myFinal (theFinal), myDigit (theDigit) {}
+
+ //! Runs sorting function for the given range.
+ void operator() () const
+ {
+ RadixSorter::Sort (myStart, myFinal, myDigit);
+ }
+ };
+
+ public:
+
+ static void Sort (LinkIterator theStart, LinkIterator theFinal, Standard_Integer theDigit)
+ {
+ #ifdef HAVE_TBB
+ if (theDigit < 24)
+ {
+ BVH::RadixSorter::perform (theStart, theFinal, theDigit);
+ }
+ else
+ {
+ LinkIterator anOffset = std::partition (theStart, theFinal, BitPredicate (theDigit));
+ tbb::parallel_invoke (Functor (theStart, anOffset, theDigit - 1),
+ Functor (anOffset, theFinal, theDigit - 1));
+ }
+ #else
+ BVH::RadixSorter::perform (theStart, theFinal, theDigit);
+ #endif
+ }
+
+ protected:
+
+ // Performs MSD (most significant digit) radix sort.
+ static void perform (LinkIterator theStart, LinkIterator theFinal, Standard_Integer theBit = 29)
+ {
+ while (theStart != theFinal && theBit >= 0)
+ {
+ LinkIterator anOffset = std::partition (theStart, theFinal, BitPredicate (theBit--));
+ perform (theStart, anOffset, theBit);
+ theStart = anOffset;
+ }
+ }
+ };
+}
+
+// =======================================================================
+// function : Perform
+// purpose :
+// =======================================================================
+template<class T, int N>
+void BVH_RadixSorter<T, N>::Perform (BVH_Set<T, N>* theSet, const Standard_Integer theStart, const Standard_Integer theFinal)
+{
+ Standard_STATIC_ASSERT (N == 3 || N == 4);
+
+ const Standard_Integer aDimensionX = 1024;
+ const Standard_Integer aDimensionY = 1024;
+ const Standard_Integer aDimensionZ = 1024;
+
+ const BVH_VecNt aSceneMin = myBox.CornerMin();
+ const BVH_VecNt aSceneMax = myBox.CornerMax();
+
+ const T aReverseSizeX = static_cast<T> (aDimensionX) / Max (static_cast<T> (BVH::THE_NODE_MIN_SIZE), aSceneMax.x() - aSceneMin.x());
+ const T aReverseSizeY = static_cast<T> (aDimensionY) / Max (static_cast<T> (BVH::THE_NODE_MIN_SIZE), aSceneMax.y() - aSceneMin.y());
+ const T aReverseSizeZ = static_cast<T> (aDimensionZ) / Max (static_cast<T> (BVH::THE_NODE_MIN_SIZE), aSceneMax.z() - aSceneMin.z());
+
+ myEncodedLinks = new NCollection_Array1<BVH_EncodedLink> (theStart, theFinal);
+
+ // Step 1 -- Assign Morton code to each primitive
+ for (Standard_Integer aPrimIdx = theStart; aPrimIdx <= theFinal; ++aPrimIdx)
+ {
+ const BVH_VecNt aCenter = theSet->Box (aPrimIdx).Center();
+
+ Standard_Integer aVoxelX = BVH::IntFloor ((aCenter.x() - aSceneMin.x()) * aReverseSizeX);
+ Standard_Integer aVoxelY = BVH::IntFloor ((aCenter.y() - aSceneMin.y()) * aReverseSizeY);
+ Standard_Integer aVoxelZ = BVH::IntFloor ((aCenter.z() - aSceneMin.z()) * aReverseSizeZ);
+
+ aVoxelX = Max (0, Min (aVoxelX, aDimensionX - 1));
+ aVoxelY = Max (0, Min (aVoxelY, aDimensionY - 1));
+ aVoxelZ = Max (0, Min (aVoxelZ, aDimensionZ - 1));
+
+ aVoxelX = (aVoxelX | (aVoxelX << 16)) & 0x030000FF;
+ aVoxelX = (aVoxelX | (aVoxelX << 8)) & 0x0300F00F;
+ aVoxelX = (aVoxelX | (aVoxelX << 4)) & 0x030C30C3;
+ aVoxelX = (aVoxelX | (aVoxelX << 2)) & 0x09249249;
+
+ aVoxelY = (aVoxelY | (aVoxelY << 16)) & 0x030000FF;
+ aVoxelY = (aVoxelY | (aVoxelY << 8)) & 0x0300F00F;
+ aVoxelY = (aVoxelY | (aVoxelY << 4)) & 0x030C30C3;
+ aVoxelY = (aVoxelY | (aVoxelY << 2)) & 0x09249249;
+
+ aVoxelZ = (aVoxelZ | (aVoxelZ << 16)) & 0x030000FF;
+ aVoxelZ = (aVoxelZ | (aVoxelZ << 8)) & 0x0300F00F;
+ aVoxelZ = (aVoxelZ | (aVoxelZ << 4)) & 0x030C30C3;
+ aVoxelZ = (aVoxelZ | (aVoxelZ << 2)) & 0x09249249;
+
+ myEncodedLinks->ChangeValue (aPrimIdx) = BVH_EncodedLink (
+ aVoxelX | (aVoxelY << 1) | (aVoxelZ << 2), aPrimIdx);
+ }
+
+ // Step 2 -- Sort primitives by their Morton codes using radix sort
+ BVH::RadixSorter::Sort (myEncodedLinks->begin(), myEncodedLinks->end(), 29);
+
+ NCollection_Array1<Standard_Integer> aLinkMap (theStart, theFinal);
+ for (Standard_Integer aLinkIdx = theStart; aLinkIdx <= theFinal; ++aLinkIdx)
+ {
+ aLinkMap (myEncodedLinks->Value (aLinkIdx).second) = aLinkIdx;
+ }
+
+ // Step 3 -- Rearranging primitive list according to Morton codes (in place)
+ Standard_Integer aPrimIdx = theStart;
+ while (aPrimIdx <= theFinal)
+ {
+ const Standard_Integer aSortIdx = aLinkMap (aPrimIdx);
+ if (aPrimIdx != aSortIdx)
+ {
+ theSet->Swap (aPrimIdx, aSortIdx);
+ std::swap (aLinkMap (aPrimIdx),
+ aLinkMap (aSortIdx));
+ }
+ else
+ {
+ ++aPrimIdx;
+ }
+ }
+}
#endif // _BVH_RadixSorter_Header
+++ /dev/null
-// Created on: 2016-04-13
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2016 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <algorithm>
-
-#ifdef HAVE_TBB
- // On Windows, function TryEnterCriticalSection has appeared in Windows NT
- // and is surrounded by #ifdef in MS VC++ 7.1 headers.
- // Thus to use it we need to define appropriate macro saying that we will
- // run on Windows NT 4.0 at least
- #if defined(_WIN32) && !defined(_WIN32_WINNT)
- #define _WIN32_WINNT 0x0501
- #endif
-
- #include <tbb/parallel_invoke.h>
-#endif
-
-// =======================================================================
-// function : Perform
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_RadixSorter<T, N>::Perform (BVH_Set<T, N>* theSet)
-{
- Perform (theSet, 0, theSet->Size() - 1);
-}
-
-namespace BVH
-{
- // Radix sort STL predicate for 32-bit integer.
- class BitPredicate
- {
- Standard_Integer myBit;
-
- public:
-
- //! Creates new radix sort predicate.
- BitPredicate (const Standard_Integer theBit) : myBit (theBit)
- {
- //
- }
-
- //! Returns predicate value.
- bool operator() (const BVH_EncodedLink theLink) const
- {
- const Standard_Integer aMask = 1 << myBit;
-
- return !(theLink.first & aMask); // 0-bit to the left side
- }
- };
-
- //! STL compare tool used in binary search algorithm.
- class BitComparator
- {
- Standard_Integer myBit;
-
- public:
-
- //! Creates new STL comparator.
- BitComparator (const Standard_Integer theBit) : myBit (theBit)
- {
- //
- }
-
- //! Checks left value for the given bit.
- bool operator() (BVH_EncodedLink theLink1, BVH_EncodedLink /*theLink2*/)
- {
- return !(theLink1.first & (1 << myBit));
- }
- };
-
- //! Tool object for sorting link array using radix sort algorithm.
- class RadixSorter
- {
- public:
-
- typedef NCollection_Array1<BVH_EncodedLink>::iterator LinkIterator;
-
- private:
-
- //! TBB functor class to run sorting.
- class Functor
- {
- //! Start element of exclusive sorting range.
- LinkIterator myStart;
-
- //! Final element of exclusive sorting range.
- LinkIterator myFinal;
-
- //! Bit number used for partition operation.
- Standard_Integer myDigit;
-
- public:
-
- //! Creates new sorting functor.
- Functor (LinkIterator theStart, LinkIterator theFinal, Standard_Integer theDigit)
- : myStart (theStart),
- myFinal (theFinal),
- myDigit (theDigit) { }
-
- //! Runs sorting function for the given range.
- void operator() () const
- {
- RadixSorter::Sort (myStart, myFinal, myDigit);
- }
- };
-
- public:
-
- static void Sort (LinkIterator theStart, LinkIterator theFinal, Standard_Integer theDigit)
- {
-#ifdef HAVE_TBB
- if (theDigit < 24)
- {
- BVH::RadixSorter::perform (theStart, theFinal, theDigit);
- }
- else
- {
- LinkIterator anOffset = std::partition (theStart, theFinal, BitPredicate (theDigit));
-
- tbb::parallel_invoke (Functor (theStart, anOffset, theDigit - 1),
- Functor (anOffset, theFinal, theDigit - 1));
- }
-#else
- BVH::RadixSorter::perform (theStart, theFinal, theDigit);
-#endif
- }
-
- protected:
-
- // Performs MSD (most significant digit) radix sort.
- static void perform (LinkIterator theStart, LinkIterator theFinal, Standard_Integer theBit = 29)
- {
- while (theStart != theFinal && theBit >= 0)
- {
- LinkIterator anOffset = std::partition (theStart, theFinal, BitPredicate (theBit--));
-
- perform (theStart, anOffset, theBit);
-
- theStart = anOffset;
- }
- }
- };
-}
-
-// =======================================================================
-// function : Perform
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_RadixSorter<T, N>::Perform (BVH_Set<T, N>* theSet, const Standard_Integer theStart, const Standard_Integer theFinal)
-{
- Standard_STATIC_ASSERT (N == 3 || N == 4);
-
- const Standard_Integer aDimensionX = 1024;
- const Standard_Integer aDimensionY = 1024;
- const Standard_Integer aDimensionZ = 1024;
-
- const BVH_VecNt aSceneMin = myBox.CornerMin();
- const BVH_VecNt aSceneMax = myBox.CornerMax();
-
- const T aReverseSizeX = static_cast<T> (aDimensionX) / Max (static_cast<T> (BVH::THE_NODE_MIN_SIZE), aSceneMax.x() - aSceneMin.x());
- const T aReverseSizeY = static_cast<T> (aDimensionY) / Max (static_cast<T> (BVH::THE_NODE_MIN_SIZE), aSceneMax.y() - aSceneMin.y());
- const T aReverseSizeZ = static_cast<T> (aDimensionZ) / Max (static_cast<T> (BVH::THE_NODE_MIN_SIZE), aSceneMax.z() - aSceneMin.z());
-
- myEncodedLinks = new NCollection_Array1<BVH_EncodedLink> (theStart, theFinal);
-
- // Step 1 -- Assign Morton code to each primitive
- for (Standard_Integer aPrimIdx = theStart; aPrimIdx <= theFinal; ++aPrimIdx)
- {
- const BVH_VecNt aCenter = theSet->Box (aPrimIdx).Center();
-
- Standard_Integer aVoxelX = BVH::IntFloor ((aCenter.x() - aSceneMin.x()) * aReverseSizeX);
- Standard_Integer aVoxelY = BVH::IntFloor ((aCenter.y() - aSceneMin.y()) * aReverseSizeY);
- Standard_Integer aVoxelZ = BVH::IntFloor ((aCenter.z() - aSceneMin.z()) * aReverseSizeZ);
-
- aVoxelX = Max (0, Min (aVoxelX, aDimensionX - 1));
- aVoxelY = Max (0, Min (aVoxelY, aDimensionY - 1));
- aVoxelZ = Max (0, Min (aVoxelZ, aDimensionZ - 1));
-
- aVoxelX = (aVoxelX | (aVoxelX << 16)) & 0x030000FF;
- aVoxelX = (aVoxelX | (aVoxelX << 8)) & 0x0300F00F;
- aVoxelX = (aVoxelX | (aVoxelX << 4)) & 0x030C30C3;
- aVoxelX = (aVoxelX | (aVoxelX << 2)) & 0x09249249;
-
- aVoxelY = (aVoxelY | (aVoxelY << 16)) & 0x030000FF;
- aVoxelY = (aVoxelY | (aVoxelY << 8)) & 0x0300F00F;
- aVoxelY = (aVoxelY | (aVoxelY << 4)) & 0x030C30C3;
- aVoxelY = (aVoxelY | (aVoxelY << 2)) & 0x09249249;
-
- aVoxelZ = (aVoxelZ | (aVoxelZ << 16)) & 0x030000FF;
- aVoxelZ = (aVoxelZ | (aVoxelZ << 8)) & 0x0300F00F;
- aVoxelZ = (aVoxelZ | (aVoxelZ << 4)) & 0x030C30C3;
- aVoxelZ = (aVoxelZ | (aVoxelZ << 2)) & 0x09249249;
-
- myEncodedLinks->ChangeValue (aPrimIdx) = BVH_EncodedLink (
- aVoxelX | (aVoxelY << 1) | (aVoxelZ << 2), aPrimIdx);
- }
-
- // Step 2 -- Sort primitives by their Morton codes using radix sort
- BVH::RadixSorter::Sort (myEncodedLinks->begin(), myEncodedLinks->end(), 29);
-
- NCollection_Array1<Standard_Integer> aLinkMap (theStart, theFinal);
-
- for (Standard_Integer aLinkIdx = theStart; aLinkIdx <= theFinal; ++aLinkIdx)
- {
- aLinkMap (myEncodedLinks->Value (aLinkIdx).second) = aLinkIdx;
- }
-
- // Step 3 -- Rearranging primitive list according to Morton codes (in place)
- Standard_Integer aPrimIdx = theStart;
-
- while (aPrimIdx <= theFinal)
- {
- const Standard_Integer aSortIdx = aLinkMap (aPrimIdx);
-
- if (aPrimIdx != aSortIdx)
- {
- theSet->Swap (aPrimIdx, aSortIdx);
-
- std::swap (aLinkMap (aPrimIdx),
- aLinkMap (aSortIdx));
- }
- else
- {
- ++aPrimIdx;
- }
- }
-}
public:
//! Creates new abstract set of objects.
- BVH_Set();
+ BVH_Set() {}
//! Releases resources of set of objects.
virtual ~BVH_Set() = 0;
//! Returns AABB of the entire set of objects.
- virtual BVH_Box<T, N> Box() const;
+ virtual BVH_Box<T, N> Box() const
+ {
+ BVH_Box<T, N> aBox;
+ const Standard_Integer aSize = Size();
+ for (Standard_Integer anIndex = 0; anIndex < aSize; ++anIndex)
+ {
+ aBox.Combine (Box (anIndex));
+ }
+ return aBox;
+ }
public:
};
-#include <BVH_Set.lxx>
+// =======================================================================
+// function : ~BVH_Set
+// purpose :
+// =======================================================================
+template<class T, int N>
+BVH_Set<T, N>::~BVH_Set()
+{
+ //
+}
#endif // _BVH_Set_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// =======================================================================
-// function : BVH_Set
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Set<T, N>::BVH_Set()
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_Set
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Set<T, N>::~BVH_Set()
-{
- //
-}
-
-// =======================================================================
-// function : Box
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Box<T, N> BVH_Set<T, N>::Box() const
-{
- BVH_Box<T, N> aBox;
- const Standard_Integer aSize = Size();
- for (Standard_Integer anIndex = 0; anIndex < aSize; ++anIndex)
- {
- aBox.Combine (Box (anIndex));
- }
- return aBox;
-}
#define _BVH_SpatialMedianBuilder_Header
#include <BVH_BinnedBuilder.hxx>
+#include <BVH_Box.hxx>
//! Performs building of BVH tree using spatial median split algorithm.
template<class T, int N>
//! Creates spatial median split builder.
BVH_SpatialMedianBuilder (const Standard_Integer theLeafNodeSize = 5,
const Standard_Integer theMaxTreeDepth = 32,
- const Standard_Boolean theToUseMainAxis = Standard_False);
+ const Standard_Boolean theToUseMainAxis = Standard_False)
+ : BVH_BinnedBuilder<T, N, 2> (theLeafNodeSize,
+ theMaxTreeDepth,
+ theToUseMainAxis) {}
//! Releases resources of spatial median split builder.
- virtual ~BVH_SpatialMedianBuilder();
+ virtual ~BVH_SpatialMedianBuilder() {}
};
-#include <BVH_SpatialMedianBuilder.lxx>
-
#endif // _BVH_SpatialMedianBuilder_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <BVH_Box.hxx>
-
-// =======================================================================
-// function : BVH_SpatialMedianBuilder
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_SpatialMedianBuilder<T, N>::BVH_SpatialMedianBuilder (const Standard_Integer theLeafNodeSize,
- const Standard_Integer theMaxTreeDepth,
- const Standard_Boolean theToUseMainAxis)
-: BVH_BinnedBuilder<T, N, 2> (theLeafNodeSize,
- theMaxTreeDepth,
- theToUseMainAxis)
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_SpatialMedianBuilder
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_SpatialMedianBuilder<T, N>::~BVH_SpatialMedianBuilder()
-{
- //
-}
#define _BVH_SweepPlaneBuilder_Header
#include <BVH_QueueBuilder.hxx>
+#include <BVH_QuickSorter.hxx>
+#include <NCollection_Array1.hxx>
//! Performs building of BVH tree using sweep plane SAH algorithm.
template<class T, int N>
//! Creates sweep plane SAH BVH builder.
BVH_SweepPlaneBuilder (const Standard_Integer theLeafNodeSize = 5,
const Standard_Integer theMaxTreeDepth = 32,
- const Standard_Integer theNumOfThreads = 1);
+ const Standard_Integer theNumOfThreads = 1)
+ : BVH_QueueBuilder<T, N> (theLeafNodeSize,
+ theMaxTreeDepth,
+ theNumOfThreads) {}
//! Releases resources of sweep plane SAH BVH builder.
- virtual ~BVH_SweepPlaneBuilder();
+ virtual ~BVH_SweepPlaneBuilder() {}
protected:
//! Performs splitting of the given BVH node.
- typename BVH_QueueBuilder<T, N>::BVH_ChildNodes BuildNode (BVH_Set<T, N>* theSet,
+ typename BVH_QueueBuilder<T, N>::BVH_ChildNodes buildNode (BVH_Set<T, N>* theSet,
BVH_Tree<T, N>* theBVH,
- const Standard_Integer theNode);
+ const Standard_Integer theNode) const Standard_OVERRIDE
+ {
+ const Standard_Integer aNodeBegPrimitive = theBVH->BegPrimitive (theNode);
+ const Standard_Integer aNodeEndPrimitive = theBVH->EndPrimitive (theNode);
+ const Standard_Integer aNodeNbPrimitives = theBVH->NbPrimitives (theNode);
+ if (aNodeEndPrimitive - aNodeBegPrimitive < BVH_Builder<T, N>::myLeafNodeSize)
+ {
+ return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes(); // node does not require partitioning
+ }
-};
+ // Parameters for storing best split
+ Standard_Integer aMinSplitAxis = -1;
+ Standard_Integer aMinSplitIndex = 0;
+
+ NCollection_Array1<Standard_Real> aLftSet (0, aNodeNbPrimitives - 1);
+ NCollection_Array1<Standard_Real> aRghSet (0, aNodeNbPrimitives - 1);
+ Standard_Real aMinSplitCost = std::numeric_limits<Standard_Real>::max();
+
+ // Find best split
+ for (Standard_Integer anAxis = 0; anAxis < (N < 4 ? N : 3); ++anAxis)
+ {
+ const T aNodeSize = BVH::VecComp<T, N>::Get (theBVH->MaxPoint (theNode), anAxis) -
+ BVH::VecComp<T, N>::Get (theBVH->MinPoint (theNode), anAxis);
+ if (aNodeSize <= BVH::THE_NODE_MIN_SIZE)
+ {
+ continue;
+ }
+
+ BVH_QuickSorter<T, N> (anAxis).Perform (theSet, aNodeBegPrimitive, aNodeEndPrimitive);
+ BVH_Box<T, N> aLftBox;
+ BVH_Box<T, N> aRghBox;
+ aLftSet.ChangeFirst() = std::numeric_limits<T>::max();
+ aRghSet.ChangeFirst() = std::numeric_limits<T>::max();
+
+ // Sweep from left
+ for (Standard_Integer anIndex = 1; anIndex < aNodeNbPrimitives; ++anIndex)
+ {
+ aLftBox.Combine (theSet->Box (anIndex + aNodeBegPrimitive - 1));
+ aLftSet (anIndex) = static_cast<Standard_Real> (aLftBox.Area());
+ }
+
+ // Sweep from right
+ for (Standard_Integer anIndex = 1; anIndex < aNodeNbPrimitives; ++anIndex)
+ {
+ aRghBox.Combine (theSet->Box (aNodeEndPrimitive - anIndex + 1));
+ aRghSet (anIndex) = static_cast<Standard_Real> (aRghBox.Area());
+ }
+
+ // Find best split using simplified SAH
+ for (Standard_Integer aNbLft = 1, aNbRgh = aNodeNbPrimitives - 1; aNbLft < aNodeNbPrimitives; ++aNbLft, --aNbRgh)
+ {
+ Standard_Real aCost = (aLftSet (aNbLft) /* / aNodeArea */) * aNbLft +
+ (aRghSet (aNbRgh) /* / aNodeArea */) * aNbRgh;
+ if (aCost < aMinSplitCost)
+ {
+ aMinSplitCost = aCost;
+ aMinSplitAxis = anAxis;
+ aMinSplitIndex = aNbLft;
+ }
+ }
+ }
-#include <BVH_SweepPlaneBuilder.lxx>
+ if (aMinSplitAxis == -1)
+ {
+ return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes(); // failed to find split axis
+ }
+
+ theBVH->SetInner (theNode);
+ if (aMinSplitAxis != (N < 4 ? N - 1 : 2))
+ {
+ BVH_QuickSorter<T, N> (aMinSplitAxis).Perform (theSet, aNodeBegPrimitive, aNodeEndPrimitive);
+ }
+
+ BVH_Box<T, N> aMinSplitBoxLft;
+ BVH_Box<T, N> aMinSplitBoxRgh;
+
+ // Compute bounding boxes for selected split plane
+ for (Standard_Integer anIndex = aNodeBegPrimitive; anIndex < aMinSplitIndex + aNodeBegPrimitive; ++anIndex)
+ {
+ aMinSplitBoxLft.Combine (theSet->Box (anIndex));
+ }
+
+ for (Standard_Integer anIndex = aNodeEndPrimitive; anIndex >= aMinSplitIndex + aNodeBegPrimitive; --anIndex)
+ {
+ aMinSplitBoxRgh.Combine (theSet->Box (anIndex));
+ }
+
+ const Standard_Integer aMiddle = aNodeBegPrimitive + aMinSplitIndex;
+ typedef typename BVH_QueueBuilder<T, N>::BVH_PrimitiveRange Range;
+ return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes (aMinSplitBoxLft,
+ aMinSplitBoxRgh,
+ Range (aNodeBegPrimitive, aMiddle - 1),
+ Range (aMiddle, aNodeEndPrimitive));
+ }
+
+};
#endif // _BVH_SweepPlaneBuilder_Header
+++ /dev/null
-// Created on: 2014-01-09
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <BVH_QuickSorter.hxx>
-
-#include <NCollection_Array1.hxx>
-
-// =======================================================================
-// function : BVH_SweepPlaneBuilder
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_SweepPlaneBuilder<T, N>::BVH_SweepPlaneBuilder (const Standard_Integer theLeafNodeSize,
- const Standard_Integer theMaxTreeDepth,
- const Standard_Integer theNumOfThreads)
-: BVH_QueueBuilder<T, N> (theLeafNodeSize,
- theMaxTreeDepth,
- theNumOfThreads)
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_SweepPlaneBuilder
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_SweepPlaneBuilder<T, N>::~BVH_SweepPlaneBuilder()
-{
- //
-}
-
-// =======================================================================
-// function : BuildNode
-// purpose :
-// =======================================================================
-template<class T, int N>
-typename BVH_QueueBuilder<T, N>::BVH_ChildNodes BVH_SweepPlaneBuilder<T, N>::BuildNode (BVH_Set<T, N>* theSet,
- BVH_Tree<T, N>* theBVH,
- const Standard_Integer theNode)
-{
- const Standard_Integer aNodeBegPrimitive = theBVH->BegPrimitive (theNode);
- const Standard_Integer aNodeEndPrimitive = theBVH->EndPrimitive (theNode);
- const Standard_Integer aNodeNbPrimitives = theBVH->NbPrimitives (theNode);
-
- if (aNodeEndPrimitive - aNodeBegPrimitive < BVH_Builder<T, N>::myLeafNodeSize)
- {
- return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes(); // node does not require partitioning
- }
-
- // Parameters for storing best split
- Standard_Integer aMinSplitAxis = -1;
- Standard_Integer aMinSplitIndex = 0;
-
- NCollection_Array1<Standard_Real> aLftSet (0, aNodeNbPrimitives - 1);
- NCollection_Array1<Standard_Real> aRghSet (0, aNodeNbPrimitives - 1);
-
- Standard_Real aMinSplitCost = std::numeric_limits<Standard_Real>::max();
-
- // Find best split
- for (Standard_Integer anAxis = 0; anAxis < (N < 4 ? N : 3); ++anAxis)
- {
- const T aNodeSize = BVH::VecComp<T, N>::Get (theBVH->MaxPoint (theNode), anAxis) -
- BVH::VecComp<T, N>::Get (theBVH->MinPoint (theNode), anAxis);
- if (aNodeSize <= BVH::THE_NODE_MIN_SIZE)
- {
- continue;
- }
-
- BVH_QuickSorter<T, N> (anAxis).Perform (theSet, aNodeBegPrimitive, aNodeEndPrimitive);
-
- BVH_Box<T, N> aLftBox;
- BVH_Box<T, N> aRghBox;
-
- aLftSet.ChangeFirst() = std::numeric_limits<T>::max();
- aRghSet.ChangeFirst() = std::numeric_limits<T>::max();
-
- // Sweep from left
- for (Standard_Integer anIndex = 1; anIndex < aNodeNbPrimitives; ++anIndex)
- {
- aLftBox.Combine (theSet->Box (anIndex + aNodeBegPrimitive - 1));
-
- aLftSet (anIndex) = static_cast<Standard_Real> (aLftBox.Area());
- }
-
- // Sweep from right
- for (Standard_Integer anIndex = 1; anIndex < aNodeNbPrimitives; ++anIndex)
- {
- aRghBox.Combine (theSet->Box (aNodeEndPrimitive - anIndex + 1));
-
- aRghSet (anIndex) = static_cast<Standard_Real> (aRghBox.Area());
- }
-
- // Find best split using simplified SAH
- for (Standard_Integer aNbLft = 1, aNbRgh = aNodeNbPrimitives - 1; aNbLft < aNodeNbPrimitives; ++aNbLft, --aNbRgh)
- {
- Standard_Real aCost = (aLftSet (aNbLft) /* / aNodeArea */) * aNbLft +
- (aRghSet (aNbRgh) /* / aNodeArea */) * aNbRgh;
-
- if (aCost < aMinSplitCost)
- {
- aMinSplitCost = aCost;
- aMinSplitAxis = anAxis;
- aMinSplitIndex = aNbLft;
- }
- }
- }
-
- if (aMinSplitAxis == -1)
- {
- return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes(); // failed to find split axis
- }
-
- theBVH->SetInner (theNode);
-
- if (aMinSplitAxis != (N < 4 ? N - 1 : 2))
- {
- BVH_QuickSorter<T, N> (aMinSplitAxis).Perform (theSet, aNodeBegPrimitive, aNodeEndPrimitive);
- }
-
- BVH_Box<T, N> aMinSplitBoxLft;
- BVH_Box<T, N> aMinSplitBoxRgh;
-
- // Compute bounding boxes for selected split plane
- for (Standard_Integer anIndex = aNodeBegPrimitive; anIndex < aMinSplitIndex + aNodeBegPrimitive; ++anIndex)
- {
- aMinSplitBoxLft.Combine (theSet->Box (anIndex));
- }
-
- for (Standard_Integer anIndex = aNodeEndPrimitive; anIndex >= aMinSplitIndex + aNodeBegPrimitive; --anIndex)
- {
- aMinSplitBoxRgh.Combine (theSet->Box (anIndex));
- }
-
- const Standard_Integer aMiddle = aNodeBegPrimitive + aMinSplitIndex;
-
- typedef typename BVH_QueueBuilder<T, N>::BVH_PrimitiveRange Range;
-
- return typename BVH_QueueBuilder<T, N>::BVH_ChildNodes (aMinSplitBoxLft,
- aMinSplitBoxRgh,
- Range (aNodeBegPrimitive, aMiddle - 1),
- Range (aMiddle, aNodeEndPrimitive));
-}
BVH_TreeBase() : myDepth (0) { }
//! Releases resources of BVH tree.
- virtual ~BVH_TreeBase();
+ virtual ~BVH_TreeBase() {}
//! Returns depth (height) of BVH tree.
int Depth() const
// Invalid type
};
-#include <BVH_Tree.lxx>
-
#endif // _BVH_TreeBase_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// =======================================================================
-// function : ~BVH_TreeBase
-// purpose : Releases resources of BVH tree
-// =======================================================================
-template<class T, int N>
-BVH_TreeBase<T, N>::~BVH_TreeBase()
-{
- //
-}
\ No newline at end of file
public:
//! Creates empty triangulation.
- BVH_Triangulation();
+ BVH_Triangulation() {}
//! Releases resources of triangulation.
- virtual ~BVH_Triangulation();
+ virtual ~BVH_Triangulation() {}
public:
public:
//! Returns total number of triangles.
- virtual Standard_Integer Size() const;
+ virtual Standard_Integer Size() const Standard_OVERRIDE
+ {
+ return BVH::Array<Standard_Integer, 4>::Size (Elements);
+ }
//! Returns AABB of entire set of objects.
using BVH_PrimitiveSet<T, N>::Box;
//! Returns AABB of the given triangle.
- virtual BVH_Box<T, N> Box (const Standard_Integer theIndex) const;
+ virtual BVH_Box<T, N> Box (const Standard_Integer theIndex) const Standard_OVERRIDE
+ {
+ const BVH_Vec4i& anIndex = BVH::Array<Standard_Integer, 4>::Value (Elements, theIndex);
+
+ const BVH_VecNt& aPoint0 = BVH::Array<T, N>::Value (Vertices, anIndex.x());
+ const BVH_VecNt& aPoint1 = BVH::Array<T, N>::Value (Vertices, anIndex.y());
+ const BVH_VecNt& aPoint2 = BVH::Array<T, N>::Value (Vertices, anIndex.z());
+
+ BVH_VecNt aMinPoint (aPoint0), aMaxPoint (aPoint0);
+
+ BVH::BoxMinMax<T, N>::CwiseMin (aMinPoint, aPoint1);
+ BVH::BoxMinMax<T, N>::CwiseMin (aMinPoint, aPoint2);
+ BVH::BoxMinMax<T, N>::CwiseMax (aMaxPoint, aPoint1);
+ BVH::BoxMinMax<T, N>::CwiseMax (aMaxPoint, aPoint2);
+ return BVH_Box<T, N> (aMinPoint, aMaxPoint);
+ }
//! Returns centroid position along the given axis.
virtual T Center (const Standard_Integer theIndex,
- const Standard_Integer theAxis) const;
+ const Standard_Integer theAxis) const Standard_OVERRIDE
+ {
+ const BVH_Vec4i& anIndex = BVH::Array<Standard_Integer, 4>::Value (Elements, theIndex);
+
+ const BVH_VecNt& aPoint0 = BVH::Array<T, N>::Value (Vertices, anIndex.x());
+ const BVH_VecNt& aPoint1 = BVH::Array<T, N>::Value (Vertices, anIndex.y());
+ const BVH_VecNt& aPoint2 = BVH::Array<T, N>::Value (Vertices, anIndex.z());
+ return (BVH::VecComp<T, N>::Get (aPoint0, theAxis) +
+ BVH::VecComp<T, N>::Get (aPoint1, theAxis) +
+ BVH::VecComp<T, N>::Get (aPoint2, theAxis)) * static_cast<T> (1.0 / 3.0);
+ }
//! Performs transposing the two given triangles in the set.
virtual void Swap (const Standard_Integer theIndex1,
- const Standard_Integer theIndex2);
+ const Standard_Integer theIndex2) Standard_OVERRIDE
+ {
+ BVH_Vec4i& anIndices1 = BVH::Array<Standard_Integer, 4>::ChangeValue (Elements, theIndex1);
+ BVH_Vec4i& anIndices2 = BVH::Array<Standard_Integer, 4>::ChangeValue (Elements, theIndex2);
+ std::swap (anIndices1, anIndices2);
+ }
};
-#include <BVH_Triangulation.lxx>
-
#endif // _BVH_Triangulation_Header
+++ /dev/null
-// Created on: 2013-12-20
-// Created by: Denis BOGOLEPOV
-// Copyright (c) 2013-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-// =======================================================================
-// function : BVH_Triangulation
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Triangulation<T, N>::BVH_Triangulation()
-{
- //
-}
-
-// =======================================================================
-// function : ~BVH_Triangulation
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Triangulation<T, N>::~BVH_Triangulation()
-{
- //
-}
-
-// =======================================================================
-// function : Size
-// purpose :
-// =======================================================================
-template<class T, int N>
-Standard_Integer BVH_Triangulation<T, N>::Size() const
-{
- return BVH::Array<Standard_Integer, 4>::Size (Elements);
-}
-
-// =======================================================================
-// function : Box
-// purpose :
-// =======================================================================
-template<class T, int N>
-BVH_Box<T, N> BVH_Triangulation<T, N>::Box (const Standard_Integer theIndex) const
-{
- const BVH_Vec4i& anIndex = BVH::Array<Standard_Integer, 4>::Value (Elements, theIndex);
-
- const BVH_VecNt& aPoint0 = BVH::Array<T, N>::Value (Vertices, anIndex.x());
- const BVH_VecNt& aPoint1 = BVH::Array<T, N>::Value (Vertices, anIndex.y());
- const BVH_VecNt& aPoint2 = BVH::Array<T, N>::Value (Vertices, anIndex.z());
-
- BVH_VecNt aMinPoint = aPoint0;
- BVH_VecNt aMaxPoint = aPoint0;
-
- BVH::BoxMinMax<T, N>::CwiseMin (aMinPoint, aPoint1);
- BVH::BoxMinMax<T, N>::CwiseMin (aMinPoint, aPoint2);
- BVH::BoxMinMax<T, N>::CwiseMax (aMaxPoint, aPoint1);
- BVH::BoxMinMax<T, N>::CwiseMax (aMaxPoint, aPoint2);
-
- return BVH_Box<T, N> (aMinPoint, aMaxPoint);
-}
-
-// =======================================================================
-// function : Center
-// purpose :
-// =======================================================================
-template<class T, int N>
-T BVH_Triangulation<T, N>::Center (const Standard_Integer theIndex,
- const Standard_Integer theAxis) const
-{
- const BVH_Vec4i& anIndex = BVH::Array<Standard_Integer, 4>::Value (Elements, theIndex);
-
- const BVH_VecNt& aPoint0 = BVH::Array<T, N>::Value (Vertices, anIndex.x());
- const BVH_VecNt& aPoint1 = BVH::Array<T, N>::Value (Vertices, anIndex.y());
- const BVH_VecNt& aPoint2 = BVH::Array<T, N>::Value (Vertices, anIndex.z());
-
- return ( BVH::VecComp<T, N>::Get (aPoint0, theAxis) +
- BVH::VecComp<T, N>::Get (aPoint1, theAxis) +
- BVH::VecComp<T, N>::Get (aPoint2, theAxis) ) * static_cast<T> (1.0 / 3.0);
-}
-
-// =======================================================================
-// function : Swap
-// purpose :
-// =======================================================================
-template<class T, int N>
-void BVH_Triangulation<T, N>::Swap (const Standard_Integer theIndex1,
- const Standard_Integer theIndex2)
-{
- BVH_Vec4i& anIndices1 = BVH::Array<Standard_Integer, 4>::ChangeValue (Elements, theIndex1);
- BVH_Vec4i& anIndices2 = BVH::Array<Standard_Integer, 4>::ChangeValue (Elements, theIndex2);
-
- std::swap (anIndices1, anIndices2);
-}
BVH.cxx
BVH_BinnedBuilder.hxx
-BVH_BinnedBuilder.lxx
BVH_Box.hxx
-BVH_Box.lxx
BVH_Builder.hxx
-BVH_Builder.lxx
BVH_BuildQueue.hxx
BVH_BuildQueue.cxx
BVH_BuildThread.hxx
BVH_DistanceField.hxx
BVH_DistanceField.lxx
BVH_Geometry.hxx
-BVH_Geometry.lxx
BVH_LinearBuilder.hxx
-BVH_LinearBuilder.lxx
BVH_Object.hxx
-BVH_Object.lxx
BVH_ObjectSet.hxx
-BVH_ObjectSet.lxx
BVH_PrimitiveSet.hxx
-BVH_PrimitiveSet.lxx
BVH_Properties.cxx
BVH_Properties.hxx
-BVH_Properties.lxx
BVH_QueueBuilder.hxx
-BVH_QueueBuilder.lxx
BVH_Set.hxx
-BVH_Set.lxx
BVH_Sorter.hxx
BVH_QuickSorter.hxx
-BVH_QuickSorter.lxx
BVH_RadixSorter.hxx
-BVH_RadixSorter.lxx
BVH_SpatialMedianBuilder.hxx
-BVH_SpatialMedianBuilder.lxx
BVH_SweepPlaneBuilder.hxx
-BVH_SweepPlaneBuilder.lxx
BVH_Tree.hxx
-BVH_Tree.lxx
BVH_BinaryTree.hxx
-BVH_BinaryTree.lxx
BVH_QuadTree.hxx
-BVH_QuadTree.lxx
BVH_Triangulation.hxx
-BVH_Triangulation.lxx
BVH_Types.hxx
OpenGl_BVHClipPrimitiveSet();
//! Returns total number of structures.
- virtual Standard_Integer Size() const;
+ virtual Standard_Integer Size() const Standard_OVERRIDE;
//! Returns AABB of the structure.
- virtual Graphic3d_BndBox3d Box (const Standard_Integer theIdx) const;
+ virtual Graphic3d_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
//! Calculates center of the AABB along given axis.
virtual Standard_Real Center (const Standard_Integer theIdx,
- const Standard_Integer theAxis) const;
+ const Standard_Integer theAxis) const Standard_OVERRIDE;
//! Swaps structures with the given indices.
virtual void Swap (const Standard_Integer theIdx1,
- const Standard_Integer theIdx2);
+ const Standard_Integer theIdx2) Standard_OVERRIDE;
//! Adds structure to the set.
//! @return true if structure added, otherwise returns false (structure already in the set).
}
//! Clears ray-tracing geometry.
- void Clear();
+ virtual void Clear() Standard_OVERRIDE;
public: //! @name methods related to acceleration structure