merge from candidate branch.

This commit is contained in:
Sébastien Loriot 2011-01-10 10:46:16 +00:00
parent a389c224a5
commit 12e8540bbe
20 changed files with 588 additions and 496 deletions

2
.gitattributes vendored
View File

@ -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

1
.gitignore vendored
View File

@ -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

View File

@ -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}.

View File

@ -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 <class InputIterator>
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

View File

@ -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 <iostream>
#include <list>
#include <CGAL/AABB_tree.h> // must be inserted before kernel
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> K;

View File

@ -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 <iostream>
#include <list>
#include <boost/iterator.hpp>
#include <CGAL/AABB_tree.h> // must be inserted before kernel
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> K;

View File

@ -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 <iostream>
#include <list>
#include <boost/iterator.hpp>
#include <CGAL/AABB_tree.h> // must be inserted before kernel
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> K;

View File

@ -0,0 +1,52 @@
#include <iostream>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h> // must be inserted before kernel
#include <CGAL/AABB_traits.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/AABB_polyhedron_triangle_primitive.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;
typedef K::Point_3 Point;
typedef K::Segment_3 Segment;
typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::AABB_polyhedron_triangle_primitive<K,Polyhedron> Primitive;
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> 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;
}

View File

@ -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 <iostream>
#include <CGAL/AABB_tree.h> // must be inserted before kernel
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/AABB_polyhedron_segment_primitive.h>
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;

View File

@ -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 <iostream>
#include <CGAL/AABB_tree.h> // must be inserted before kernel
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/AABB_polyhedron_triangle_primitive.h>
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;
typedef K::Point_3 Point;

View File

@ -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 <iostream>
#include <CGAL/AABB_tree.h> // must be inserted before kernel
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/AABB_polyhedron_triangle_primitive.h>
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point;
typedef K::Plane_3 Plane;

View File

@ -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 <iostream>
#include <list>
#include <CGAL/AABB_tree.h> // must be inserted before kernel
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_segment_primitive.h>
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;

View File

@ -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 <iostream>
#include <list>
#include <CGAL/AABB_tree.h> // must be inserted before kernel
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_triangle_primitive.h>
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;

View File

@ -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()

View File

@ -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 <class Solid>
@ -204,6 +205,16 @@ Intersection intersection_object() {return Intersection();}
(p, GeomTraits().compute_squared_distance_3_object()(p, bound)), pr)?
CGAL::SMALLER : CGAL::LARGER;
}
template <class Solid>
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();}

View File

