// Copyright (c) 2008,2011 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // // $URL: https://github.com/CGAL/cgal/blob/v5.1/AABB_tree/include/CGAL/AABB_tree.h $ // $Id: AABB_tree.h 1379710 2020-04-29T17:02:48+02:00 Sébastien Loriot // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Camille Wormser, Pierre Alliez, Stephane Tayeb #ifndef CGAL_AABB_TREE_H #define CGAL_AABB_TREE_H #include #include #include #include #include #include #include #include #include #include #include #ifdef CGAL_HAS_THREADS #include #endif /// \file AABB_tree.h namespace CGAL { /// \addtogroup PkgAABBTreeRef /// @{ /** * Static data structure for efficient * intersection and distance computations in 3D. It builds a * hierarchy of axis-aligned bounding boxes (an AABB tree) from a set * of 3D geometric objects, and can receive intersection and distance * queries, provided that the corresponding predicates are * implemented in the traits class AABBTraits. * An instance of the class `AABBTraits` is internally stored. * * \sa `AABBTraits` * \sa `AABBPrimitive` * */ template class AABB_tree { private: // internal KD-tree used to accelerate the distance queries typedef AABB_search_tree Search_tree; // type of the primitives container typedef std::vector Primitives; typedef internal::Primitive_helper Helper; public: typedef AABBTraits AABB_traits; /// \name Types ///@{ /// Number type returned by the distance queries. typedef typename AABBTraits::FT FT; /// Type of 3D point. typedef typename AABBTraits::Point_3 Point; /// Type of input primitive. typedef typename AABBTraits::Primitive Primitive; /// Identifier for a primitive in the tree. typedef typename Primitive::Id Primitive_id; /// Unsigned integral size type. typedef typename Primitives::size_type size_type; /// Type of bounding box. typedef typename AABBTraits::Bounding_box Bounding_box; /// 3D Point and Primitive Id type typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; /// \deprecated typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; /*! An alias to `AABBTraits::Intersection_and_primitive_id` */ #ifdef DOXYGEN_RUNNING template using Intersection_and_primitive_id = AABBTraits::Intersection_and_primitive_id; #else template struct Intersection_and_primitive_id { typedef typename AABBTraits::template Intersection_and_primitive_id::Type Type; }; #endif ///@} public: /// \name Creation ///@{ /// constructs an empty tree, and initializes the internally stored traits /// class using `traits`. AABB_tree(const AABBTraits& traits = AABBTraits()); /** * @brief Builds the datastructure from a sequence of primitives. * @param first iterator over first primitive to insert * @param beyond past-the-end iterator * * constructs an empty tree followed by a call to `insert(first,last,t...)`. * The tree stays empty if the memory allocation is not successful. */ template AABB_tree(InputIterator first, InputIterator beyond,T&& ...); /// triggers the (re)construction of the internal tree structure. /// The internal tree structure is automatically invalidated by the insertion of any primitives /// after one or more calls to `insert()`. /// This procedure is called implicitly at the first call to a query member function. /// An explicit call to `build()` must be made to ensure that the next call to /// a query function will not trigger the construction of the data structure. /// A call to `AABBTraits::set_shared_data(t...)` is made using the internally stored traits. /// This procedure has a complexity of \f$O(n log(n))\f$, where \f$n\f$ is the number of /// primitives of the tree. template 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 ///@} /// \name Operations ///@{ /// is equivalent to calling `clear()`, `insert(first,last,t...)`, and `build()` template void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T&& ...); /// adds a sequence of primitives to the set of primitives of the AABB tree. /// `%InputIterator` is any iterator and the parameter pack `T` contains any types /// such that `Primitive` has a constructor with the following signature: /// `Primitive(%InputIterator, T...)`. If `Primitive` is a model of the concept /// `AABBPrimitiveWithSharedData`, a call to `AABBTraits::set_shared_data(t...)` /// is made using the internally stored traits. template void insert(InputIterator first, InputIterator beyond,T&& ...); /// adds a primitive to the set of primitives of the tree. inline void insert(const Primitive& p); /// clears and destroys the tree. ~AABB_tree() { clear(); } /// returns a const reference to the internally stored traits class. const AABBTraits& traits() const{ return m_traits; } /// clears the tree and the search tree if it was constructed, /// and switches on the usage of the search tree to find the hint for the distance queries void clear() { // clear AABB tree clear_nodes(); m_primitives.clear(); clear_search_tree(); m_use_default_search_tree = true; } /// returns the axis-aligned bounding box of the whole tree. /// \pre `!empty()` const Bounding_box bbox() const { CGAL_precondition(!empty()); if(size() > 1) return root_node()->bbox(); else return traits().compute_bbox_object()(m_primitives.begin(), m_primitives.end()); } /// returns the number of primitives in the tree. size_type size() const { return m_primitives.size(); } /// returns \c true, iff the tree contains no primitive. bool empty() const { return m_primitives.empty(); } ///@} private: template void set_primitive_data_impl(CGAL::Boolean_tag,T ... ){} template void set_primitive_data_impl(CGAL::Boolean_tag,T&& ... t) {m_traits.set_shared_data(std::forward(t)...);} template void set_shared_data(T&& ...t){ set_primitive_data_impl(CGAL::Boolean_tag::value>(),std::forward(t)...); } bool build_kd_tree(); template bool build_kd_tree(ConstPointIterator first, ConstPointIterator beyond); public: /// \name Intersection Tests ///@{ /// returns `true`, iff the query intersects at least one of /// the input primitives. /// \tparam Query must be a type for which `Do_intersect` operators are /// defined in the traits class `AABBTraits`. template bool do_intersect(const Query& query) const; /// returns the number of primitives intersected by the /// query. /// \tparam Query must be a type for which `Do_intersect` operators are /// defined in the traits class `AABBTraits`. template size_type number_of_intersected_primitives(const Query& query) const; /// puts in `out` the ids of all intersected primitives. /// This function does not compute the intersection points /// and is hence faster than the function `all_intersections()` /// function below. /// \tparam Query must be a type for which `Do_intersect` operators are /// defined in the traits class `AABBTraits`. template OutputIterator all_intersected_primitives(const Query& query, OutputIterator out) const; /// returns the id of the intersected primitive that is encountered first /// in the tree traversal, iff /// the query intersects at least one of the input primitives. No /// particular order is guaranteed over the tree traversal, such /// that, e.g, the primitive returned is not necessarily the /// closest from the source point of a ray query. /// \tparam Query must be a type for which `Do_intersect` operators are /// defined in the traits class `AABBTraits`. template boost::optional any_intersected_primitive(const Query& query) const; ///@} /// \name Intersections ///@{ /// puts in `out` all intersections, as objects of /// `Intersection_and_primitive_id::%Type`, /// between the query and the input data to /// the iterator. /// \tparam Query must be a type for which `Do_intersect` and `Intersection` operators are /// defined in the traits class `AABBTraits`. template OutputIterator all_intersections(const Query& query, OutputIterator out) const; /// returns if any the intersection that is encountered first /// in the tree traversal. No particular /// order is guaranteed over the tree traversal, e.g, the /// primitive returned is not necessarily the closest from the query. /// \tparam Query must be a type for which `Do_intersect` and `Intersection` operators are /// defined in the traits class `AABBTraits`. template boost::optional< typename Intersection_and_primitive_id::Type > any_intersection(const Query& query) const; /// returns the intersection and primitive id closest to the source point of the ray /// query. /// \tparam Ray must be the same as `AABBTraits::Ray_3` and /// `do_intersect` predicates and intersections for it must be /// defined. /// \tparam Skip a functor with an operator /// `bool operator()(const Primitive_id& id) const` /// that returns `true` in order to skip the primitive. /// Defaults to a functor that always returns `false`. /// /// \note `skip` might be given some primitives that are not intersected by `query` /// because the intersection test is done after the skip test. Also note that /// the order the primitives are given to `skip` is not necessarily the /// intersection order with `query`. /// /// /// `AABBTraits` must be a model of `AABBRayIntersectionTraits` to /// call this member function. template boost::optional< typename Intersection_and_primitive_id::Type > first_intersection(const Ray& query, const SkipFunctor& skip) const; /// \cond template boost::optional< typename Intersection_and_primitive_id::Type > first_intersection(const Ray& query) const { return first_intersection(query, boost::lambda::constant(false)); } /// \endcond /// returns the primitive id closest to the source point of the ray /// query. /// \tparam Ray must be the same as `AABBTraits::Ray_3` and /// `do_intersect` predicates and intersections for it must be /// defined. /// \tparam Skip a functor with an operator /// `bool operator()(const Primitive_id& id) const` /// that returns `true` in order to skip the primitive. /// Defaults to a functor that always returns `false`. /// /// `AABBTraits` must be a model of `AABBRayIntersectionTraits` to /// call this member function. template boost::optional first_intersected_primitive(const Ray& query, const SkipFunctor& skip) const; /// \cond template boost::optional first_intersected_primitive(const Ray& query) const { return first_intersected_primitive(query, boost::lambda::constant(false)); } /// \endcond ///@} /// \name Distance Queries ///@{ /// returns the minimum squared distance between the query point /// and all input primitives. /// \pre `!empty()` FT squared_distance(const Point& query) const; /// returns the point in the union of all input primitives which /// is closest to the query. In case there are several closest /// points, one arbitrarily chosen closest point is /// returned. /// \pre `!empty()` Point closest_point(const Point& query) const; /// returns a `Point_and_primitive_id` which realizes the /// smallest distance between the query point and all input /// primitives. /// \pre `!empty()` Point_and_primitive_id closest_point_and_primitive(const Point& query) const; ///@} /// \name Accelerating the Distance Queries /// /// In the following paragraphs, we discuss details of the /// implementation of the distance queries. We explain the /// internal use of hints, how the user can pass his own hints to /// the tree, and how the user can influence the construction of /// the secondary data structure used for accelerating distance /// queries. /// Internally, the distance queries algorithms are initialized /// with some hint, which has the same type as the return type of /// the query, and this value is refined along a traversal of the /// tree, until it is optimal, that is to say until it realizes /// the shortest distance to the primitives. In particular, the /// exact specification of these internal algorithms is that they /// minimize the distance to the object composed of the union of /// the primitives and the hint. /// It follows that /// - in order to return the exact distance to the set of /// primitives, the algorithms need the hint to be exactly on the /// primitives; /// - if this is not the case, and if the hint happens to be closer /// to the query point than any of the primitives, then the hint /// is returned. /// /// This second observation is reasonable, in the sense that /// providing a hint to the algorithm means claiming that this /// hint belongs to the union of the primitives. These /// considerations about the hints being exactly on the primitives /// or not are important: in the case where the set of primitives /// is a triangle soup, and if some of the primitives are large, /// one may want to provide a much better hint than a vertex of /// the triangle soup could be. It could be, for example, the /// barycenter of one of the triangles. But, except with the use /// of a kernel with exact constructions, one cannot easily construct /// points other than the vertices, that lie exactly on a triangle /// soup. Hence, providing a good hint sometimes means not being /// able to provide it exactly on the primitives. In rare /// occasions, this hint can be returned as the closest point. /// In order to accelerate distance queries significantly, the /// AABB tree builds an internal KD-tree containing a set of /// potential hints. This KD-tree provides very good hints /// that allow the algorithms to run much faster than /// when `do_not_accelerate_distance_queries()` that makes the /// hint to always be the `reference_point` of the first primitive. /// The set of potential hints is a sampling of the union of the primitives, /// which is obtained, by default, by calling the method /// `reference_point` of each of the primitives. However, such /// a sampling with one point per primitive may not be the most /// relevant one: if some primitives are very large, it helps /// inserting more than one sample on them. Conversely, a sparser /// sampling with less than one point per input primitive is /// relevant in some cases. /// The internal KD-tree is always used if no call to `do_not_accelerate_distance_queries()` /// was made since object creation or the last call to `clear()`. It will be built by /// the first distance query or by a call to `accelerate_distance_queries()`. ///@{ /// constructs the internal search tree from /// a point set taken on the internal primitives /// returns `true` iff successful memory allocation bool accelerate_distance_queries(); /// turns off the usage of the internal search tree and clears it if it was already constructed. void do_not_accelerate_distance_queries(); /// constructs an internal KD-tree containing the specified point /// set, to be used as the set of potential hints for accelerating /// the distance queries. Note that the search tree built in /// this function will not be invalidated by the insertion of a new /// primitive, and an explicit call to `accelerate_distance_queries()` /// is needed to update the search tree. /// \tparam ConstPointIterator is an iterator with /// value type `Point_and_primitive_id`. template bool accelerate_distance_queries(ConstPointIterator first, ConstPointIterator beyond) { m_use_default_search_tree = false; return build_kd_tree(first,beyond); } /// returns the minimum squared distance between the query point /// and all input primitives. The internal KD-tree is not used. /// \pre `!empty()` FT squared_distance(const Point& query, const Point& hint) const; /// returns the point in the union of all input primitives which /// is closest to the query. In case there are several closest /// points, one arbitrarily chosen closest point is returned. The /// internal KD-tree is not used. /// \pre `!empty()` Point closest_point(const Point& query, const Point& hint) const; /// returns a `Point_and_primitive_id` which realizes the /// smallest distance between the query point and all input /// primitives. The internal KD-tree is not used. /// \pre `!empty()` Point_and_primitive_id closest_point_and_primitive(const Point& query, const Point_and_primitive_id& hint) const; ///@} private: template friend class AABB_ray_intersection; // clear nodes void clear_nodes() { if( size() > 1 ) { delete [] m_p_root_node; } m_p_root_node = nullptr; } // clears internal KD tree void clear_search_tree() { #ifdef CGAL_HAS_THREADS if ( m_atomic_search_tree_constructed.load(std::memory_order_relaxed) ) #else if ( m_search_tree_constructed ) #endif { CGAL_assertion( m_p_search_tree!=nullptr ); delete m_p_search_tree; m_p_search_tree = nullptr; #ifdef CGAL_HAS_THREADS m_atomic_search_tree_constructed.store(false, std::memory_order_relaxed); #else m_search_tree_constructed = false; #endif } } public: /// \internal template void traversal(const Query& query, Traversal_traits& traits) const { switch(size()) { case 0: break; case 1: traits.intersection(query, singleton_data()); break; default: // if(size() >= 2) root_node()->template traversal(query, traits, m_primitives.size()); } } private: typedef AABB_node Node; public: // returns a point which must be on one primitive Point_and_primitive_id any_reference_point_and_id() const { CGAL_assertion(!empty()); return Point_and_primitive_id( Helper::get_reference_point(m_primitives[0],m_traits), m_primitives[0].id() ); } public: Point_and_primitive_id best_hint(const Point& query) const { #ifdef CGAL_HAS_THREADS bool m_search_tree_constructed = m_atomic_search_tree_constructed.load(std::memory_order_acquire); #endif // lazily build the search tree in case the default should be used if (m_use_default_search_tree && !m_search_tree_constructed) { #ifdef CGAL_HAS_THREADS CGAL_SCOPED_LOCK(build_mutex); m_search_tree_constructed = m_atomic_search_tree_constructed.load(std::memory_order_relaxed); if (!m_search_tree_constructed) #endif m_search_tree_constructed = const_cast(this)->build_kd_tree(); } if(m_search_tree_constructed) return m_p_search_tree->closest_point(query); else return this->any_reference_point_and_id(); } //! Returns the datum (geometric object) represented `p`. #ifndef DOXYGEN_RUNNING typename Helper::Datum_type #else typename AABBTraits::Primitive::Datum_reference #endif datum(Primitive& p)const { return Helper::get_datum(p, this->traits()); } private: //Traits class AABBTraits m_traits; // set of input primitives Primitives m_primitives; // single root node Node* m_p_root_node = nullptr; #ifdef CGAL_HAS_THREADS mutable CGAL_MUTEX build_mutex; // mutex used to protect const calls inducing build() and build_kd_tree() #endif const Node* root_node() const { CGAL_assertion(size() > 1); #ifdef CGAL_HAS_THREADS bool m_need_build = m_atomic_need_build.load(std::memory_order_acquire); #endif if(m_need_build){ #ifdef CGAL_HAS_THREADS //this ensures that build() will be called once CGAL_SCOPED_LOCK(build_mutex); m_need_build = m_atomic_need_build.load(std::memory_order_relaxed); if(m_need_build) #endif const_cast< AABB_tree* >(this)->build(); } return m_p_root_node; } const Primitive& singleton_data() const { CGAL_assertion(size() == 1); return *m_primitives.begin(); } // search KD-tree const Search_tree* m_p_search_tree = nullptr; bool m_use_default_search_tree = true; // indicates whether the internal kd-tree should be built #ifdef CGAL_HAS_THREADS std::atomic m_atomic_need_build; std::atomic m_atomic_search_tree_constructed; #else bool m_need_build = false; mutable bool m_search_tree_constructed = false; #endif private: // Disabled copy constructor & assignment operator typedef AABB_tree Self; AABB_tree(const Self& src); Self& operator=(const Self& src); }; // end class AABB_tree /// @} template AABB_tree::AABB_tree(const Tr& traits) : m_traits(traits) #ifdef CGAL_HAS_THREADS , m_atomic_need_build(false) , m_atomic_search_tree_constructed(false) #endif {} template template AABB_tree::AABB_tree(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, T&& ... t) #ifdef CGAL_HAS_THREADS : m_atomic_need_build(false) , m_atomic_search_tree_constructed(false) #endif { // Insert each primitive into tree insert(first, beyond,std::forward(t)...); } template template void AABB_tree::insert(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, T&& ... t) { if (m_use_default_search_tree && first!=beyond) clear_search_tree(); set_shared_data(std::forward(t)...); while(first != beyond) { m_primitives.push_back(Primitive(first,std::forward(t)...)); ++first; } #ifdef CGAL_HAS_THREADS m_atomic_need_build.store(true, std::memory_order_relaxed); #else m_need_build = true; #endif } // Clears tree and insert a set of primitives template template void AABB_tree::rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, T&& ... t) { // cleanup current tree and internal KD tree clear(); // inserts primitives insert(first, beyond,std::forward(t)...); build(); } template template void AABB_tree::build(T&& ... t) { set_shared_data(std::forward(t)...); build(); } template void AABB_tree::insert(const Primitive& p) { if (m_use_default_search_tree) clear_search_tree(); m_primitives.push_back(p); #ifdef CGAL_HAS_THREADS m_atomic_need_build.store(true, std::memory_order_relaxed); #else m_need_build = true; #endif } template void AABB_tree::build() { custom_build(m_traits.compute_bbox_object(), m_traits.split_primitives_object()); } #ifndef DOXYGEN_RUNNING // 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) { // allocates tree nodes m_p_root_node = new Node[m_primitives.size()-1](); if(m_p_root_node == nullptr) { std::cerr << "Unable to allocate memory for AABB tree" << std::endl; CGAL_assertion(m_p_root_node != nullptr); m_primitives.clear(); clear(); } // constructs the tree m_p_root_node->expand(m_primitives.begin(), m_primitives.end(), 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() #else m_need_build = false; #endif } #endif // constructs the search KD tree from given points // to accelerate the distance queries template bool AABB_tree::build_kd_tree() { // iterate over primitives to get reference points on them std::vector points; points.reserve(m_primitives.size()); for(const Primitive& p : m_primitives) points.push_back( Point_and_primitive_id( Helper::get_reference_point(p, m_traits), p.id() ) ); // clears current KD tree return build_kd_tree(points.begin(), points.end()); } // constructs the search KD tree from given points // to accelerate the distance queries template template bool AABB_tree::build_kd_tree(ConstPointIterator first, ConstPointIterator beyond) { clear_search_tree(); m_p_search_tree = new Search_tree(first, beyond); if(m_p_search_tree != nullptr) { #ifdef CGAL_HAS_THREADS m_atomic_search_tree_constructed.store(true, std::memory_order_release); // in case build_kd_tree() is triggered by a call to best_hint() #else m_search_tree_constructed = true; #endif return true; } else { std::cerr << "Unable to allocate memory for accelerating distance queries" << std::endl; return false; } } template void AABB_tree::do_not_accelerate_distance_queries() { clear_search_tree(); m_use_default_search_tree = false; } // constructs the search KD tree from internal primitives template bool AABB_tree::accelerate_distance_queries() { m_use_default_search_tree = true; if(m_primitives.empty()) return true; return build_kd_tree(); } template template bool AABB_tree::do_intersect(const Query& query) const { using namespace CGAL::internal::AABB_tree; typedef typename AABB_tree::AABB_traits AABBTraits; Do_intersect_traits traversal_traits(m_traits); this->traversal(query, traversal_traits); return traversal_traits.is_intersection_found(); } #ifndef DOXYGEN_RUNNING //To avoid doxygen to consider definition and declaration as 2 different functions (size_type causes problems) template template typename AABB_tree::size_type AABB_tree::number_of_intersected_primitives(const Query& query) const { using namespace CGAL::internal::AABB_tree; using CGAL::internal::AABB_tree::Counting_output_iterator; typedef typename AABB_tree::AABB_traits AABBTraits; typedef Counting_output_iterator Counting_iterator; size_type counter = 0; Counting_iterator out(&counter); Listing_primitive_traits traversal_traits(out,m_traits); this->traversal(query, traversal_traits); return counter; } #endif template template OutputIterator AABB_tree::all_intersected_primitives(const Query& query, OutputIterator out) const { using namespace CGAL::internal::AABB_tree; typedef typename AABB_tree::AABB_traits AABBTraits; Listing_primitive_traits traversal_traits(out,m_traits); this->traversal(query, traversal_traits); return out; } template template OutputIterator AABB_tree::all_intersections(const Query& query, OutputIterator out) const { using namespace CGAL::internal::AABB_tree; typedef typename AABB_tree::AABB_traits AABBTraits; Listing_intersection_traits traversal_traits(out,m_traits); this->traversal(query, traversal_traits); return out; } template template boost::optional< typename AABB_tree::template Intersection_and_primitive_id::Type > AABB_tree::any_intersection(const Query& query) const { using namespace CGAL::internal::AABB_tree; typedef typename AABB_tree::AABB_traits AABBTraits; First_intersection_traits traversal_traits(m_traits); this->traversal(query, traversal_traits); return traversal_traits.result(); } template template boost::optional::Primitive_id> AABB_tree::any_intersected_primitive(const Query& query) const { using namespace CGAL::internal::AABB_tree; typedef typename AABB_tree::AABB_traits AABBTraits; First_primitive_traits traversal_traits(m_traits); this->traversal(query, traversal_traits); return traversal_traits.result(); } // closest point with user-specified hint template typename AABB_tree::Point AABB_tree::closest_point(const Point& query, const Point& hint) const { CGAL_precondition(!empty()); typename Primitive::Id hint_primitive = m_primitives[0].id(); using namespace CGAL::internal::AABB_tree; typedef typename AABB_tree::AABB_traits AABBTraits; Projection_traits projection_traits(hint,hint_primitive,m_traits); this->traversal(query, projection_traits); return projection_traits.closest_point(); } // closest point without hint, the search KD-tree is queried for the // first closest neighbor point to get a hint template typename AABB_tree::Point AABB_tree::closest_point(const Point& query) const { CGAL_precondition(!empty()); const Point_and_primitive_id hint = best_hint(query); return closest_point(query,hint.first); } // squared distance with user-specified hint template typename AABB_tree::FT AABB_tree::squared_distance(const Point& query, const Point& hint) const { CGAL_precondition(!empty()); const Point closest = this->closest_point(query, hint); return Tr().squared_distance_object()(query, closest); } // squared distance without user-specified hint template typename AABB_tree::FT AABB_tree::squared_distance(const Point& query) const { CGAL_precondition(!empty()); const Point closest = this->closest_point(query); return Tr().squared_distance_object()(query, closest); } // closest point with user-specified hint template typename AABB_tree::Point_and_primitive_id AABB_tree::closest_point_and_primitive(const Point& query) const { CGAL_precondition(!empty()); return closest_point_and_primitive(query,best_hint(query)); } // closest point with user-specified hint template typename AABB_tree::Point_and_primitive_id AABB_tree::closest_point_and_primitive(const Point& query, const Point_and_primitive_id& hint) const { CGAL_precondition(!empty()); using namespace CGAL::internal::AABB_tree; typedef typename AABB_tree::AABB_traits AABBTraits; Projection_traits projection_traits(hint.first,hint.second,m_traits); this->traversal(query, projection_traits); return projection_traits.closest_point_and_primitive(); } } // end namespace CGAL #include #include #endif // CGAL_AABB_TREE_H /***EMACS SETTINGS** */ /* Local Variables: */ /* tab-width: 2 */ /* indent-tabs-mode: t */ /* End: */