From bf9e51383997558f6a08cd68d23e90496c73ed6d Mon Sep 17 00:00:00 2001 From: Yoann Le Montagner Date: Fri, 31 Oct 2025 15:33:41 +0100 Subject: [PATCH 1/2] feat(AABBTree): allow non-parallel search queries --- include/geode/geometry/aabb.hpp | 36 +++++++++--- include/geode/geometry/detail/aabb_impl.hpp | 63 ++++++++++++++------- src/geode/geometry/aabb.cpp | 6 +- tests/geometry/test-aabb.cpp | 56 ++++++++++-------- 4 files changed, 105 insertions(+), 56 deletions(-) diff --git a/include/geode/geometry/aabb.hpp b/include/geode/geometry/aabb.hpp index 6f3232ccf..1708f4d12 100644 --- a/include/geode/geometry/aabb.hpp +++ b/include/geode/geometry/aabb.hpp @@ -73,9 +73,10 @@ namespace geode /*! * @brief Gets all the boxes containing a point * @param[in] query the point to test + * @param[in] parallel true to enable parallelization. */ [[nodiscard]] std::vector< index_t > containing_boxes( - const Point< dimension >& query ) const; + const Point< dimension >& query, bool parallel = true ) const; /*! * @brief Gets the closest element to a point @@ -106,6 +107,7 @@ namespace geode * @param[in] box the box to test * @param[in] action The functor to run when an element box intersects * \p box + * @param[in] parallel true to enable parallelization. * * @tparam EvalIntersection this functor should have an operator() * defined like this: @@ -118,11 +120,13 @@ namespace geode template < class EvalIntersection > void compute_bbox_element_bbox_intersections( const BoundingBox< dimension >& box, - EvalIntersection& action ) const; + EvalIntersection& action, + bool parallel = true ) const; /*! * @brief Computes the self intersections of the element boxes. * @param[in] action The functor to run when two boxes intersect + * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box1, index_t cur_element_box2 @@ -138,12 +142,13 @@ namespace geode */ template < class EvalIntersection > void compute_self_element_bbox_intersections( - EvalIntersection& action ) const; + EvalIntersection& action, bool parallel = true ) const; /*! * @brief Computes all the intersections of the element boxes between * this tree and another one. * @param[in] action The functor to run when two boxes intersect + * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box1, index_t cur_element_box2 @@ -156,7 +161,8 @@ namespace geode template < class EvalIntersection > void compute_other_element_bbox_intersections( const AABBTree< dimension >& other_tree, - EvalIntersection& action ) const; + EvalIntersection& action, + bool parallel = true ) const; /*! * @brief Computes the intersections between a given ray and all @@ -164,6 +170,7 @@ namespace geode * @param[in] ray The ray to test. * @param[in] action The functor to run when a box is intersected by the * ray. + * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box ) ; @@ -174,7 +181,9 @@ namespace geode */ template < class EvalIntersection > void compute_ray_element_bbox_intersections( - const Ray< dimension >& ray, EvalIntersection& action ) const; + const Ray< dimension >& ray, + EvalIntersection& action, + bool parallel = true ) const; /*! * @brief Computes the intersections between a given infinite line and @@ -182,6 +191,7 @@ namespace geode * @param[in] line The line to test. * @param[in] action The functor to run when a box is intersected by the * line. + * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box ) ; @@ -193,7 +203,8 @@ namespace geode template < class EvalIntersection > void compute_line_element_bbox_intersections( const InfiniteLine< dimension >& line, - EvalIntersection& action ) const; + EvalIntersection& action, + bool parallel = true ) const; /*! * @brief Computes the intersections between any object (for which @@ -204,6 +215,7 @@ namespace geode * either to an internal tree node or to a tree element. * @param[in] action The functor to run when a tree element box is * intersected by the search object. + * @param[in] parallel true to enable parallelization. * @tparam EvalBox this functor should have an operator() defined like * this: bool operator( const BoundingBox & ) ; * @tparam EvalIntersection this functor should have an operator() @@ -216,7 +228,9 @@ namespace geode */ template < class EvalBox, class EvalIntersection > void compute_generic_element_bbox_intersections( - const EvalBox& box_filter, EvalIntersection& action ) const; + const EvalBox& box_filter, + EvalIntersection& action, + bool parallel = true ) const; /*! * @brief Computes the intersections between a given Segment and @@ -224,6 +238,7 @@ namespace geode * @param[in] segment The segment to test. * @param[in] action The functor to run when a box is intersected by the * segment. + * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box ) ; @@ -235,7 +250,8 @@ namespace geode template < class EvalIntersection > void compute_segment_element_bbox_intersections( const Segment< dimension >& segment, - EvalIntersection& action ) const; + EvalIntersection& action, + bool parallel = true ) const; /*! * @brief Computes the intersections between a given Triangle and @@ -243,6 +259,7 @@ namespace geode * @param[in] triangle The triangle to test. * @param[in] action The functor to run when a box is intersected by the * segment. + * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box ) ; @@ -254,7 +271,8 @@ namespace geode template < class EvalIntersection > void compute_triangle_element_bbox_intersections( const Triangle< dimension >& triangle, - EvalIntersection& action ) const; + EvalIntersection& action, + bool parallel = true ) const; private: IMPLEMENTATION_MEMBER( impl_ ); diff --git a/include/geode/geometry/detail/aabb_impl.hpp b/include/geode/geometry/detail/aabb_impl.hpp index e7b310869..5ccbbe042 100644 --- a/include/geode/geometry/detail/aabb_impl.hpp +++ b/include/geode/geometry/detail/aabb_impl.hpp @@ -111,6 +111,11 @@ namespace geode return mapping_morton_.size(); } + [[nodiscard]] index_t initial_depth( bool parallel ) const + { + return parallel ? 0 : async_depth_ + 1; + } + [[nodiscard]] static bool is_leaf( index_t element_begin, index_t element_end ) { @@ -569,95 +574,115 @@ namespace geode template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_bbox_element_bbox_intersections( - const BoundingBox< dimension >& box, EvalIntersection& action ) const + const BoundingBox< dimension >& box, + EvalIntersection& action, + bool parallel ) const { const auto box_filter = [&box]( const auto& inner_box ) { return inner_box.intersects( box ); }; - compute_generic_element_bbox_intersections( box_filter, action ); + compute_generic_element_bbox_intersections( + box_filter, action, parallel ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_self_element_bbox_intersections( - EvalIntersection& action ) const + EvalIntersection& action, bool parallel ) const { if( nb_bboxes() == 0 ) { return; } - impl_->self_intersect_recursive( Impl::ROOT_INDEX, 0, nb_bboxes(), 0, - Impl::ROOT_INDEX, 0, nb_bboxes(), action ); + impl_->self_intersect_recursive( Impl::ROOT_INDEX, 0, nb_bboxes(), + impl_->initial_depth( parallel ), Impl::ROOT_INDEX, 0, nb_bboxes(), + action ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_other_element_bbox_intersections( const AABBTree< dimension >& other_tree, - EvalIntersection& action ) const + EvalIntersection& action, + bool parallel ) const { if( nb_bboxes() == 0 || other_tree.nb_bboxes() == 0 ) { return; } - impl_->other_intersect_recursive( Impl::ROOT_INDEX, 0, nb_bboxes(), 0, - other_tree, Impl::ROOT_INDEX, 0, other_tree.nb_bboxes(), action ); + impl_->other_intersect_recursive( Impl::ROOT_INDEX, 0, nb_bboxes(), + impl_->initial_depth( parallel ), other_tree, Impl::ROOT_INDEX, 0, + other_tree.nb_bboxes(), action ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_ray_element_bbox_intersections( - const Ray< dimension >& ray, EvalIntersection& action ) const + const Ray< dimension >& ray, + EvalIntersection& action, + bool parallel ) const { const auto box_filter = [&ray]( const auto& box ) { return box.intersects( ray ); }; - compute_generic_element_bbox_intersections( box_filter, action ); + compute_generic_element_bbox_intersections( + box_filter, action, parallel ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_line_element_bbox_intersections( - const InfiniteLine< dimension >& line, EvalIntersection& action ) const + const InfiniteLine< dimension >& line, + EvalIntersection& action, + bool parallel ) const { const auto box_filter = [&line]( const auto& box ) { return box.intersects( line ); }; - compute_generic_element_bbox_intersections( box_filter, action ); + compute_generic_element_bbox_intersections( + box_filter, action, parallel ); } template < index_t dimension > template < class EvalBox, class EvalIntersection > void AABBTree< dimension >::compute_generic_element_bbox_intersections( - const EvalBox& box_filter, EvalIntersection& action ) const + const EvalBox& box_filter, + EvalIntersection& action, + bool parallel ) const { if( nb_bboxes() == 0 ) { return; } - impl_->generic_intersect_recursive( - box_filter, Impl::ROOT_INDEX, 0, nb_bboxes(), 0, action ); + impl_->generic_intersect_recursive( box_filter, Impl::ROOT_INDEX, 0, + nb_bboxes(), impl_->initial_depth( parallel ), action ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_triangle_element_bbox_intersections( - const Triangle< dimension >& triangle, EvalIntersection& action ) const + const Triangle< dimension >& triangle, + EvalIntersection& action, + bool parallel ) const { const auto box_filter = [&triangle]( const auto& box ) { return box.intersects( triangle ); }; - compute_generic_element_bbox_intersections( box_filter, action ); + compute_generic_element_bbox_intersections( + box_filter, action, parallel ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_segment_element_bbox_intersections( - const Segment< dimension >& segment, EvalIntersection& action ) const + const Segment< dimension >& segment, + EvalIntersection& action, + bool parallel ) const { const auto box_filter = [&segment]( const auto& box ) { return box.intersects( segment ); }; - compute_generic_element_bbox_intersections( box_filter, action ); + compute_generic_element_bbox_intersections( + box_filter, action, parallel ); } } // namespace geode diff --git a/src/geode/geometry/aabb.cpp b/src/geode/geometry/aabb.cpp index 1e95ccbc3..edaf33eb3 100644 --- a/src/geode/geometry/aabb.cpp +++ b/src/geode/geometry/aabb.cpp @@ -76,7 +76,7 @@ namespace geode template < index_t dimension > std::vector< index_t > AABBTree< dimension >::containing_boxes( - const Point< dimension >& query ) const + const Point< dimension >& query, bool parallel ) const { if( nb_bboxes() == 0 ) { @@ -84,8 +84,8 @@ namespace geode } std::vector< index_t > result; std::mutex mutex; - impl_->containing_boxes_recursive( - Impl::ROOT_INDEX, 0, nb_bboxes(), 0, query, result, mutex ); + impl_->containing_boxes_recursive( Impl::ROOT_INDEX, 0, nb_bboxes(), + impl_->initial_depth( parallel ), query, result, mutex ); return result; } diff --git a/tests/geometry/test-aabb.cpp b/tests/geometry/test-aabb.cpp index 063e59b50..f411eaba3 100644 --- a/tests/geometry/test-aabb.cpp +++ b/tests/geometry/test-aabb.cpp @@ -209,11 +209,11 @@ class BoxAABBIntersection absl::Span< const geode::BoundingBox< dimension > > bounding_boxes_; }; -template < geode::index_t dimension > +template < geode::index_t dimension, bool parallel > void test_intersections_with_query_box() { - geode::Logger::info( - "TEST", " Box-Box intersection AABB ", dimension, "D" ); + geode::Logger::info( "TEST", " Box-Box intersection AABB ", dimension, "D ", + parallel ? "parallel" : "sequential" ); const geode::index_t nb_boxes{ 10 }; const double box_size{ 0.5 }; const auto box_vector = @@ -234,7 +234,7 @@ void test_intersections_with_query_box() eval_intersection.box_intersections_.clear(); aabb.compute_bbox_element_bbox_intersections( - box_query, eval_intersection ); + box_query, eval_intersection, parallel ); OPENGEODE_EXCEPTION( eval_intersection.box_intersections_.size() == 4, @@ -296,11 +296,11 @@ class RayAABBIntersection absl::Span< const geode::BoundingBox< dimension > > bounding_boxes_; }; -template < geode::index_t dimension > +template < geode::index_t dimension, bool parallel > void test_intersections_with_ray_trace() { - geode::Logger::info( - "TEST", " Box-Ray intersection AABB ", dimension, "D" ); + geode::Logger::info( "TEST", " Box-Ray intersection AABB ", dimension, "D ", + parallel ? "parallel" : "sequential" ); const geode::index_t nb_boxes{ 10 }; const double box_size{ 0.5 }; @@ -322,7 +322,8 @@ void test_intersections_with_ray_trace() geode::Ray< dimension > query{ ray_direction, ray_origin }; eval_intersection.box_intersections_.clear(); - aabb.compute_ray_element_bbox_intersections( query, eval_intersection ); + aabb.compute_ray_element_bbox_intersections( + query, eval_intersection, parallel ); OPENGEODE_EXCEPTION( eval_intersection.box_intersections_.size() == nb_boxes - i, @@ -396,11 +397,11 @@ void test_intersections_with_ray_trace() "[Test] Box-Ray intersection - Wrong set of boxes" ); } -template < geode::index_t dimension > +template < geode::index_t dimension, bool parallel > void test_self_intersections() { - geode::Logger::info( - "TEST", " Box self intersection AABB ", dimension, "D" ); + geode::Logger::info( "TEST", " Box self intersection AABB ", dimension, + "D ", parallel ? "parallel" : "sequential" ); const geode::index_t nb_boxes{ 10 }; // Create a grid of intersecting boxes @@ -414,7 +415,7 @@ void test_self_intersections() BoxAABBIntersection< dimension > eval_intersection{ box_vector }; // investigate box inclusions eval_intersection.included_box_.clear(); - aabb.compute_self_element_bbox_intersections( eval_intersection ); + aabb.compute_self_element_bbox_intersections( eval_intersection, parallel ); OPENGEODE_EXCEPTION( eval_intersection.included_box_.size() == nb_boxes * nb_boxes, @@ -445,18 +446,18 @@ class OtherAABBIntersection std::mutex mutex_; }; -template < geode::index_t dimension > +template < geode::index_t dimension, bool parallel > void test_other_intersections() { - geode::Logger::info( - "TEST", " Box other intersection AABB ", dimension, "D" ); + geode::Logger::info( "TEST", " Box other intersection AABB ", dimension, + "D ", parallel ? "parallel" : "sequential" ); const geode::AABBTree< dimension > aabb{ create_box_vector< dimension >( 5, 0.2 ) }; const geode::AABBTree< dimension > other{ create_box_vector< dimension >( 2, 0.4 ) }; OtherAABBIntersection< dimension > action; - aabb.compute_other_element_bbox_intersections( other, action ); + aabb.compute_other_element_bbox_intersections( other, action, parallel ); absl::flat_hash_map< geode::index_t, geode::index_t > answer{ { 0, 0 }, { 1, 1 }, { 5, 2 }, { 6, 3 } }; @@ -467,21 +468,26 @@ void test_other_intersections() } } -template < geode::index_t dimension > +template < geode::index_t dimension, bool parallel > void do_test() { - test_build_aabb< dimension >(); - test_nearest_neighbor_search< dimension >(); - test_intersections_with_query_box< dimension >(); - test_intersections_with_ray_trace< dimension >(); - test_self_intersections< dimension >(); - test_other_intersections< dimension >(); + if( !parallel ) + { + test_build_aabb< dimension >(); + test_nearest_neighbor_search< dimension >(); + } + test_intersections_with_query_box< dimension, parallel >(); + test_intersections_with_ray_trace< dimension, parallel >(); + test_self_intersections< dimension, parallel >(); + test_other_intersections< dimension, parallel >(); } void test() { - do_test< 2 >(); - do_test< 3 >(); + do_test< 2, false >(); + do_test< 3, false >(); + do_test< 2, true >(); + do_test< 3, true >(); } OPENGEODE_TEST( "aabb" ) From 1a5b72a073300dc3a7d9bf4c0e3b86453e47eef4 Mon Sep 17 00:00:00 2001 From: Yoann Le Montagner Date: Mon, 3 Nov 2025 11:03:32 +0100 Subject: [PATCH 2/2] Impl parallel/sequential switch as an option of each AABBTree instance --- include/geode/geometry/aabb.hpp | 47 +++++++-------- include/geode/geometry/detail/aabb_impl.hpp | 66 +++++++++------------ src/geode/geometry/aabb.cpp | 16 ++++- tests/geometry/test-aabb.cpp | 23 ++++--- 4 files changed, 77 insertions(+), 75 deletions(-) diff --git a/include/geode/geometry/aabb.hpp b/include/geode/geometry/aabb.hpp index 1708f4d12..a242c2132 100644 --- a/include/geode/geometry/aabb.hpp +++ b/include/geode/geometry/aabb.hpp @@ -70,13 +70,23 @@ namespace geode [[nodiscard]] const BoundingBox< dimension >& bounding_box() const; + /*! + * @brief Whether or not the queries run on this tree are parallelized. + */ + [[nodiscard]] bool parallel() const; + + /*! + * @brief Sets whether or not the queries run on this tree are + * parallelized. + */ + void set_parallel( bool parallel ); + /*! * @brief Gets all the boxes containing a point * @param[in] query the point to test - * @param[in] parallel true to enable parallelization. */ [[nodiscard]] std::vector< index_t > containing_boxes( - const Point< dimension >& query, bool parallel = true ) const; + const Point< dimension >& query ) const; /*! * @brief Gets the closest element to a point @@ -107,7 +117,6 @@ namespace geode * @param[in] box the box to test * @param[in] action The functor to run when an element box intersects * \p box - * @param[in] parallel true to enable parallelization. * * @tparam EvalIntersection this functor should have an operator() * defined like this: @@ -120,13 +129,11 @@ namespace geode template < class EvalIntersection > void compute_bbox_element_bbox_intersections( const BoundingBox< dimension >& box, - EvalIntersection& action, - bool parallel = true ) const; + EvalIntersection& action ) const; /*! * @brief Computes the self intersections of the element boxes. * @param[in] action The functor to run when two boxes intersect - * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box1, index_t cur_element_box2 @@ -142,13 +149,12 @@ namespace geode */ template < class EvalIntersection > void compute_self_element_bbox_intersections( - EvalIntersection& action, bool parallel = true ) const; + EvalIntersection& action ) const; /*! * @brief Computes all the intersections of the element boxes between * this tree and another one. * @param[in] action The functor to run when two boxes intersect - * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box1, index_t cur_element_box2 @@ -161,8 +167,7 @@ namespace geode template < class EvalIntersection > void compute_other_element_bbox_intersections( const AABBTree< dimension >& other_tree, - EvalIntersection& action, - bool parallel = true ) const; + EvalIntersection& action ) const; /*! * @brief Computes the intersections between a given ray and all @@ -170,7 +175,6 @@ namespace geode * @param[in] ray The ray to test. * @param[in] action The functor to run when a box is intersected by the * ray. - * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box ) ; @@ -181,9 +185,7 @@ namespace geode */ template < class EvalIntersection > void compute_ray_element_bbox_intersections( - const Ray< dimension >& ray, - EvalIntersection& action, - bool parallel = true ) const; + const Ray< dimension >& ray, EvalIntersection& action ) const; /*! * @brief Computes the intersections between a given infinite line and @@ -191,7 +193,6 @@ namespace geode * @param[in] line The line to test. * @param[in] action The functor to run when a box is intersected by the * line. - * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box ) ; @@ -203,8 +204,7 @@ namespace geode template < class EvalIntersection > void compute_line_element_bbox_intersections( const InfiniteLine< dimension >& line, - EvalIntersection& action, - bool parallel = true ) const; + EvalIntersection& action ) const; /*! * @brief Computes the intersections between any object (for which @@ -215,7 +215,6 @@ namespace geode * either to an internal tree node or to a tree element. * @param[in] action The functor to run when a tree element box is * intersected by the search object. - * @param[in] parallel true to enable parallelization. * @tparam EvalBox this functor should have an operator() defined like * this: bool operator( const BoundingBox & ) ; * @tparam EvalIntersection this functor should have an operator() @@ -228,9 +227,7 @@ namespace geode */ template < class EvalBox, class EvalIntersection > void compute_generic_element_bbox_intersections( - const EvalBox& box_filter, - EvalIntersection& action, - bool parallel = true ) const; + const EvalBox& box_filter, EvalIntersection& action ) const; /*! * @brief Computes the intersections between a given Segment and @@ -238,7 +235,6 @@ namespace geode * @param[in] segment The segment to test. * @param[in] action The functor to run when a box is intersected by the * segment. - * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box ) ; @@ -250,8 +246,7 @@ namespace geode template < class EvalIntersection > void compute_segment_element_bbox_intersections( const Segment< dimension >& segment, - EvalIntersection& action, - bool parallel = true ) const; + EvalIntersection& action ) const; /*! * @brief Computes the intersections between a given Triangle and @@ -259,7 +254,6 @@ namespace geode * @param[in] triangle The triangle to test. * @param[in] action The functor to run when a box is intersected by the * segment. - * @param[in] parallel true to enable parallelization. * @tparam EvalIntersection this functor should have an operator() * defined like this: * bool operator()( index_t cur_element_box ) ; @@ -271,8 +265,7 @@ namespace geode template < class EvalIntersection > void compute_triangle_element_bbox_intersections( const Triangle< dimension >& triangle, - EvalIntersection& action, - bool parallel = true ) const; + EvalIntersection& action ) const; private: IMPLEMENTATION_MEMBER( impl_ ); diff --git a/include/geode/geometry/detail/aabb_impl.hpp b/include/geode/geometry/detail/aabb_impl.hpp index 5ccbbe042..aa9781300 100644 --- a/include/geode/geometry/detail/aabb_impl.hpp +++ b/include/geode/geometry/detail/aabb_impl.hpp @@ -111,9 +111,19 @@ namespace geode return mapping_morton_.size(); } - [[nodiscard]] index_t initial_depth( bool parallel ) const + [[nodiscard]] bool parallel() const { - return parallel ? 0 : async_depth_ + 1; + return parallel_; + } + + void set_parallel( bool parallel ) + { + parallel_ = parallel; + } + + [[nodiscard]] index_t initial_depth() const + { + return parallel_ ? 0 : async_depth_ + 1; } [[nodiscard]] static bool is_leaf( @@ -552,6 +562,7 @@ namespace geode std::vector< index_t > mapping_morton_; index_t depth_{ 1 }; index_t async_depth_{ 0 }; + bool parallel_{ true }; }; template < index_t dimension > @@ -574,115 +585,96 @@ namespace geode template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_bbox_element_bbox_intersections( - const BoundingBox< dimension >& box, - EvalIntersection& action, - bool parallel ) const + const BoundingBox< dimension >& box, EvalIntersection& action ) const { const auto box_filter = [&box]( const auto& inner_box ) { return inner_box.intersects( box ); }; - compute_generic_element_bbox_intersections( - box_filter, action, parallel ); + compute_generic_element_bbox_intersections( box_filter, action ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_self_element_bbox_intersections( - EvalIntersection& action, bool parallel ) const + EvalIntersection& action ) const { if( nb_bboxes() == 0 ) { return; } impl_->self_intersect_recursive( Impl::ROOT_INDEX, 0, nb_bboxes(), - impl_->initial_depth( parallel ), Impl::ROOT_INDEX, 0, nb_bboxes(), - action ); + impl_->initial_depth(), Impl::ROOT_INDEX, 0, nb_bboxes(), action ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_other_element_bbox_intersections( const AABBTree< dimension >& other_tree, - EvalIntersection& action, - bool parallel ) const + EvalIntersection& action ) const { if( nb_bboxes() == 0 || other_tree.nb_bboxes() == 0 ) { return; } impl_->other_intersect_recursive( Impl::ROOT_INDEX, 0, nb_bboxes(), - impl_->initial_depth( parallel ), other_tree, Impl::ROOT_INDEX, 0, + impl_->initial_depth(), other_tree, Impl::ROOT_INDEX, 0, other_tree.nb_bboxes(), action ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_ray_element_bbox_intersections( - const Ray< dimension >& ray, - EvalIntersection& action, - bool parallel ) const + const Ray< dimension >& ray, EvalIntersection& action ) const { const auto box_filter = [&ray]( const auto& box ) { return box.intersects( ray ); }; - compute_generic_element_bbox_intersections( - box_filter, action, parallel ); + compute_generic_element_bbox_intersections( box_filter, action ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_line_element_bbox_intersections( - const InfiniteLine< dimension >& line, - EvalIntersection& action, - bool parallel ) const + const InfiniteLine< dimension >& line, EvalIntersection& action ) const { const auto box_filter = [&line]( const auto& box ) { return box.intersects( line ); }; - compute_generic_element_bbox_intersections( - box_filter, action, parallel ); + compute_generic_element_bbox_intersections( box_filter, action ); } template < index_t dimension > template < class EvalBox, class EvalIntersection > void AABBTree< dimension >::compute_generic_element_bbox_intersections( - const EvalBox& box_filter, - EvalIntersection& action, - bool parallel ) const + const EvalBox& box_filter, EvalIntersection& action ) const { if( nb_bboxes() == 0 ) { return; } impl_->generic_intersect_recursive( box_filter, Impl::ROOT_INDEX, 0, - nb_bboxes(), impl_->initial_depth( parallel ), action ); + nb_bboxes(), impl_->initial_depth(), action ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_triangle_element_bbox_intersections( - const Triangle< dimension >& triangle, - EvalIntersection& action, - bool parallel ) const + const Triangle< dimension >& triangle, EvalIntersection& action ) const { const auto box_filter = [&triangle]( const auto& box ) { return box.intersects( triangle ); }; - compute_generic_element_bbox_intersections( - box_filter, action, parallel ); + compute_generic_element_bbox_intersections( box_filter, action ); } template < index_t dimension > template < class EvalIntersection > void AABBTree< dimension >::compute_segment_element_bbox_intersections( - const Segment< dimension >& segment, - EvalIntersection& action, - bool parallel ) const + const Segment< dimension >& segment, EvalIntersection& action ) const { const auto box_filter = [&segment]( const auto& box ) { return box.intersects( segment ); }; - compute_generic_element_bbox_intersections( - box_filter, action, parallel ); + compute_generic_element_bbox_intersections( box_filter, action ); } } // namespace geode diff --git a/src/geode/geometry/aabb.cpp b/src/geode/geometry/aabb.cpp index edaf33eb3..bbe6f5b55 100644 --- a/src/geode/geometry/aabb.cpp +++ b/src/geode/geometry/aabb.cpp @@ -74,9 +74,21 @@ namespace geode return impl_->node( Impl::ROOT_INDEX ); } + template < index_t dimension > + bool AABBTree< dimension >::parallel() const + { + return impl_->parallel(); + } + + template < index_t dimension > + void AABBTree< dimension >::set_parallel( bool parallel ) + { + impl_->set_parallel( parallel ); + } + template < index_t dimension > std::vector< index_t > AABBTree< dimension >::containing_boxes( - const Point< dimension >& query, bool parallel ) const + const Point< dimension >& query ) const { if( nb_bboxes() == 0 ) { @@ -85,7 +97,7 @@ namespace geode std::vector< index_t > result; std::mutex mutex; impl_->containing_boxes_recursive( Impl::ROOT_INDEX, 0, nb_bboxes(), - impl_->initial_depth( parallel ), query, result, mutex ); + impl_->initial_depth(), query, result, mutex ); return result; } diff --git a/tests/geometry/test-aabb.cpp b/tests/geometry/test-aabb.cpp index f411eaba3..a6831a4a9 100644 --- a/tests/geometry/test-aabb.cpp +++ b/tests/geometry/test-aabb.cpp @@ -218,7 +218,8 @@ void test_intersections_with_query_box() const double box_size{ 0.5 }; const auto box_vector = create_box_vector< dimension >( nb_boxes, box_size ); - const geode::AABBTree< dimension > aabb{ box_vector }; + geode::AABBTree< dimension > aabb{ box_vector }; + aabb.set_parallel( parallel ); BoxAABBIntersection< dimension > eval_intersection{ box_vector }; @@ -234,7 +235,7 @@ void test_intersections_with_query_box() eval_intersection.box_intersections_.clear(); aabb.compute_bbox_element_bbox_intersections( - box_query, eval_intersection, parallel ); + box_query, eval_intersection ); OPENGEODE_EXCEPTION( eval_intersection.box_intersections_.size() == 4, @@ -306,7 +307,8 @@ void test_intersections_with_ray_trace() const double box_size{ 0.5 }; const auto box_vector = create_box_vector< dimension >( nb_boxes, box_size ); - const geode::AABBTree< dimension > aabb{ box_vector }; + geode::AABBTree< dimension > aabb{ box_vector }; + aabb.set_parallel( parallel ); RayAABBIntersection< dimension > eval_intersection{ box_vector }; @@ -322,8 +324,7 @@ void test_intersections_with_ray_trace() geode::Ray< dimension > query{ ray_direction, ray_origin }; eval_intersection.box_intersections_.clear(); - aabb.compute_ray_element_bbox_intersections( - query, eval_intersection, parallel ); + aabb.compute_ray_element_bbox_intersections( query, eval_intersection ); OPENGEODE_EXCEPTION( eval_intersection.box_intersections_.size() == nb_boxes - i, @@ -411,11 +412,13 @@ void test_self_intersections() box_vector.insert( box_vector.end(), box_vector2.begin(), box_vector2.end() ); - const geode::AABBTree< dimension > aabb{ box_vector }; + geode::AABBTree< dimension > aabb{ box_vector }; + aabb.set_parallel( parallel ); + BoxAABBIntersection< dimension > eval_intersection{ box_vector }; // investigate box inclusions eval_intersection.included_box_.clear(); - aabb.compute_self_element_bbox_intersections( eval_intersection, parallel ); + aabb.compute_self_element_bbox_intersections( eval_intersection ); OPENGEODE_EXCEPTION( eval_intersection.included_box_.size() == nb_boxes * nb_boxes, @@ -452,12 +455,14 @@ void test_other_intersections() geode::Logger::info( "TEST", " Box other intersection AABB ", dimension, "D ", parallel ? "parallel" : "sequential" ); - const geode::AABBTree< dimension > aabb{ create_box_vector< dimension >( + geode::AABBTree< dimension > aabb{ create_box_vector< dimension >( 5, 0.2 ) }; + aabb.set_parallel( parallel ); + const geode::AABBTree< dimension > other{ create_box_vector< dimension >( 2, 0.4 ) }; OtherAABBIntersection< dimension > action; - aabb.compute_other_element_bbox_intersections( other, action, parallel ); + aabb.compute_other_element_bbox_intersections( other, action ); absl::flat_hash_map< geode::index_t, geode::index_t > answer{ { 0, 0 }, { 1, 1 }, { 5, 2 }, { 6, 3 } };