@ -22,9 +22,10 @@
#include <vector>
#include <iterator>
#include <CGAL/internal/AABB_tree/AABB_traversal_traits.h>
#include <CGAL/internal/AABB_tree/AABB_node.h>
#include <CGAL/internal/AABB_tree/AABB_search_tree.h>
#include <boost/optional.hpp>
#include <CGAL/AABB_node.h>
#include <CGAL/AABB_search_tree.h>
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<typename ConstPrimitiveIterator>
void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond);
/// Add primitives in the structure. build() must be called before any
/// request.
template<typename ConstPrimitiveIterator>
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<typename ConstPointIterator>
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<typename Query>
@ -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<Traversal_traits,Query>(query, traits, m_primitives.size());
root_node()->template traversal<Traversal_traits,Query>(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<AABBTraits> Node;
//-------------------------------------------------------
// Traits classes for traversal computation
//-------------------------------------------------------
/**
* @class First_intersection_traits
*/
template<typename Query>
class First_intersection_traits
{
public:
typedef typename boost::optional<Object_and_primitive_id> 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<typename Query>
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<typename Query, typename Output_iterator>
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<Object_and_primitive_id> 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<typename Query, typename Output_iterator>
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<typename Query>
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<typename Primitive::Id>(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<typename Primitive::Id> result() const { return m_result; }
bool is_intersection_found() const { return m_is_found; }
private:
bool m_is_found;
boost::optional<typename Primitive::Id> m_result;
};
/**
* @class Do_intersect_traits
*/
template<typename Query>
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<AABBTraits>* >(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<typename Tr>
template<typename ConstPrimitiveIterator>
AABB_tree<Tr>::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<typename Tr>
template<typename ConstPrimitiveIterator>
void AABB_tree<Tr>::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<typename Tr>
void AABB_tree<Tr>::insert(const Primitive& p)
{
m_primitives.push_back(p);
m_need_build = true;
}
// Clears tree and insert a set of primitives
template<typename Tr>
template<typename ConstPrimitiveIterator>
void AABB_tree<Tr>::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<typename Tr>
void AABB_tree<Tr>::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<typename Tr>
template<typename ConstPointIterator>
bool AABB_tree<Tr>::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<typename Tr>
bool AABB_tree<Tr>::accelerate_distance_queries()
bool AABB_tree<Tr>::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<Tr>::do_intersect(const Query& query) const
{
Do_intersect_traits<Query> traversal_traits;
using namespace CGAL::internal::AABB_tree;
typedef typename AABB_tree<Tr>::AABB_traits AABBTraits;
Do_intersect_traits<AABBTraits, Query> traversal_traits;
this->traversal(query, traversal_traits);
return traversal_traits.is_intersection_found();
}
@ -563,9 +380,18 @@ namespace CGAL {
typename AABB_tree<Tr>::size_type
AABB_tree<Tr>::number_of_intersected_primitives(const Query& query) const
{
Counting_traits<Query> traversal_traits;
using namespace CGAL::internal::AABB_tree;
using CGAL::internal::AABB_tree::Counting_output_iterator;
typedef typename AABB_tree<Tr>::AABB_traits AABBTraits;
typedef Counting_output_iterator<Primitive_id, size_type> Counting_iterator;
size_type counter = 0;
Counting_iterator out(&counter);
Listing_primitive_traits<AABBTraits,
Query, Counting_iterator> traversal_traits(out);
this->traversal(query, traversal_traits);
return traversal_traits.number_of_intersections();
return counter;
}
template<typename Tr>
@ -574,7 +400,10 @@ namespace CGAL {
AABB_tree<Tr>::all_intersected_primitives(const Query& query,
OutputIterator out) const
{
Listing_primitive_traits<Query, OutputIterator> traversal_traits(out);
using namespace CGAL::internal::AABB_tree;
typedef typename AABB_tree<Tr>::AABB_traits AABBTraits;
Listing_primitive_traits<AABBTraits,
Query, OutputIterator> traversal_traits(out);
this->traversal(query, traversal_traits);
return out;
}
@ -585,7 +414,10 @@ namespace CGAL {
AABB_tree<Tr>::all_intersections(const Query& query,
OutputIterator out) const
{
Listing_intersection_traits<Query, OutputIterator> traversal_traits(out);
using namespace CGAL::internal::AABB_tree;
typedef typename AABB_tree<Tr>::AABB_traits AABBTraits;
Listing_intersection_traits<AABBTraits,
Query, OutputIterator> traversal_traits(out);
this->traversal(query, traversal_traits);
return out;
}
@ -595,7 +427,9 @@ namespace CGAL {
boost::optional<typename AABB_tree<Tr>::Object_and_primitive_id>
AABB_tree<Tr>::any_intersection(const Query& query) const
{
First_intersection_traits<Query> traversal_traits;
using namespace CGAL::internal::AABB_tree;
typedef typename AABB_tree<Tr>::AABB_traits AABBTraits;
First_intersection_traits<AABBTraits, Query> traversal_traits;
this->traversal(query, traversal_traits);
return traversal_traits.result();
}
@ -605,7 +439,9 @@ namespace CGAL {
boost::optional<typename AABB_tree<Tr>::Primitive_id>
AABB_tree<Tr>::any_intersected_primitive(const Query& query) const
{
First_primitive_traits<Query> traversal_traits;
using namespace CGAL::internal::AABB_tree;
typedef typename AABB_tree<Tr>::AABB_traits AABBTraits;
First_primitive_traits<AABBTraits, Query> 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<Tr>::AABB_traits AABBTraits;
Projection_traits<AABBTraits> 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<Tr>::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<Tr>::AABB_traits AABBTraits;
Projection_traits<AABBTraits> 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: */

View File

@ -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 <CGAL/AABB_tree.h>
#include <CGAL/internal/AABB_tree/AABB_node.h>
#include <boost/optional.hpp>
namespace CGAL {
template <typename AABBTraits> class AABB_tree;
namespace internal { namespace AABB_tree {
template <class Value_type, typename Integral_type>
class Counting_output_iterator {
typedef Counting_output_iterator<Value_type,Integral_type> 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<typename AABBTraits, typename Query>
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<AABBTraits> Node;
typedef typename ::CGAL::AABB_tree<AABBTraits>::size_type size_type;
public:
typedef typename boost::optional<Object_and_primitive_id> 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<typename AABBTraits, typename Query, typename Output_iterator>
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<AABBTraits> Node;
typedef typename ::CGAL::AABB_tree<AABBTraits>::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<Object_and_primitive_id> 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<typename AABBTraits, typename Query, typename Output_iterator>
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<AABBTraits> Node;
typedef typename ::CGAL::AABB_tree<AABBTraits>::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<typename AABBTraits, typename Query>
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<AABBTraits> Node;
typedef typename ::CGAL::AABB_tree<AABBTraits>::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<typename Primitive::Id>(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<typename Primitive::Id> result() const { return m_result; }
bool is_intersection_found() const { return m_is_found; }
private:
bool m_is_found;
boost::optional<typename Primitive::Id> m_result;
};
/**
* @class Do_intersect_traits
*/
template<typename AABBTraits, typename Query>
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<AABBTraits> Node;
typedef typename ::CGAL::AABB_tree<AABBTraits>::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 <typename AABBTraits>
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<AABBTraits> Node;
typedef typename ::CGAL::AABB_tree<AABBTraits>::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