From db287f0e56e2054aefbcb808fbff271b5fd31cc9 Mon Sep 17 00:00:00 2001 From: Pierre Alliez Date: Thu, 7 May 2009 10:51:01 +0000 Subject: [PATCH] AABB tree: more on internal KD-tree used to accelerate the distance queries. --- AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex | 8 +-- AABB_tree/include/CGAL/AABB_tree.h | 63 +++++++++++++------ 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex b/AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex index 6b7074b07f7..668f683ba30 100644 --- a/AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex +++ b/AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex @@ -140,14 +140,14 @@ squared_distance(const Point& query, \ccHeading{Accelerating the distance queries} -\ccMethod{void construct_search_tree();} -{ Constructs the internal search KD-tree used to accelerate the distance queries. The points in the search tree are taken from the primitives by calling the member function \ccc{reference_point} from the primitive.} +\ccMethod{bool construct_search_tree();} +{ Constructs the internal search KD-tree used to accelerate the distance queries. The points in the search tree are taken from the primitives by calling the member function \ccc{reference_point} from the primitive. Returns \ccc{true}, iff the memory allocation is successful.} \begin{ccAdvanced} \ccMethod{template -void construct_search_tree(InputIterator begin, +bool construct_search_tree(InputIterator begin, InputIterator beyond);} -{ Constructs the internal search KD-tree used to accelerate the distance queries from a specified point set. Iterator \ccc{InputIterator} must have \ccc{Point_and_primitive} as value type. Each point from the specified \ccc{Point_and_primitive} set must be located on the corresponding input primitive. For a triangle surface mesh this point set can be provided, e.g., as the vertex points or as the triangle centroids. It is not required to provide one point per primitive, such that, e.g., large input primitive can be sampled with several sample points or conversely such that a single point is provided for clusters of small input primitives. } +{ Constructs the internal search KD-tree used to accelerate the distance queries from a specified point set. Iterator \ccc{InputIterator} must have \ccc{Point_and_primitive} as value type. Each point from the specified \ccc{Point_and_primitive} set must be located on the corresponding input primitive. For a triangle surface mesh this point set can be provided, e.g., as the vertex points or as the triangle centroids. It is not required to provide one point per primitive, such that, e.g., large input primitive can be sampled with several sample points or conversely such that a single point is provided for clusters of small input primitives. Returns \ccc{true}, iff the memory allocation is successful.} \end{ccAdvanced} \ccSeeAlso diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 996291a6979..6cef0f858af 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -70,33 +70,37 @@ namespace CGAL { bool rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond); /// Non virtual destructor - ~AABB_tree() { + ~AABB_tree() + { clear(); - if(m_search_tree_constructed) - delete(m_search_tree); } /// Clears the tree - void clear(void) + void clear() { + // clear AABB tree m_data.clear(); - delete[] m_p_root; + delete [] m_p_root; m_p_root = NULL; - m_search_tree_constructed = false; + + clear_search_tree(); } + // bbox and size Bounding_box bbox() const { return m_p_root->bbox(); } Size_type size() const { return m_data.size(); } bool empty() const { return m_data.empty(); } /// Construct internal search tree with a given point set + // returns true iff successful memory allocation template - void construct_search_tree(ConstPointIterator first, ConstPointIterator beyond); + bool construct_search_tree(ConstPointIterator first, ConstPointIterator beyond); /// Construct internal search tree from /// a point set taken on the internal primitives - void construct_search_tree(void); + // returns true iff successful memory allocation + bool construct_search_tree(); template bool do_intersect(const Query& query) const; @@ -126,6 +130,17 @@ namespace CGAL { Point_and_primitive closest_point_and_primitive(const Point& query, const Point& hint) const; Point_and_primitive closest_point_and_primitive(const Point& query) const; + private: + + void clear_search_tree() + { + // clear KD tree + delete m_p_search_tree; + m_p_search_tree = NULL; + m_search_tree_constructed = false; + } + + /// generic traversal of the tree template void traversal(const Query& query, Traversal_traits& traits) const @@ -353,7 +368,7 @@ namespace CGAL { // single root node Node* m_p_root; // search KD-tree - Search_tree* m_search_tree; + Search_tree* m_p_search_tree; bool m_search_tree_constructed; private: @@ -370,6 +385,7 @@ namespace CGAL { ConstPrimitiveIterator beyond) : m_data() , m_p_root(NULL) + , m_p_search_tree(NULL) , m_search_tree_constructed(false) { // Insert each primitive into tree @@ -398,7 +414,7 @@ namespace CGAL { bool AABB_tree::rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond) { - // cleanup current tree + // cleanup current tree and internal KD tree clear(); // inserts primitives @@ -425,17 +441,25 @@ namespace CGAL { // constructs the search KD tree from given points template template - void - AABB_tree::construct_search_tree(ConstPointIterator first, - ConstPointIterator beyond) + bool AABB_tree::construct_search_tree(ConstPointIterator first, + ConstPointIterator beyond) { - m_search_tree = new Search_tree(first, beyond); - m_search_tree_constructed = true; + // clears current KD tree + clear_search_tree(); + + m_p_search_tree = new Search_tree(first, beyond); + if(m_p_search_tree != NULL) + { + m_search_tree_constructed = true; + return true; + } + else + return false; } // constructs the search KD tree from interal primitives template - void AABB_tree::construct_search_tree(void) + bool AABB_tree::construct_search_tree() { CGAL_assertion(!m_data.empty()); @@ -443,10 +467,9 @@ namespace CGAL { std::vector points; typename std::vector::const_iterator it; for(it = m_data.begin(); it != m_data.end(); ++it) - { points.push_back(it->reference_point()); - } - construct_search_tree(points.begin(), points.end()); + + return construct_search_tree(points.begin(), points.end()); } template @@ -550,7 +573,7 @@ namespace CGAL { { Point hint; if(m_search_tree_constructed) - hint = m_search_tree->closest_point(query); // pick closest neighbor point as hint (fast) + hint = m_p_search_tree->closest_point(query); // pick closest neighbor point as hint (fast) else hint = m_data[0].reference_point(); // pick first primitive reference point as hint (slow) return closest_point(query,hint);