diff --git a/.gitattributes b/.gitattributes index 1745a84c043..bcc70dae89a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -39,10 +39,10 @@ AABB_tree/examples/AABB_tree/cleanup.bat -text AABB_tree/include/CGAL/AABB_intersections.h -text AABB_tree/include/CGAL/AABB_polyhedron_segment_primitive.h -text AABB_tree/include/CGAL/AABB_polyhedron_triangle_primitive.h -text -AABB_tree/include/CGAL/AABB_search_tree.h -text AABB_tree/include/CGAL/AABB_segment_primitive.h -text AABB_tree/include/CGAL/AABB_traits.h -text AABB_tree/include/CGAL/AABB_triangle_primitive.h -text +AABB_tree/include/CGAL/internal/AABB_tree/AABB_search_tree.h -text AABB_tree/include/CGAL/internal/AABB_tree/nearest_point_segment_3.h -text AABB_tree/test/AABB_tree/AABB_test_util.h -text AABB_tree/test/AABB_tree/aabb_correctness_triangle_test.cpp -text diff --git a/.gitignore b/.gitignore index d276b275548..f24b9a7d089 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ AABB_tree/examples/AABB_tree/Makefile AABB_tree/examples/AABB_tree/cgal_test_with_cmake AABB_tree/test/AABB_tree/*.kdev* AABB_tree/test/AABB_tree/AABB_tests.sln +AABB_tree/test/AABB_tree/CMakeLists.txt AABB_tree/test/AABB_tree/Makefile AABB_tree/test/AABB_tree/aabb_correctness_triangle_test AABB_tree/test/AABB_tree/aabb_distance_edge_test diff --git a/AABB_tree/doc_tex/AABB_tree/examples.tex b/AABB_tree/doc_tex/AABB_tree/examples.tex index 21857c7e1f8..f302144f425 100644 --- a/AABB_tree/doc_tex/AABB_tree/examples.tex +++ b/AABB_tree/doc_tex/AABB_tree/examples.tex @@ -1,8 +1,6 @@ \section{Examples} \label{AABB_tree_section_examples} -In all following examples the file \ccc{CGAL/AABB_tree.h} must be included \emph{before} the kernel (here \ccc{Simple_cartesian.h}) so that the related intersection functions (in folder \ccc{AABB_intersections}) are properly parsed by the compiler. - \subsection{Tree of Triangles, for Intersection and Distance Queries} In the following example a set of 3D triangles is stored in a list. The AABB primitive wraps a triangle as \ccc{datum} and an iterator in the list as \ccc{id}. We compute the number of input triangles intersected by a ray query, as well as the closest point and the squared distance from a point query. \ccIncludeExampleCode{AABB_tree/AABB_triangle_3_example.cpp} @@ -23,6 +21,13 @@ In the following example the segments are stored into a list, and the AABB primi In the following example the AABB primitive wraps a halfedge handle as \ccc{id} and generates a 3D segment on the fly, each time its method \ccc{datum} is called. We compute the number of intersections with a triangle query and the closest point from a point query. \ccIncludeExampleCode{AABB_tree/AABB_polyhedron_edge_example.cpp} +\subsection{Incremental Insertion of Primitives} +The AABB tree is a static data structure, but it allows to insert primitives, and will internally +rebuild triggered by the first query, or because the user calls the \ccc{build} method. +The following example illustrates this for two polyhedral surfaces. + +\ccIncludeExampleCode{AABB_tree/AABB_insertion_example.cpp} + \subsection{Trees of Custom Primitives} The AABB tree example folder contains three examples of trees constructed with customize primitives. In \ccc{AABB_custom_example.cpp} the primitive contains triangles which are defined by three pointers to custom points. In \ccc{AABB_custom_triangle_soup_example.cpp} all input triangles are stored into a single array so as to form a triangle soup. The primitive internally uses a \ccc{boost::iterator_adaptor} so as to provide the three functions (\ccc{id()}, \ccc{datum()}, \ccc{reference_point()}) required by the primitive concept. In \ccc{AABB_custom_indexed_triangle_set_example.cpp} the input is an indexed triangle set stored through two arrays: one array of points and one array of indices which refer to the point array. Here also the primitive internally uses a \ccc{boost::iterator_adaptor}. 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 398d163abfa..9a806e223c9 100644 --- a/AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex +++ b/AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex @@ -19,7 +19,7 @@ \ccDefinition -Class \ccRefName\ is a static data structure for efficient intersection and distance computations in 3D. It builds a hierarchy of axis-aligned bounding boxes (a 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 \ccc{AT}. The template parameter \ccc{AT} stands for a traits class which must be a model of the concept \ccc{AABBTraits}. +Class \ccRefName\ is a 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 \ccc{AT}. The template parameter \ccc{AT} stands for a traits class which must be a model of the concept \ccc{AABBTraits}. \ccInclude{CGAL/AABB_tree.h} @@ -53,6 +53,29 @@ Class \ccRefName\ is a static data structure for efficient intersection and dist InputIterator beyond);}{Clears the current tree and rebuilds it from scratch. See constructor above for the parameters. } \ccGlue \ccMethod{void clear();}{Clears the AABB tree. } + +\ccGlue +\ccMethod{template + void insert(InputIterator begin, InputIterator beyond);} + {Add a sequence of primitives to the set of primitive of the AABB + tree. Type \ccc{InputIterator} can be any const iterator such that \ccc{Primitive} + has a constructor taking an InputIterator as argument.} +\ccGlue +\ccMethod{void insert(const Primitive p);} + {Add a primitive to the set of primitives of the AABB tree.} + +\begin{ccAdvanced} +\ccMethod{void build();} + {After one or more calls to \ccc{insert}, the internal data structure + of \ccRefName\ must be reconstructed. This procedure has a complexity of + \ccc{O(n log(n))}, where n is the number of primitives of the tree. This + procedure is called implicitly at the first call to a query member + function. You can call \ccc{build()} explicitly to ensure that the + next call to query functions will not trigger the reconstruction of the + data structure.} +\end{ccAdvanced> + + \ccGlue \ccMethod{Bounding_box bbox();}{Returns the axis-aligned bounding box of the whole tree. } \ccGlue diff --git a/AABB_tree/examples/AABB_tree/AABB_custom_example.cpp b/AABB_tree/examples/AABB_tree/AABB_custom_example.cpp index 3ea788b25b2..0ebb56d7bd3 100644 --- a/AABB_tree/examples/AABB_tree/AABB_custom_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_custom_example.cpp @@ -1,35 +1,13 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Camille Wormser, Pierre Alliez -// -//****************************************************************************** -// File Description : An example of AABB tree constructed with -// custom point and triangle types. -// -//****************************************************************************** +// Author(s): Camille Wormser, Pierre Alliez +// An example of an AABB tree constructed with custom point and triangle types. #include #include - -#include // must be inserted before kernel +#include +#include #include -#include + typedef CGAL::Simple_cartesian K; diff --git a/AABB_tree/examples/AABB_tree/AABB_custom_indexed_triangle_set_example.cpp b/AABB_tree/examples/AABB_tree/AABB_custom_indexed_triangle_set_example.cpp index 9c856e1a075..d8b2daefaf0 100644 --- a/AABB_tree/examples/AABB_tree/AABB_custom_indexed_triangle_set_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_custom_indexed_triangle_set_example.cpp @@ -1,35 +1,15 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Camille Wormser, Pierre Alliez -// -//****************************************************************************** -// File Description : Example of AABB tree used with indexed triangle set -// -//****************************************************************************** +// Author(s): Camille Wormser, Pierre Alliez +// Example of an AABB tree used with indexed triangle set #include #include #include -#include // must be inserted before kernel +#include +#include #include -#include + typedef CGAL::Simple_cartesian K; diff --git a/AABB_tree/examples/AABB_tree/AABB_custom_triangle_soup_example.cpp b/AABB_tree/examples/AABB_tree/AABB_custom_triangle_soup_example.cpp index 285bd10888d..1084afb310e 100644 --- a/AABB_tree/examples/AABB_tree/AABB_custom_triangle_soup_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_custom_triangle_soup_example.cpp @@ -1,36 +1,16 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Camille Wormser, Pierre Alliez -// -//****************************************************************************** -// File Description : Example of AABB tree used with a simple list of +// Author(s) : Camille Wormser, Pierre Alliez +// Example of an AABB tree used with a simple list of // triangles (a triangle soup) stored into an array of points. -// -//****************************************************************************** #include #include #include -#include // must be inserted before kernel +#include +#include #include -#include + typedef CGAL::Simple_cartesian K; diff --git a/AABB_tree/examples/AABB_tree/AABB_insertion_example.cpp b/AABB_tree/examples/AABB_tree/AABB_insertion_example.cpp new file mode 100644 index 00000000000..8f27fc3c829 --- /dev/null +++ b/AABB_tree/examples/AABB_tree/AABB_insertion_example.cpp @@ -0,0 +1,52 @@ +#include + +#include +#include // must be inserted before kernel +#include +#include +#include + +typedef CGAL::Simple_cartesian K; +typedef K::FT FT; +typedef K::Point_3 Point; +typedef K::Segment_3 Segment; +typedef CGAL::Polyhedron_3 Polyhedron; +typedef CGAL::AABB_polyhedron_triangle_primitive Primitive; +typedef CGAL::AABB_traits Traits; +typedef CGAL::AABB_tree Tree; +typedef Tree::Object_and_primitive_id Object_and_primitive_id; +typedef Tree::Point_and_primitive_id Point_and_primitive_id; + +int main() +{ + Point p(1.0, 0.0, 0.0); + Point q(0.0, 1.0, 0.0); + Point r(0.0, 0.0, 1.0); + Point s(0.0, 0.0, 0.0); + Polyhedron polyhedron1; + polyhedron1.make_tetrahedron(p, q, r, s); + + + Point p2(11.0, 0.0, 0.0); + Point q2(10.0, 1.0, 0.0); + Point r2(10.0, 0.0, 1.0); + Point s2(10.0, 0.0, 0.0); + Polyhedron polyhedron2; + polyhedron2.make_tetrahedron(p2, q2, r2, s2); + // constructs AABB tree and computes internal KD-tree + // data structure to accelerate distance queries + Tree tree(polyhedron1.facets_begin(),polyhedron1.facets_end()); + + tree.accelerate_distance_queries(); + + tree.insert(polyhedron2.facets_begin(),polyhedron2.facets_end()); + + // query point + Point query(0.0, 0.0, 3.0); + + // computes squared distance from query + FT sqd = tree.squared_distance(query); + std::cout << "squared distance: " << sqd << std::endl; + + return EXIT_SUCCESS; +} diff --git a/AABB_tree/examples/AABB_tree/AABB_polyhedron_edge_example.cpp b/AABB_tree/examples/AABB_tree/AABB_polyhedron_edge_example.cpp index 0a13da9d217..c8e3bd66dd1 100644 --- a/AABB_tree/examples/AABB_tree/AABB_polyhedron_edge_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_polyhedron_edge_example.cpp @@ -1,34 +1,12 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Pierre Alliez -// -//****************************************************************************** -// File Description : -// -//****************************************************************************** +// Author(s) : Pierre Alliez #include -#include // must be inserted before kernel +#include +#include #include #include #include -#include typedef CGAL::Simple_cartesian K; typedef K::FT FT; diff --git a/AABB_tree/examples/AABB_tree/AABB_polyhedron_facet_distance_example.cpp b/AABB_tree/examples/AABB_tree/AABB_polyhedron_facet_distance_example.cpp index 3cd70b273a4..8e558b29952 100644 --- a/AABB_tree/examples/AABB_tree/AABB_polyhedron_facet_distance_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_polyhedron_facet_distance_example.cpp @@ -1,36 +1,14 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Pierre Alliez -// -//****************************************************************************** -// File Description : -// -//****************************************************************************** + +// Author(s) : Pierre Alliez #include -#include // must be inserted before kernel +#include +#include #include #include #include -#include - typedef CGAL::Simple_cartesian K; typedef K::FT FT; typedef K::Point_3 Point; diff --git a/AABB_tree/examples/AABB_tree/AABB_polyhedron_facet_intersection_example.cpp b/AABB_tree/examples/AABB_tree/AABB_polyhedron_facet_intersection_example.cpp index 2005b534194..c02947ab657 100644 --- a/AABB_tree/examples/AABB_tree/AABB_polyhedron_facet_intersection_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_polyhedron_facet_intersection_example.cpp @@ -1,36 +1,13 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Camille Wormser, Pierre Alliez -// -//****************************************************************************** -// File Description : -// -//****************************************************************************** +// Author(s) : Camille Wormser, Pierre Alliez #include -#include // must be inserted before kernel +#include +#include #include #include #include -#include - typedef CGAL::Simple_cartesian K; typedef K::Point_3 Point; typedef K::Plane_3 Plane; diff --git a/AABB_tree/examples/AABB_tree/AABB_segment_3_example.cpp b/AABB_tree/examples/AABB_tree/AABB_segment_3_example.cpp index 000826475e4..cf3ddc89f12 100644 --- a/AABB_tree/examples/AABB_tree/AABB_segment_3_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_segment_3_example.cpp @@ -1,36 +1,13 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Pierre Alliez -// -//****************************************************************************** -// File Description : -// -//****************************************************************************** +// Author : Pierre Alliez #include #include -#include // must be inserted before kernel +#include +#include #include #include -#include - typedef CGAL::Simple_cartesian K; typedef K::FT FT; diff --git a/AABB_tree/examples/AABB_tree/AABB_triangle_3_example.cpp b/AABB_tree/examples/AABB_tree/AABB_triangle_3_example.cpp index 68d6d2eab9f..b90e5eafa35 100644 --- a/AABB_tree/examples/AABB_tree/AABB_triangle_3_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_triangle_3_example.cpp @@ -1,36 +1,13 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Camille Wormser, Pierre Alliez -// -//****************************************************************************** -// File Description : -// -//****************************************************************************** +// Author(s) : Camille Wormser, Pierre Alliez #include #include -#include // must be inserted before kernel +#include +#include #include #include -#include - typedef CGAL::Simple_cartesian K; typedef K::FT FT; diff --git a/AABB_tree/examples/AABB_tree/CMakeLists.txt b/AABB_tree/examples/AABB_tree/CMakeLists.txt index 7c304d542be..1adc84f89c1 100644 --- a/AABB_tree/examples/AABB_tree/CMakeLists.txt +++ b/AABB_tree/examples/AABB_tree/CMakeLists.txt @@ -29,6 +29,7 @@ if ( CGAL_FOUND ) create_single_source_cgal_program("AABB_polyhedron_facet_distance_example.cpp") create_single_source_cgal_program("AABB_polyhedron_facet_intersection_example.cpp") create_single_source_cgal_program("AABB_custom_example.cpp") + create_single_source_cgal_program("AABB_insertion_example.cpp") create_single_source_cgal_program("AABB_custom_indexed_triangle_set_example.cpp") create_single_source_cgal_program("AABB_custom_triangle_soup_example.cpp") else() diff --git a/AABB_tree/include/CGAL/AABB_traits.h b/AABB_tree/include/CGAL/AABB_traits.h index c50692375a7..9f5fe2fee0d 100644 --- a/AABB_tree/include/CGAL/AABB_traits.h +++ b/AABB_tree/include/CGAL/AABB_traits.h @@ -194,6 +194,7 @@ Intersection intersection_object() {return Intersection();} // this is not the same do_intersect as the spherical kernel) class Compare_distance { typedef typename AT::Point Point; + typedef typename AT::FT FT; typedef typename AT::Primitive Primitive; public: template @@ -204,6 +205,16 @@ Intersection intersection_object() {return Intersection();} (p, GeomTraits().compute_squared_distance_3_object()(p, bound)), pr)? CGAL::SMALLER : CGAL::LARGER; } + + template + CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const FT& sq_distance) const + { + return GeomTraits().do_intersect_3_object() + (GeomTraits().construct_sphere_3_object()(p, sq_distance), + pr) ? + CGAL::SMALLER : + CGAL::LARGER; + } }; Closest_point closest_point_object() {return Closest_point();} diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 0b9c88517f9..bc442975040 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -22,9 +22,10 @@ #include #include +#include +#include +#include #include -#include -#include namespace CGAL { @@ -38,6 +39,7 @@ namespace CGAL { { public: /// types + typedef AABBTraits AABB_traits; typedef typename AABBTraits::FT FT; typedef typename AABBTraits::Point Point; typedef typename AABBTraits::Primitive Primitive; @@ -85,6 +87,16 @@ namespace CGAL { template void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond); + /// Add primitives in the structure. build() must be called before any + /// request. + template + void insert(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond); + + inline void insert(const Primitive& p); + + /// Build the data structure, after calls to insert() + void build(); + /// Non virtual destructor ~AABB_tree() { @@ -96,26 +108,25 @@ namespace CGAL { { // clear AABB tree m_primitives.clear(); - delete [] m_p_root_node; - m_p_root_node = NULL; - + clear_nodes(); clear_search_tree(); } // bbox and size - Bounding_box bbox() const { return m_p_root_node->bbox(); } + Bounding_box bbox() const { return root_node()->bbox(); } size_type size() const { return m_primitives.size(); } bool empty() const { return m_primitives.empty(); } /// Construct internal search tree with a given point set // returns true iff successful memory allocation template - bool accelerate_distance_queries(ConstPointIterator first, ConstPointIterator beyond); + bool accelerate_distance_queries(ConstPointIterator first, + ConstPointIterator beyond) const; /// Construct internal search tree from /// a point set taken on the internal primitives // returns true iff successful memory allocation - bool accelerate_distance_queries(); + bool accelerate_distance_queries() const; // intersection tests template @@ -146,13 +157,20 @@ namespace CGAL { Point_and_primitive_id closest_point_and_primitive(const Point& query, const Point_and_primitive_id& hint) const; private: + // clear nodes + void clear_nodes() + { + delete [] m_p_root_node; + m_p_root_node = NULL; + } // clears internal KD tree - void clear_search_tree() + void clear_search_tree() const { delete m_p_search_tree; m_p_search_tree = NULL; m_search_tree_constructed = false; + m_default_search_tree_constructed = false; } public: @@ -163,7 +181,7 @@ namespace CGAL { void traversal(const Query& query, Traversal_traits& traits) const { if(!empty()) - m_p_root_node->template traversal(query, traits, m_primitives.size()); + root_node()->template traversal(query, traits, m_primitives.size()); else std::cerr << "AABB tree traversal with empty tree" << std::endl; } @@ -171,244 +189,6 @@ namespace CGAL { private: typedef AABB_node Node; - //------------------------------------------------------- - // Traits classes for traversal computation - //------------------------------------------------------- - /** - * @class First_intersection_traits - */ - template - class First_intersection_traits - { - public: - typedef typename boost::optional Result; - public: - First_intersection_traits() - : m_result() - {} - - bool go_further() const { return !m_result; } - - void intersection(const Query& query, const Primitive& primitive) - { - m_result = AABBTraits().intersection_object()(query, primitive); - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - Result result() const { return m_result; } - bool is_intersection_found() const { return m_result; } - - private: - Result m_result; - }; - - - /** - * @class Counting_traits - */ - template - class Counting_traits - { - public: - Counting_traits() - : m_nb_intersections(0) - {} - - bool go_further() const { return true; } - - void intersection(const Query& query, const Primitive& primitive) - { - if( AABBTraits().do_intersect_object()(query, primitive) ) - { - ++m_nb_intersections; - } - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - size_type number_of_intersections() const { return m_nb_intersections; } - - private: - size_type m_nb_intersections; - }; - - - /** - * @class Listing_intersection_traits - */ - template - class Listing_intersection_traits - { - public: - Listing_intersection_traits(Output_iterator out_it) - : m_out_it(out_it) {} - - bool go_further() const { return true; } - - void intersection(const Query& query, const Primitive& primitive) - { - boost::optional intersection; - intersection = AABBTraits().intersection_object()(query, primitive); - if(intersection) - { - *m_out_it++ = *intersection; - } - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - private: - Output_iterator m_out_it; - }; - - - /** - * @class Listing_primitive_traits - */ - template - class Listing_primitive_traits - { - public: - Listing_primitive_traits(Output_iterator out_it) - : m_out_it(out_it) {} - - bool go_further() const { return true; } - - void intersection(const Query& query, const Primitive& primitive) - { - if( AABBTraits().do_intersect_object()(query, primitive) ) - { - *m_out_it++ = primitive.id(); - } - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - private: - Output_iterator m_out_it; - }; - - - /** - * @class First_primitive_traits - */ - template - class First_primitive_traits - { - public: - First_primitive_traits() - : m_is_found(false) - , m_result() {} - - bool go_further() const { return !m_is_found; } - - void intersection(const Query& query, const Primitive& primitive) - { - if( AABBTraits().do_intersect_object()(query, primitive) ) - { - m_result = boost::optional(primitive.id()); - m_is_found = true; - } - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - boost::optional result() const { return m_result; } - bool is_intersection_found() const { return m_is_found; } - - private: - bool m_is_found; - boost::optional m_result; - }; - - /** - * @class Do_intersect_traits - */ - template - class Do_intersect_traits - { - public: - Do_intersect_traits() - : m_is_found(false) - {} - - bool go_further() const { return !m_is_found; } - - void intersection(const Query& query, const Primitive& primitive) - { - if( AABBTraits().do_intersect_object()(query, primitive) ) - m_is_found = true; - } - - bool do_intersect(const Query& query, const Node& node) const - { - return AABBTraits().do_intersect_object()(query, node.bbox()); - } - - bool is_intersection_found() const { return m_is_found; } - - private: - bool m_is_found; - }; - - - /** - * @class Distance_traits - */ - class Distance_traits - { - public: - Distance_traits(const Point& hint, - const typename Primitive::Id& hint_primitive) - : m_closest_point(hint), - m_closest_primitive(hint_primitive) - {} - - bool go_further() const { return true; } - - void intersection(const Point& query, const Primitive& primitive) - { - Point new_closest_point = AABBTraits().closest_point_object() - (query, primitive, m_closest_point); - if(new_closest_point != m_closest_point) - { - m_closest_primitive = primitive.id(); - m_closest_point = new_closest_point; // this effectively shrinks the sphere - } - } - - bool do_intersect(const Point& query, const Node& node) const - { - return AABBTraits().compare_distance_object() - (query, node.bbox(), m_closest_point) == CGAL::SMALLER; - } - - Point closest_point() const { return m_closest_point; } - Point_and_primitive_id closest_point_and_primitive() const - { - return Point_and_primitive_id(m_closest_point, m_closest_primitive); - } - - private: - Point m_closest_point; - typename Primitive::Id m_closest_primitive; - }; public: // returns a point which must be on one primitive @@ -432,9 +212,18 @@ namespace CGAL { Primitives m_primitives; // single root node Node* m_p_root_node; + + Node* root_node() const { + if(m_need_build) + const_cast< AABB_tree* >(this)->build(); + return m_p_root_node; + } + // search KD-tree - Search_tree* m_p_search_tree; - bool m_search_tree_constructed; + mutable Search_tree* m_p_search_tree; + mutable bool m_search_tree_constructed; + mutable bool m_default_search_tree_constructed; + bool m_need_build; private: // Disabled copy constructor & assignment operator @@ -450,63 +239,88 @@ namespace CGAL { , m_p_root_node(NULL) , m_p_search_tree(NULL) , m_search_tree_constructed(false) - { } + , m_default_search_tree_constructed(false) + , m_need_build(false) + {} template template AABB_tree::AABB_tree(ConstPrimitiveIterator first, - ConstPrimitiveIterator beyond) + ConstPrimitiveIterator beyond) : m_primitives() , m_p_root_node(NULL) , m_p_search_tree(NULL) , m_search_tree_constructed(false) + , m_default_search_tree_constructed(false) + , m_need_build(false) { // Insert each primitive into tree - while ( first != beyond ) + insert(first, beyond); + } + + template + template + void AABB_tree::insert(ConstPrimitiveIterator first, + ConstPrimitiveIterator beyond) + { + while(first != beyond) { m_primitives.push_back(Primitive(first)); ++first; } + m_need_build = true; + } - CGAL_assertion(m_primitives.size() > 1); - m_p_root_node = new Node[m_primitives.size()-1](); - if(m_p_root_node == NULL) - { - std::cerr << "Unable to allocate memory for AABB tree" << std::endl; - CGAL_assertion(m_p_root_node != NULL); - m_primitives.clear(); - } - else - m_p_root_node->expand(m_primitives.begin(), m_primitives.end(), m_primitives.size()); - } + template + void AABB_tree::insert(const Primitive& p) + { + m_primitives.push_back(p); + m_need_build = true; + } // Clears tree and insert a set of primitives template template void AABB_tree::rebuild(ConstPrimitiveIterator first, - ConstPrimitiveIterator beyond) + ConstPrimitiveIterator beyond) { // cleanup current tree and internal KD tree clear(); // inserts primitives - while(first != beyond) - { - m_primitives.push_back(Primitive(first)); - first++; - } + insert(first, beyond); + + build(); + } + + // Build the data structure, after calls to insert(..) + template + void AABB_tree::build() + { + clear_nodes(); + + CGAL_assertion(m_primitives.size() > 1); // allocates tree nodes m_p_root_node = new Node[m_primitives.size()-1](); if(m_p_root_node == NULL) { std::cerr << "Unable to allocate memory for AABB tree" << std::endl; - m_primitives.clear(); + CGAL_assertion(m_p_root_node != NULL); + m_primitives.clear(); clear(); } // constructs the tree m_p_root_node->expand(m_primitives.begin(), m_primitives.end(), m_primitives.size()); + + m_need_build = false; + + // In case the users has switched on the acceletated distance query + // data structure with the default arguments, then it has to be + // rebuilt. + if(m_default_search_tree_constructed) + accelerate_distance_queries(); } @@ -515,7 +329,7 @@ namespace CGAL { template template bool AABB_tree::accelerate_distance_queries(ConstPointIterator first, - ConstPointIterator beyond) + ConstPointIterator beyond) const { // clears current KD tree clear_search_tree(); @@ -535,7 +349,7 @@ namespace CGAL { // constructs the search KD tree from internal primitives template - bool AABB_tree::accelerate_distance_queries() + bool AABB_tree::accelerate_distance_queries() const { CGAL_assertion(!m_primitives.empty()); @@ -545,6 +359,7 @@ namespace CGAL { for(it = m_primitives.begin(); it != m_primitives.end(); ++it) points.push_back(Point_and_primitive_id(it->reference_point(), it->id())); + m_default_search_tree_constructed = true; return accelerate_distance_queries(points.begin(), points.end()); } @@ -553,7 +368,9 @@ namespace CGAL { bool AABB_tree::do_intersect(const Query& query) const { - Do_intersect_traits traversal_traits; + using namespace CGAL::internal::AABB_tree; + typedef typename AABB_tree::AABB_traits AABBTraits; + Do_intersect_traits traversal_traits; this->traversal(query, traversal_traits); return traversal_traits.is_intersection_found(); } @@ -563,9 +380,18 @@ namespace CGAL { typename AABB_tree::size_type AABB_tree::number_of_intersected_primitives(const Query& query) const { - Counting_traits traversal_traits; + 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); this->traversal(query, traversal_traits); - return traversal_traits.number_of_intersections(); + return counter; } template @@ -574,7 +400,10 @@ namespace CGAL { AABB_tree::all_intersected_primitives(const Query& query, OutputIterator out) const { - Listing_primitive_traits traversal_traits(out); + using namespace CGAL::internal::AABB_tree; + typedef typename AABB_tree::AABB_traits AABBTraits; + Listing_primitive_traits traversal_traits(out); this->traversal(query, traversal_traits); return out; } @@ -585,7 +414,10 @@ namespace CGAL { AABB_tree::all_intersections(const Query& query, OutputIterator out) const { - Listing_intersection_traits traversal_traits(out); + using namespace CGAL::internal::AABB_tree; + typedef typename AABB_tree::AABB_traits AABBTraits; + Listing_intersection_traits traversal_traits(out); this->traversal(query, traversal_traits); return out; } @@ -595,7 +427,9 @@ namespace CGAL { boost::optional::Object_and_primitive_id> AABB_tree::any_intersection(const Query& query) const { - First_intersection_traits traversal_traits; + using namespace CGAL::internal::AABB_tree; + typedef typename AABB_tree::AABB_traits AABBTraits; + First_intersection_traits traversal_traits; this->traversal(query, traversal_traits); return traversal_traits.result(); } @@ -605,7 +439,9 @@ namespace CGAL { boost::optional::Primitive_id> AABB_tree::any_intersected_primitive(const Query& query) const { - First_primitive_traits traversal_traits; + using namespace CGAL::internal::AABB_tree; + typedef typename AABB_tree::AABB_traits AABBTraits; + First_primitive_traits traversal_traits; this->traversal(query, traversal_traits); return traversal_traits.result(); } @@ -617,9 +453,11 @@ namespace CGAL { const Point& hint) const { typename Primitive::Id hint_primitive = m_primitives[0].id(); - Distance_traits distance_traits(hint,hint_primitive); - this->traversal(query, distance_traits); - return distance_traits.closest_point(); + using namespace CGAL::internal::AABB_tree; + typedef typename AABB_tree::AABB_traits AABBTraits; + Projection_traits projection_traits(hint,hint_primitive); + this->traversal(query, projection_traits); + return projection_traits.closest_point(); } // closest point without hint, the search KD-tree is queried for the @@ -665,11 +503,19 @@ namespace CGAL { AABB_tree::closest_point_and_primitive(const Point& query, const Point_and_primitive_id& hint) const { - Distance_traits distance_traits(hint.first,hint.second); - this->traversal(query, distance_traits); - return distance_traits.closest_point_and_primitive(); + using namespace CGAL::internal::AABB_tree; + typedef typename AABB_tree::AABB_traits AABBTraits; + Projection_traits projection_traits(hint.first,hint.second); + this->traversal(query, projection_traits); + return projection_traits.closest_point_and_primitive(); } } // end namespace CGAL #endif // CGAL_AABB_TREE_H + +/***EMACS SETTINGS***/ +/* Local Variables: */ +/* tab-width: 2 */ +/* End: */ + diff --git a/AABB_tree/include/CGAL/AABB_drawing_traits.h b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_drawing_traits.h similarity index 100% rename from AABB_tree/include/CGAL/AABB_drawing_traits.h rename to AABB_tree/include/CGAL/internal/AABB_tree/AABB_drawing_traits.h diff --git a/AABB_tree/include/CGAL/AABB_node.h b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_node.h similarity index 100% rename from AABB_tree/include/CGAL/AABB_node.h rename to AABB_tree/include/CGAL/internal/AABB_tree/AABB_node.h diff --git a/AABB_tree/include/CGAL/AABB_search_tree.h b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_search_tree.h similarity index 100% rename from AABB_tree/include/CGAL/AABB_search_tree.h rename to AABB_tree/include/CGAL/internal/AABB_tree/AABB_search_tree.h diff --git a/AABB_tree/include/CGAL/internal/AABB_tree/AABB_traversal_traits.h b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_traversal_traits.h new file mode 100644 index 00000000000..7896eb79812 --- /dev/null +++ b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_traversal_traits.h @@ -0,0 +1,328 @@ +// Copyright (c) 2008-2009 INRIA Sophia-Antipolis (France), ETH Zurich (Switzerland). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Camille Wormser, Pierre Alliez, Stephane Tayeb + +#ifndef CGAL_AABB_TRAVERSAL_TRAITS_H +#define CGAL_AABB_TRAVERSAL_TRAITS_H + +#include +#include +#include + +namespace CGAL { + +template class AABB_tree; + +namespace internal { namespace AABB_tree { + +template +class Counting_output_iterator { + typedef Counting_output_iterator Self; + Integral_type* i; +public: + Counting_output_iterator(Integral_type* i_) : i(i_) {}; + + struct Proxy { + Proxy& operator=(const Value_type&) { return *this; }; + }; + + Proxy operator*() { + return Proxy(); + } + + Self& operator++() { + ++*i; + return *this; + } + + Self& operator++(int) { + ++*i; + return *this; + } +}; + +//------------------------------------------------------- +// Traits classes for traversal computation +//------------------------------------------------------- +/** + * @class First_intersection_traits + */ +template +class First_intersection_traits +{ + typedef typename AABBTraits::FT FT; + typedef typename AABBTraits::Point Point; + typedef typename AABBTraits::Primitive Primitive; + typedef typename AABBTraits::Bounding_box Bounding_box; + typedef typename AABBTraits::Primitive::Id Primitive_id; + typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; + typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; + typedef ::CGAL::AABB_node Node; + typedef typename ::CGAL::AABB_tree::size_type size_type; + +public: + typedef typename boost::optional Result; +public: + First_intersection_traits() + : m_result() + {} + + bool go_further() const { return !m_result; } + + void intersection(const Query& query, const Primitive& primitive) + { + m_result = AABBTraits().intersection_object()(query, primitive); + } + + bool do_intersect(const Query& query, const Node& node) const + { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + + Result result() const { return m_result; } + bool is_intersection_found() const { return m_result; } + +private: + Result m_result; +}; + + +/** + * @class Listing_intersection_traits + */ +template +class Listing_intersection_traits +{ + typedef typename AABBTraits::FT FT; + typedef typename AABBTraits::Point Point; + typedef typename AABBTraits::Primitive Primitive; + typedef typename AABBTraits::Bounding_box Bounding_box; + typedef typename AABBTraits::Primitive::Id Primitive_id; + typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; + typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; + typedef ::CGAL::AABB_node Node; + typedef typename ::CGAL::AABB_tree::size_type size_type; + +public: + Listing_intersection_traits(Output_iterator out_it) + : m_out_it(out_it) {} + + bool go_further() const { return true; } + + void intersection(const Query& query, const Primitive& primitive) + { + boost::optional intersection; + intersection = AABBTraits().intersection_object()(query, primitive); + if(intersection) + { + *m_out_it++ = *intersection; + } + } + + bool do_intersect(const Query& query, const Node& node) const + { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + +private: + Output_iterator m_out_it; +}; + + +/** + * @class Listing_primitive_traits + */ +template +class Listing_primitive_traits +{ + typedef typename AABBTraits::FT FT; + typedef typename AABBTraits::Point Point; + typedef typename AABBTraits::Primitive Primitive; + typedef typename AABBTraits::Bounding_box Bounding_box; + typedef typename AABBTraits::Primitive::Id Primitive_id; + typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; + typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; + typedef ::CGAL::AABB_node Node; + typedef typename ::CGAL::AABB_tree::size_type size_type; + +public: + Listing_primitive_traits(Output_iterator out_it) + : m_out_it(out_it) {} + + bool go_further() const { return true; } + + void intersection(const Query& query, const Primitive& primitive) + { + if( AABBTraits().do_intersect_object()(query, primitive) ) + { + *m_out_it++ = primitive.id(); + } + } + + bool do_intersect(const Query& query, const Node& node) const + { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + +private: + Output_iterator m_out_it; +}; + + +/** + * @class First_primitive_traits + */ +template +class First_primitive_traits +{ + typedef typename AABBTraits::FT FT; + typedef typename AABBTraits::Point Point; + typedef typename AABBTraits::Primitive Primitive; + typedef typename AABBTraits::Bounding_box Bounding_box; + typedef typename AABBTraits::Primitive::Id Primitive_id; + typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; + typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; + typedef ::CGAL::AABB_node Node; + typedef typename ::CGAL::AABB_tree::size_type size_type; + +public: + First_primitive_traits() + : m_is_found(false) + , m_result() {} + + bool go_further() const { return !m_is_found; } + + void intersection(const Query& query, const Primitive& primitive) + { + if( AABBTraits().do_intersect_object()(query, primitive) ) + { + m_result = boost::optional(primitive.id()); + m_is_found = true; + } + } + + bool do_intersect(const Query& query, const Node& node) const + { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + + boost::optional result() const { return m_result; } + bool is_intersection_found() const { return m_is_found; } + +private: + bool m_is_found; + boost::optional m_result; +}; + +/** + * @class Do_intersect_traits + */ +template +class Do_intersect_traits +{ + typedef typename AABBTraits::FT FT; + typedef typename AABBTraits::Point Point; + typedef typename AABBTraits::Primitive Primitive; + typedef typename AABBTraits::Bounding_box Bounding_box; + typedef typename AABBTraits::Primitive::Id Primitive_id; + typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; + typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; + typedef ::CGAL::AABB_node Node; + typedef typename ::CGAL::AABB_tree::size_type size_type; + +public: + Do_intersect_traits() + : m_is_found(false) + {} + + bool go_further() const { return !m_is_found; } + + void intersection(const Query& query, const Primitive& primitive) + { + if( AABBTraits().do_intersect_object()(query, primitive) ) + m_is_found = true; + } + + bool do_intersect(const Query& query, const Node& node) const + { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + + bool is_intersection_found() const { return m_is_found; } + +private: + bool m_is_found; +}; + + +/** + * @class Projection_traits + */ +template +class Projection_traits +{ + typedef typename AABBTraits::FT FT; + typedef typename AABBTraits::Point Point; + typedef typename AABBTraits::Primitive Primitive; + typedef typename AABBTraits::Bounding_box Bounding_box; + typedef typename AABBTraits::Primitive::Id Primitive_id; + typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; + typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; + typedef ::CGAL::AABB_node Node; + typedef typename ::CGAL::AABB_tree::size_type size_type; + +public: + Projection_traits(const Point& hint, + const typename Primitive::Id& hint_primitive) + : m_closest_point(hint), + m_closest_primitive(hint_primitive) + {} + + bool go_further() const { return true; } + + void intersection(const Point& query, const Primitive& primitive) + { + Point new_closest_point = AABBTraits().closest_point_object() + (query, primitive, m_closest_point); + if(new_closest_point != m_closest_point) + { + m_closest_primitive = primitive.id(); + m_closest_point = new_closest_point; // this effectively shrinks the sphere + } + } + + bool do_intersect(const Point& query, const Node& node) const + { + return AABBTraits().compare_distance_object() + (query, node.bbox(), m_closest_point) == CGAL::SMALLER; + } + + Point closest_point() const { return m_closest_point; } + Point_and_primitive_id closest_point_and_primitive() const + { + return Point_and_primitive_id(m_closest_point, m_closest_primitive); + } + +private: + Point m_closest_point; + typename Primitive::Id m_closest_primitive; +}; + +}}} // end namespace CGAL::internal::AABB_tree + +#endif // CGAL_AABB_TRAVERSAL_TRAITS_H