diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 0fe6f6bf5de..d2ed637719f 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -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 + 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 void AABB_tree::build() + { + custom_build(m_traits.compute_bbox_object(), + m_traits.split_primitives_object()); + } + + // Build the data structure, after calls to insert(..) + template + template + void AABB_tree::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() diff --git a/AABB_tree/include/CGAL/internal/AABB_tree/AABB_node.h b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_node.h index 3844166ed50..6fcfef9ede8 100644 --- a/AABB_tree/include/CGAL/internal/AABB_tree/AABB_node.h +++ b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_node.h @@ -56,10 +56,12 @@ public: * * [first,last[ is the range of primitives to be added to the tree. */ - template + template 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 -template +template void AABB_node::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::expand(ConstPrimitiveIterator first, case 3: m_p_left_child = &(*first); m_p_right_child = static_cast(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(this) + 1; m_p_right_child = static_cast(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); } }