add the possibility to pass custom functors to build the tree

This commit is contained in:
Sébastien Loriot 2020-04-23 16:13:32 +02:00
parent 0c98cd8eee
commit f56cd59eb4
2 changed files with 33 additions and 10 deletions

View File

@ -137,6 +137,13 @@ namespace CGAL {
void build(T&& ...);
#ifndef DOXYGEN_RUNNING
void build();
/// triggers the (re)construction of the tree similarly to a call to `build()`
/// but the traits functors `Compute_bbox` and `Split_primitives` are ignored
/// and `compute_bbox` and `split_primitives` are used instead.
template <class ComputeBbox, class SplitPrimitives>
void custom_build(const ComputeBbox& compute_bbox,
const SplitPrimitives& split_primitives);
#endif
///@}
@ -697,9 +704,19 @@ public:
#endif
}
// Build the data structure, after calls to insert(..)
template<typename Tr>
void AABB_tree<Tr>::build()
{
custom_build(m_traits.compute_bbox_object(),
m_traits.split_primitives_object());
}
// Build the data structure, after calls to insert(..)
template<typename Tr>
template <class ComputeBbox, class SplitPrimitives>
void AABB_tree<Tr>::custom_build(
const ComputeBbox& compute_bbox,
const SplitPrimitives& split_primitives)
{
clear_nodes();
if(m_primitives.size() > 1) {
@ -716,7 +733,10 @@ public:
// constructs the tree
m_p_root_node->expand(m_primitives.begin(), m_primitives.end(),
m_primitives.size(), m_traits);
m_primitives.size(),
compute_bbox,
split_primitives,
m_traits);
}
#ifdef CGAL_HAS_THREADS
m_atomic_need_build.store(false, std::memory_order_release); // in case build() is triggered by a call to root_node()

View File

@ -56,10 +56,12 @@ public:
*
* [first,last[ is the range of primitives to be added to the tree.
*/
template<typename ConstPrimitiveIterator>
template<typename ConstPrimitiveIterator, typename ComputeBbox, typename SplitPrimitives>
void expand(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
const std::size_t range,
const ComputeBbox& compute_bbox,
const SplitPrimitives& split_primitives,
const AABBTraits&);
/**
@ -117,19 +119,20 @@ private:
}; // end class AABB_node
template<typename Tr>
template<typename ConstPrimitiveIterator>
template<typename ConstPrimitiveIterator, typename ComputeBbox, typename SplitPrimitives>
void
AABB_node<Tr>::expand(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
const std::size_t range,
const ComputeBbox& compute_bbox,
const SplitPrimitives& split_primitives,
const Tr& traits)
{
m_bbox = traits.compute_bbox_object()(first, beyond);
m_bbox = compute_bbox(first, beyond);
// sort primitives along longest axis aabb
traits.split_primitives_object()(first, beyond, m_bbox);
split_primitives(first, beyond, m_bbox);
switch(range)
{
@ -140,14 +143,14 @@ AABB_node<Tr>::expand(ConstPrimitiveIterator first,
case 3:
m_p_left_child = &(*first);
m_p_right_child = static_cast<Node*>(this)+1;
right_child().expand(first+1, beyond, 2,traits);
right_child().expand(first+1, beyond, 2, compute_bbox, split_primitives, traits);
break;
default:
const std::size_t new_range = range/2;
m_p_left_child = static_cast<Node*>(this) + 1;
m_p_right_child = static_cast<Node*>(this) + new_range;
left_child().expand(first, first + new_range, new_range,traits);
right_child().expand(first + new_range, beyond, range - new_range,traits);
left_child().expand(first, first + new_range, new_range, compute_bbox, split_primitives, traits);
right_child().expand(first + new_range, beyond, range - new_range, compute_bbox, split_primitives, traits);
}
}