AABB tree: added two examples (one compiles fine)

This commit is contained in:
Pierre Alliez 2009-04-24 14:11:17 +00:00
parent aeb4889551
commit ce4a6039f5
10 changed files with 1728 additions and 135 deletions

2
.gitattributes vendored
View File

@ -24,6 +24,8 @@ AABB_tree/include/CGAL/Triangle_3_line_3_intersection.h -text
AABB_tree/test/AABB_tree/CMakeLists.txt -text
AABB_tree/test/AABB_tree/aabb_intersection_test.cpp -text
AABB_tree/test/AABB_tree/aabb_projection_test.cpp -text
AABB_tree/test/AABB_tree/data/anchor.off -text
AABB_tree/test/AABB_tree/data/cube.off -text
Algebraic_foundations/doc_tex/Algebraic_foundations/Algebraic_foundations.png -text
Algebraic_foundations/doc_tex/Algebraic_foundations/Algebraic_foundations2.png -text
Algebraic_foundations/doc_tex/Algebraic_foundations/algebraic_structures.tex -text

View File

@ -26,7 +26,6 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_triangle_primitive.h>
#include <CGAL/AABB_tree.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
@ -35,19 +34,21 @@ typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef K::FT FT;
typedef K::Ray_3 Ray;
typedef K::Point_3 Point;
typedef K::Vector_3 Vector;
class Polyhedron_triangle_primitive
{
// type
// types
public:
typedef K::Triangle_3 Object; // object type
typedef Polyhedron::Facet_handle Id; // Id type
// member data
// member data
private:
Id m_handle; // Facet_handle
Object m_object; // 3D triangle
public:
Polyhedron_triangle_primitive(Id handle)
: m_handle(handle)
{
@ -56,13 +57,13 @@ private:
const Point& c = handle->halfedge()->prev()->vertex()->point();
m_object = Object(a,b,c);
}
public:
Object object() { return m_object; }
const Object& object() const { return m_object; }
Object& object() { return m_object; }
Id id() { return m_handle; }
};
typedef AABB_traits<K, Polyhedron_triangle_primitive> AABB_Polyhedron_traits;
typedef AABB_tree<AABB_Polyhedron_traits> Polyhedron_tree;
typedef CGAL::AABB_traits<K, Polyhedron_triangle_primitive> AABB_Polyhedron_traits;
typedef CGAL::AABB_tree<AABB_Polyhedron_traits> Polyhedron_tree;
int main(void)
{

View File

@ -23,9 +23,9 @@
//******************************************************************************
#include <iostream>
#include <list>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_triangle_primitive.h>
#include <CGAL/AABB_tree.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
@ -48,20 +48,22 @@ private:
Id m_it; // iterator
Object m_object; // 3D triangle
public:
Triangle_primitive(Id it)
: m_it(it)
{
m_object = *it; // copy triangle
}
public:
Object object() { return m_object; }
const Object& object() const { return m_object; }
Object& object() { return m_object; }
Id id() { return m_it; }
};
typedef std::list<Triangle>::iterator Iterator;
typedef typename Triangle_primitive<Iterator> Primitive;
typedef AABB_traits<K, Primitive> AABB_triangle_traits;
typedef AABB_tree<AABB_triangle_traits> Polyhedron_tree;
typedef std::list<typename Triangle>::iterator Iterator;
typedef Triangle_primitive<Iterator> Primitive;
typedef CGAL::AABB_traits<typename K, typename Primitive> AABB_triangle_traits;
typedef CGAL::AABB_tree<typename AABB_triangle_traits> Polyhedron_tree;
int main(void)
{

View File

@ -1,12 +1,11 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
project(AABB_example)
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.5)
include_directories(../../include/CGAL/AABB_tree)
include_directories(../../include/)
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
@ -24,12 +23,11 @@ if ( CGAL_FOUND )
include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program("AABB_polyhedron_facet_example.cpp")
create_single_source_cgal_program("AABB_triangle_3_example.cpp")
create_single_source_cgal_program("AABB_polyhedron_facet_example.cpp")
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif()

View File

