12 #ifndef EBGeometry_BVH
13 #define EBGeometry_BVH
48 template <
class T,
class P,
class BV,
size_t K>
56 template <
class T,
class P,
class BV,
size_t K>
64 template <
class T,
class P,
class BV,
size_t K>
77 template <
class P,
class BV>
78 using PrimAndBV = std::pair<std::shared_ptr<const P>, BV>;
84 template <
class P,
class BV>
93 template <
class P,
class BV,
size_t K>
104 template <
class T,
class P,
class BV,
size_t K>
121 template <
class NodeType,
class Meta>
122 using Visiter = std::function<bool(
const NodeType& a_node,
const Meta& a_meta)>;
130 template <
class NodeType,
class Meta,
size_t K>
131 using Sorter = std::function<void(std::array<std::pair<std::shared_ptr<const NodeType>, Meta>, K>& a_children)>;
136 template <
class NodeType,
class Meta>
142 template <
class X,
size_t K>
143 auto equalCounts = [](
const std::vector<X>& a_primitives) noexcept -> std::array<std::vector<X>, K> {
144 int length = a_primitives.size() / K;
145 int remain = a_primitives.size() % K;
150 std::array<std::vector<X>, K> chunks;
152 for (
size_t k = 0; k < K; k++) {
156 chunks[k] = std::vector<X>(a_primitives.begin() + begin, a_primitives.begin() + end);
168 template <
class T,
class P,
class BV,
size_t K>
174 for (
const auto& pbv : a_primsAndBVs) {
175 lo =
min(lo, pbv.first->getCentroid());
176 hi =
max(hi, pbv.first->getCentroid());
179 const size_t splitDir = (hi - lo).maxDir(
true);
184 std::sort(sortedPrimsAndBVs.begin(),
185 sortedPrimsAndBVs.end(),
187 return pbv1.first->getCentroid(splitDir) < pbv2.first->getCentroid(splitDir);
190 return BVH::equalCounts<PrimAndBV<P, BV>, K>(sortedPrimsAndBVs);
197 template <
class T,
class P,
class BV,
size_t K>
202 for (
const auto& pbv : a_primsAndBVs) {
203 lo =
min(lo, pbv.second.getCentroid());
204 hi =
max(hi, pbv.second.getCentroid());
207 const size_t splitDir = (hi - lo).maxDir(
true);
212 std::sort(sortedPrimsAndBVs.begin(),
213 sortedPrimsAndBVs.end(),
215 return pbv1.second.getCentroid()[splitDir] < pbv2.second.getCentroid()[splitDir];
218 return BVH::equalCounts<PrimAndBV<P, BV>, K>(sortedPrimsAndBVs);
225 template <
class T,
class P,
class BV,
size_t K>
236 template <
class T,
class P,
class BV,
size_t K>
237 class NodeT :
public std::enable_shared_from_this<NodeT<T, P, BV, K>>
307 template <typename S>
341 inline const std::vector<BV>&
357 inline const std::array<std::shared_ptr<
NodeT<T, P, BV, K>>, K>&
368 template <class Meta>
381 inline std::shared_ptr<
LinearBVH<T, P, BV, K>>
421 inline std::vector<BV>&
430 setChildren(const std::array<std::shared_ptr<
NodeT<T, P, BV, K>>, K>& a_children) noexcept;
446 std::vector<std::shared_ptr<const P>>& a_sortedPrimitives,
447 size_t& a_offset) const noexcept;
480 template <class T, class P, class BV,
size_t K>
504 setBoundingVolume(const BV& a_boundingVolume) noexcept;
510 setPrimitivesOffset(const
size_t a_primitivesOffset) noexcept;
517 setNumPrimitives(const
size_t a_numPrimitives) noexcept;
525 setChildOffset(const
size_t a_childOffset, const
size_t a_whichChild) noexcept;
539 getPrimitivesOffset() const noexcept;
546 getNumPrimitives() const noexcept;
552 inline const std::array<
size_t, K>&
553 getChildOffsets() const noexcept;
582 inline std::vector<T>
583 getDistances(const
Vec3& a_point, const std::vector<std::shared_ptr<const P>>& a_primitives) const noexcept;
599 size_t m_primitivesOffset;
604 size_t m_numPrimitives;
609 std::array<
size_t, K> m_childOffsets;
615 template <class T, class P, class BV,
size_t K>
650 const std::vector<std::shared_ptr<const P>>& a_primitives);
658 const std::vector<std::shared_ptr<const P>>& a_primitives);
679 template <class Meta>
690 std::vector<std::shared_ptr<const
LinearNodeT<T, P, BV, K>>> m_linearNodes;
700 #include "EBGeometry_NamespaceFooter.hpp"
702 #include "EBGeometry_BVHImplem.hpp"
Declaration of various space-filling curves.
Declaration of 2D and 3D point/vector classes with templated precision. Used with DCEL tools.
Vec2T< T > max(const Vec2T< T > &u, const Vec2T< T > &v) noexcept
Maximum function. Returns new vector with component-wise minimums.
T length(const Vec2T< T > &v) noexcept
Length function.
Vec2T< T > min(const Vec2T< T > &u, const Vec2T< T > &v) noexcept
Minimum function. Returns new vector with component-wise minimums.
Forward declare linear BVH class.
Definition: EBGeometry_BVH.hpp:617
LinearBVH()=default
Disallowed. Use the full constructor please.
LinearBVH(const LinearBVH &)=default
Copy constructor.
const BV & getBoundingVolume() const noexcept
Get the bounding volume for this BVH.
std::vector< std::shared_ptr< const P > > PrimitiveList
Alias for list of primitives.
Definition: EBGeometry_BVH.hpp:632
virtual ~LinearBVH()
Destructor. Does nothing.
LinearBVH(const std::vector< std::shared_ptr< const LinearNodeT< T, P, BV, K >>> &a_linearNodes, const std::vector< std::shared_ptr< const P >> &a_primitives)
Full constructor. Associates the nodes and primitives.
LinearBVH(const std::vector< std::shared_ptr< LinearNodeT< T, P, BV, K >>> &a_linearNodes, const std::vector< std::shared_ptr< const P >> &a_primitives)
Full constructor. Associates the nodes and primitives.
Forward declare linear node class.
Definition: EBGeometry_BVH.hpp:482
LinearNodeT() noexcept
Constructor.
Forward declare the BVH node since it is needed for the polymorphic lambdas.
Definition: EBGeometry_BVH.hpp:238
std::shared_ptr< Node > NodePtr
Alias for node type pointer.
Definition: EBGeometry_BVH.hpp:258
PrimitiveListT< P > PrimitiveList
Alias for list of primitives.
Definition: EBGeometry_BVH.hpp:243
std::vector< std::shared_ptr< const P > > m_primitives
Primitives list. This will be empty for regular nodes.
Definition: EBGeometry_BVH.hpp:398
const std::vector< BV > & getBoundingVolumes() const noexcept
Get the bounding volumes for the primitives in this node (can be empty if regular node)
void setChildren(const std::array< std::shared_ptr< NodeT< T, P, BV, K >>, K > &a_children) noexcept
Explicitly set this node's children.
const BV & getBoundingVolume() const noexcept
Get bounding volume.
std::shared_ptr< LinearBVH< T, P, BV, K > > flattenTree() const noexcept
Flatten everything beneath this node into a depth-first sorted BVH hierarchy.
bool isLeaf() const noexcept
Get node type.
bool m_partitioned
Determines whether or not the partitioning function has already been called.
Definition: EBGeometry_BVH.hpp:393
NodeT() noexcept
Default constructor which sets a regular node.
BV m_boundingVolume
Bounding volume object for enclosing everything in this node.
Definition: EBGeometry_BVH.hpp:388
const PrimitiveList & getPrimitives() const noexcept
Get the primitives stored in this node.
T getDistanceToBoundingVolume(const Vec3 &a_point) const noexcept
Get the distance from a 3D point to the bounding volume.
void topDownSortAndPartition(const Partitioner &a_partitioner=BVCentroidPartitioner< T, P, BV, K >, const StopFunction &a_stopCrit=DefaultStopFunction< T, P, BV, K >) noexcept
Function for using top-down construction of the bounding volume hierarchy.
std::vector< BV > m_boundingVolumes
List of bounding volumes for the primitives. This will be empty for regular nodes.
Definition: EBGeometry_BVH.hpp:403
PartitionerT< P, BV, K > Partitioner
Alias for partitioner.
Definition: EBGeometry_BVH.hpp:263
bool isPartitioned() const noexcept
Check if BVH is already partitioned.
void bottomUpSortAndPartition() noexcept
Function for doing bottom-up construction using a specified space-filling curve.
StopFunctionT< T, P, BV, K > StopFunction
Alias for stop function.
Definition: EBGeometry_BVH.hpp:268
const std::array< std::shared_ptr< NodeT< T, P, BV, K > >, K > & getChildren() const noexcept
Return this node's children.
void traverse(const BVH::Updater< P > &a_updater, const BVH::Visiter< Node, Meta > &a_visiter, const BVH::Sorter< Node, Meta, K > &a_sorter, const BVH::MetaUpdater< Node, Meta > &a_metaUpdater) const noexcept
Recursion-less BVH traversal algorithm. The user inputs the update rule, a pruning criterion,...
std::array< std::shared_ptr< NodeT< T, P, BV, K > >, K > m_children
Children nodes.
Definition: EBGeometry_BVH.hpp:408
Three-dimensional vector class with arithmetic operators.
Definition: EBGeometry_Vec.hpp:218
static constexpr Vec3T< T > max() noexcept
Return a vector with maximum representable components.
Namespace for various bounding volume hierarchy (BVH) functionality.
Definition: EBGeometry_BVH.hpp:30
std::vector< PrimAndBV< P, BV > > PrimAndBVListT
List of primitives and their bounding volumes.
Definition: EBGeometry_BVH.hpp:85
auto DefaultStopFunction
Simple stop function which ends the recursion when there aren't enough primitives in the node.
Definition: EBGeometry_BVH.hpp:226
std::pair< std::shared_ptr< const P >, BV > PrimAndBV
Alias for a list geometric primitive and BV.
Definition: EBGeometry_BVH.hpp:78
auto BVCentroidPartitioner
Simple partitioner which sorts the BVs based on their bounding volume centroids, and then splits into...
Definition: EBGeometry_BVH.hpp:198
Build
Enum for specifying whether or not the construction is top-down or bottom-up.
Definition: EBGeometry_BVH.hpp:36
std::function< bool(const NodeType &a_node, const Meta &a_meta)> Visiter
Visiter pattern for LinearBVH::traverse. Must return true if we should visit the node and false other...
Definition: EBGeometry_BVH.hpp:122
std::function< void(const PrimitiveListT< P > &a_primitives)> Updater
Updater for tree traversal.
Definition: EBGeometry_BVH.hpp:112
std::function< void(std::array< std::pair< std::shared_ptr< const NodeType >, Meta >, K > &a_children)> Sorter
Sorting criterion for which child node to visit first. This takes an input list of child nodes and so...
Definition: EBGeometry_BVH.hpp:131
std::vector< std::shared_ptr< const P > > PrimitiveListT
List of primitives.
Definition: EBGeometry_BVH.hpp:72
auto PrimitiveCentroidPartitioner
Simple partitioner which sorts the primitives based on their centroids, and then splits into K pieces...
Definition: EBGeometry_BVH.hpp:169
std::function< Meta(const NodeType &a_node)> MetaUpdater
Updater for when user wants to add some meta-data to his BVH traversal.
Definition: EBGeometry_BVH.hpp:137
std::function< std::array< PrimAndBVListT< P, BV >, K >(const PrimAndBVListT< P, BV > &a_primsAndBVs)> PartitionerT
Polymorphic partitioner for splitting a list of primitives and BVs into K new subsets.
Definition: EBGeometry_BVH.hpp:94
std::function< bool(const NodeT< T, P, BV, K > &a_node)> StopFunctionT
Stop function for deciding when a BVH node can't be divided into sub-volumes.
Definition: EBGeometry_BVH.hpp:105
auto equalCounts
Function for splitting a vector of some size into K almost-equal chunks. This is a utility function.
Definition: EBGeometry_BVH.hpp:143