@ -1,9 +1,11 @@
#include <CGAL/AABB_tree/Ray_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Bbox_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Segment_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Plane_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Triangle_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Line_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Sphere_3_Bbox_do_intersect.h>
#include <CGAL/AABB_tree/Triangle_3_segment_3_intersection.h>
#include <CGAL/AABB_tree/Triangle_3_ray_3_intersection.h>
// PA: this file will move later to the kernel folder
#include <CGAL/Ray_3_Bbox_3_do_intersect.h>
#include <CGAL/Bbox_3_Bbox_3_do_intersect.h>
#include <CGAL/Segment_3_Bbox_3_do_intersect.h>
#include <CGAL/Plane_3_Bbox_3_do_intersect.h>
#include <CGAL/Triangle_3_Bbox_3_do_intersect.h>
#include <CGAL/Line_3_Bbox_3_do_intersect.h>
#include <CGAL/Sphere_3_Bbox_do_intersect.h>
#include <CGAL/Triangle_3_segment_3_intersection.h>
#include <CGAL/Triangle_3_ray_3_intersection.h>

View File

@ -31,15 +31,7 @@
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/contains.hpp>
#include <CGAL/AABB_tree/Ray_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Bbox_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Segment_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Plane_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Triangle_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Line_3_Bbox_3_do_intersect.h>
#include <CGAL/AABB_tree/Sphere_3_Bbox_do_intersect.h>
#include <CGAL/AABB_tree/Triangle_3_segment_3_intersection.h>
#include <CGAL/AABB_tree/Triangle_3_ray_3_intersection.h>
#include <CGAL/AABB_intersections.h>
namespace CGAL {

View File

@ -26,6 +26,7 @@
#define AABB_TRAITS_H_
#include <CGAL/Bbox_3.h>
#include <CGAL/AABB_intersections.h>
namespace CGAL {
@ -34,7 +35,7 @@ namespace CGAL {
*
*
*/
template<typename GeomTraits, typename Primitive>
template<typename GeomTraits, typename AABB_primitive>
class AABB_traits
{
public:
@ -45,10 +46,14 @@ public:
/// Segment query type
typedef typename GeomTraits::Segment_3 Segment_3;
// TODO: delete once "inside..." disappears
typedef typename GeomTraits::Triangle_3 Triangle_3;
/// AABBTraits concept types
typedef typename CGAL::Bbox_3 Bounding_box;
typedef typename Primitive::Data Data;
typedef typename AABB_primitive Primitive;
typedef typename AABB_primitive::Object Object;
typedef typename GeomTraits::Sphere_3 Sphere;
typedef typename GeomTraits::Point_3 Projection;
@ -121,7 +126,6 @@ private:
/// Private types
typedef typename GeomTraits::FT FT;
typedef typename GeomTraits::Point_3 Point_3;
typedef typename TrianglePrimitive::Triangle_3 Triangle_3;
private:
/**
@ -131,7 +135,7 @@ private:
*/
Bounding_box compute_bbox(const Primitive& pr) const
{
return pr.data().bbox();
return pr.object().bbox();
}
typedef enum { CGAL_AXIS_X = 0,
@ -144,7 +148,7 @@ private:
private:
// Disabled copy constructor & assignment operator
typedef AABB_traits<GeomTraits, TrianglePrimitive> Self;
typedef AABB_traits<GeomTraits, Primitive> Self;
AABB_traits(const Self& src);
Self& operator=(const Self& src);
@ -152,59 +156,59 @@ private:
template<typename GT, typename TP>
template<typename GT, typename P>
bool
AABB_traits<GT,TP>::x_less_than(const Primitive& pr1,
const Primitive& pr2)
AABB_traits<GT,P>::x_less_than(const P& pr1,
const P& pr2)
{
const FT& ax1 = pr1.data().vertex(0).x();
const FT& bx1 = pr1.data().vertex(1).x();
const FT& cx1 = pr1.data().vertex(2).x();
const FT& ax1 = pr1.object().vertex(0).x();
const FT& bx1 = pr1.object().vertex(1).x();
const FT& cx1 = pr1.object().vertex(2).x();
const FT& ax2 = pr2.data().vertex(0).x();
const FT& bx2 = pr2.data().vertex(1).x();
const FT& cx2 = pr2.data().vertex(2).x();
const FT& ax2 = pr2.object().vertex(0).x();
const FT& bx2 = pr2.object().vertex(1).x();
const FT& cx2 = pr2.object().vertex(2).x();
return (ax1+bx1+cx1) < (ax2+bx2+cx2);
}
template<typename GT, typename TP>
template<typename GT, typename P>
bool
AABB_traits<GT,TP>::y_less_than(const Primitive& pr1,
const Primitive& pr2)
AABB_traits<GT,P>::y_less_than(const P& pr1,
const P& pr2)
{
const FT& ay1 = pr1.data().vertex(0).y();
const FT& by1 = pr1.data().vertex(1).y();
const FT& cy1 = pr1.data().vertex(2).y();
const FT& ay1 = pr1.object().vertex(0).y();
const FT& by1 = pr1.object().vertex(1).y();
const FT& cy1 = pr1.object().vertex(2).y();
const FT& ay2 = pr2.data().vertex(0).y();
const FT& by2 = pr2.data().vertex(1).y();
const FT& cy2 = pr2.data().vertex(2).y();
const FT& ay2 = pr2.object().vertex(0).y();
const FT& by2 = pr2.object().vertex(1).y();
const FT& cy2 = pr2.object().vertex(2).y();
return (ay1+by1+cy1) < (ay2+by2+cy2);
}
template<typename GT, typename TP>
template<typename GT, typename P>
bool
AABB_traits<GT,TP>::z_less_than(const Primitive& pr1,
const Primitive& pr2)
AABB_traits<GT,P>::z_less_than(const P& pr1,
const P& pr2)
{
const FT& az1 = pr1.data().vertex(0).z();
const FT& bz1 = pr1.data().vertex(1).z();
const FT& cz1 = pr1.data().vertex(2).z();
const FT& az1 = pr1.object().vertex(0).z();
const FT& bz1 = pr1.object().vertex(1).z();
const FT& cz1 = pr1.object().vertex(2).z();
const FT& az2 = pr2.data().vertex(0).z();
const FT& bz2 = pr2.data().vertex(1).z();
const FT& cz2 = pr2.data().vertex(2).z();
const FT& az2 = pr2.object().vertex(0).z();
const FT& bz2 = pr2.object().vertex(1).z();
const FT& cz2 = pr2.object().vertex(2).z();
return (az1+bz1+cz1) < (az2+bz2+cz2);
}
template<typename GT, typename TP>
template<typename GT, typename P>
template<typename PrimitiveIterator>
void
AABB_traits<GT,TP>::sort_primitives(PrimitiveIterator first,
AABB_traits<GT,P>::sort_primitives(PrimitiveIterator first,
PrimitiveIterator last,
const Bounding_box& bbox) const
{
@ -225,10 +229,10 @@ AABB_traits<GT,TP>::sort_primitives(PrimitiveIterator first,
}
}
template<typename GT, typename TP>
template<typename GT, typename P>
template<typename ConstPrimitiveIterator>
typename AABB_traits<GT,TP>::Bounding_box
AABB_traits<GT,TP>::compute_bbox(ConstPrimitiveIterator first,
typename AABB_traits<GT,P>::Bounding_box
AABB_traits<GT,P>::compute_bbox(ConstPrimitiveIterator first,
ConstPrimitiveIterator last) const
{
Bounding_box bbox = compute_bbox(*first);
@ -240,10 +244,10 @@ AABB_traits<GT,TP>::compute_bbox(ConstPrimitiveIterator first,
}
template<typename GT, typename TP>
template<typename GT, typename P>
template<typename Query>
bool
AABB_traits<GT,TP>::do_intersect(const Query& q,
AABB_traits<GT,P>::do_intersect(const Query& q,
const Bounding_box& bbox) const
{
// AABB tree package call
@ -252,26 +256,26 @@ AABB_traits<GT,TP>::do_intersect(const Query& q,
}
template<typename GT, typename TP>
template<typename GT, typename P>
template<typename Query>
bool
AABB_traits<GT,TP>::do_intersect(const Query& q,
const Primitive& pr) const
AABB_traits<GT,P>::do_intersect(const Query& q,
const P& pr) const
{
return GT().do_intersect_3_object()(q, pr.data());
return GT().do_intersect_3_object()(q, pr.object());
}
template<typename GT, typename TP>
template<typename GT, typename P>
template<typename Query>
bool
AABB_traits<GT,TP>::intersection(const Query& q,
const Primitive& pr,
AABB_traits<GT,P>::intersection(const Query& q,
const P& pr,
Intersection& intersection) const
{
// TODO: implement a real intersection construction method
// do_intersect is needed here because we construct intersection between
// pr.data().supporting_plane() and q
// pr.object().supporting_plane() and q
if ( ! do_intersect(q,pr) )
{
return false;
@ -279,7 +283,8 @@ AABB_traits<GT,TP>::intersection(const Query& q,
// AABB tree package call
// TODO: extend kernel
Object intersection_obj = CGAL::intersection(pr.data(), q);
Object o = pr.object();
CGAL::Object intersection_obj = CGAL::intersection(o, q);
return CGAL::assign(intersection, intersection_obj);
}
@ -287,15 +292,15 @@ AABB_traits<GT,TP>::intersection(const Query& q,
// PA: CAREFUL: the ad-hoc code here must be removed.
template<typename GT, typename TP>
template<typename GT, typename P>
bool
AABB_traits<GT,TP>::intersection(const Sphere& sphere,
const Primitive& pr,
AABB_traits<GT,P>::intersection(const Sphere& sphere,
const P& pr,
Projection& projected) const
{
typedef typename TP::Data Triangle_3;
typedef typename P::Object Triangle_3;
const Triangle_3 triangle = pr.data();
const Triangle_3 triangle = pr.object();
projected = triangle.supporting_plane().projection(sphere.center());
// If point is projected outside sphere, return false
@ -318,9 +323,9 @@ AABB_traits<GT,TP>::intersection(const Sphere& sphere,
}
template<typename GT, typename TP>
template<typename GT, typename P>
bool
AABB_traits<GT,TP>::is_smaller(const Sphere& a, const Sphere& b) const
AABB_traits<GT,P>::is_smaller(const Sphere& a, const Sphere& b) const
{
CGAL_precondition(a.center() == b.center());
@ -333,9 +338,9 @@ AABB_traits<GT,TP>::is_smaller(const Sphere& a, const Sphere& b) const
//-------------------------------------------------------
// Private methods
//-------------------------------------------------------
template<typename GT, typename TP>
typename AABB_traits<GT,TP>::Axis
AABB_traits<GT,TP>::longest_axis(const Bounding_box& bbox) const
template<typename GT, typename P>
typename AABB_traits<GT,P>::Axis
AABB_traits<GT,P>::longest_axis(const Bounding_box& bbox) const
{
const double dx = bbox.xmax() - bbox.xmin();
const double dy = bbox.ymax() - bbox.ymin();
@ -366,9 +371,9 @@ AABB_traits<GT,TP>::longest_axis(const Bounding_box& bbox) const
}
// PA: ad-hoc code to be removed
template<typename GT, typename TP>
template<typename GT, typename P>
bool
AABB_traits<GT,TP>::is_inside_triangle_3(Point_3& p,
AABB_traits<GT,P>::is_inside_triangle_3(Point_3& p,
const Triangle_3& t) const
{
typedef typename GT::Vector_3 Vector;

View File

@ -23,7 +23,7 @@
#include <vector>
#include <iterator>
#include <CGAL/AABB_tree/AABB_node.h>
#include <CGAL/AABB_node.h>
#include <boost/mpl/vector.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/contains.hpp>
@ -43,8 +43,8 @@ public:
typedef typename AABBTraits::Primitive Primitive;
typedef typename AABBTraits::Bounding_box Bounding_box;
typedef typename AABBTraits::Projection_query Projection_query;
typedef typename AABBTraits::Projection_type Projection_type;
typedef typename AABBTraits::Intersection_type Intersection_type;
typedef typename AABBTraits::Projection Projection;
typedef typename AABBTraits::Intersection Intersection;
/**
* @brief Constructor
@ -77,27 +77,27 @@ public:
template<typename Query>
bool any_intersection(const Query& q,
Intersection_type& intersection) const;
Intersection& intersection) const;
template<typename Query, typename OutputIterator>
bool any_intersected_primitive(const Query& q,
Primitive& pr) const;
Projection_type closest_point(const Projection_query& q,
const Projection_type& hint) const;
Projection closest_point(const Projection_query& q,
const Projection& hint) const;
//////////////////////////////////////////////
//TODO: document this
Bounding_box root_bbox() const { return p_root_->bounding_box(); }
bool is_empty() const { return data_.empty(); }
size_t size() const { return data_.size(); }
Bounding_box root_bbox() const { return m_p_root->bounding_box(); }
bool is_empty() const { return m_data.empty(); }
size_t size() const { return m_data.size(); }
/// generic traversal of tree
template <class Query, class Traversal_traits>
void traversal(const Query& q, Traversal_traits& traits) const
{
p_root_->template traversal<Traversal_traits,Query>(q, traits, data_.size());
m_p_root->template traversal<Traversal_traits,Query>(q, traits, m_data.size());
}
//////////////////////////////////////////////
@ -116,14 +116,14 @@ private:
{
public:
First_intersection_traits()
: is_found_(false)
, result_() {}
: m_is_found(false)
, m_result() {}
bool go_further() const { return !is_found_; }
bool go_further() const { return !m_is_found; }
void intersection(const Query& q, const Primitive& primitive)
{
is_found_ = AABBTraits().intersection(q, primitive, result_);
m_is_found = AABBTraits().intersection(q, primitive, m_result);
}
bool do_intersect(const Query& q, const Node& node) const
@ -131,12 +131,12 @@ private:
return AABBTraits().do_intersect(q, node.bounding_box());
}
Intersection_type result() const { return result_; }
bool is_intersection_found() const { return is_found_; }
Intersection result() const { return m_result; }
bool is_intersection_found() const { return m_is_found; }
private:
bool is_found_;
Intersection_type result_;
bool m_is_found;
Intersection m_result;
};
@ -169,7 +169,7 @@ private:
int intersection_number() const { return intersection_nb_; }
private:
Intersection_type intersection_;
Intersection intersection_;
int intersection_nb_;
};
@ -201,7 +201,7 @@ private:
}
private:
Intersection_type intersection_;
Intersection intersection_;
Output_iterator out_it_;
};
@ -233,7 +233,7 @@ private:
}
private:
Intersection_type intersection_;
Intersection intersection_;
Output_iterator out_it_;
};
@ -244,7 +244,7 @@ private:
{
public:
Projecting_traits(const Projection_query& query,
const Projection_type& hint)
const Projection& hint)
: projection_(hint)
, center_(query)
, sphere_(AABBTraits().sphere(query,hint)) { }
@ -256,7 +256,7 @@ private:
// We don't use q here because it is embedded in sphere_ and we don't
// want to compute sphere everytime
Projection_type projection;
Projection projection;
if ( AABBTraits().intersection(sphere_, primitive, projection) )
{
const Sphere sphere = AABBTraits().sphere(center_, projection);
@ -273,10 +273,10 @@ private:
return AABBTraits().do_intersect(sphere_, node.bounding_box());
}
Projection_type projection() const { return projection_; }
Projection projection() const { return projection_; }
private:
Projection_type projection_;
Projection projection_;
Projection_query center_;
Sphere sphere_;
};
@ -284,9 +284,9 @@ private:
private:
// set of input primitives (halfedge or face handles)
std::vector<Primitive> data_;
std::vector<Primitive> m_data;
// single root node
Node* p_root_;
Node* m_p_root;
private:
// Disabled copy constructor & assignment operator
@ -300,26 +300,26 @@ template<typename Tr>
template<typename ConstPrimitiveIterator>
AABB_tree<Tr>::AABB_tree(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond)
: data_()
, p_root_(NULL)
: m_data()
, m_p_root(NULL)
{
// Insert each primitive into tree
// TODO: get number of elements to reserve space ?
while ( first != beyond )
{
data_.push_back(Primitive(first));
m_data.push_back(Primitive(first));
++first;
}
p_root_ = new Node[data_.size()-1]();
p_root_->expand(data_.begin(), data_.end(), data_.size());
m_p_root = new Node[m_data.size()-1]();
m_p_root->expand(m_data.begin(), m_data.end(), m_data.size());
}
template<typename Tr>
AABB_tree<Tr>::~AABB_tree()
{
delete[] p_root_;
delete[] m_p_root;
}
@ -353,8 +353,8 @@ AABB_tree<Tr>::number_of_intersections(const Query& query) const
template<typename Tr>
template<typename Query, typename OutputIterator>
OutputIterator
AABB_tree<Tr>::intersected_primitives(const Query& query,
OutputIterator out) const
AABB_tree<Tr>::all_intersected_primitives(const Query& query,
OutputIterator out) const
{
typedef Listing_primitive_traits<Query, OutputIterator> Traversal_traits;
Traversal_traits traversal_traits(out);
@ -363,8 +363,6 @@ AABB_tree<Tr>::intersected_primitives(const Query& query,
return out;
}
template<typename Tr>
template<typename Query, typename OutputIterator>
OutputIterator
@ -383,7 +381,7 @@ template<typename Tr>
template<typename Query>
bool
AABB_tree<Tr>::any_intersection(const Query& query,
Intersection_type& intersection) const
Intersection& intersection) const
{
typedef First_intersection_traits<Query> Traversal_traits;
Traversal_traits traversal_traits;
@ -396,9 +394,9 @@ AABB_tree<Tr>::any_intersection(const Query& query,
template<typename Tr>
typename AABB_tree<Tr>::Projection_type
typename AABB_tree<Tr>::Projection
AABB_tree<Tr>::closest_point(const Projection_query& query,
const Projection_type& hint) const
const Projection& hint) const
{
Projecting_traits traversal_traits(query,hint);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
OFF
8 12 0
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0
1.0 0.0 1.0
1.0 1.0 1.0
0.0 1.0 1.0
3 0 1 3
3 3 1 2
3 0 4 1
3 1 4 5
3 3 2 7
3 7 2 6
3 4 0 3
3 7 4 3
3 6 4 7
3 6 5 4
3 1 5 6
3 2 1 6