Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 7 additions & 27 deletions AABB_tree/benchmark/AABB_tree/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,31 +1,11 @@
# Created by the script cgal_create_CMakeLists
# This is the CMake script for compiling a set of CGAL applications.
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.

cmake_minimum_required(VERSION 3.1...3.15)
project( AABB_traits_benchmark)
cmake_minimum_required(VERSION 3.1...3.14)
project( AABB_traits_benchmark )

# CGAL and its components
find_package( CGAL QUIET)
if ( CGAL_FOUND )
include( ${CGAL_USE_FILE} )
else ()
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()

endif()


# Boost and its components
find_package( Boost REQUIRED )
# include for local directory
if ( NOT Boost_FOUND )
message(STATUS "This project requires the Boost library, and will not be compiled.")
return()
endif()

# include for local package
include_directories( BEFORE ../../include )

add_executable (test_ test.cpp)
find_package(CGAL REQUIRED QUIET OPTIONAL_COMPONENTS Core )

create_single_source_cgal_program( "test.cpp" )
create_single_source_cgal_program( "tree_construction.cpp" )

124 changes: 124 additions & 0 deletions AABB_tree/benchmark/AABB_tree/tree_construction.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/Polygon_mesh_processing/bbox.h>

#include <CGAL/Timer.h>

#include <iostream>
#include <fstream>

int longest_axis(const CGAL::Bbox_3& bbox)
{
const double dx = bbox.xmax() - bbox.xmin();
const double dy = bbox.ymax() - bbox.ymin();
const double dz = bbox.zmax() - bbox.zmin();
return (dx>=dy) ? ((dx>=dz) ? 0 : 2) : ((dy>=dz) ? 1 : 2);
}

template <class RPM>
struct Split_primitives
{
Split_primitives(RPM rpm)
: rpm(rpm)
{}

template<typename PrimitiveIterator>
void operator()(PrimitiveIterator first,
PrimitiveIterator beyond,
const CGAL::Bbox_3& bbox) const
{
PrimitiveIterator middle = first + (beyond - first)/2;
typedef typename std::iterator_traits<PrimitiveIterator>::value_type Primitive;
const int crd=longest_axis(bbox);
const RPM& l_rpm=rpm;
std::nth_element(first, middle, beyond,
[l_rpm, crd](const Primitive& p1, const Primitive& p2){ return get(l_rpm, p1.id())[crd] < get(l_rpm, p2.id())[crd];});
}
RPM rpm;
};

template <class BBM>
struct Compute_bbox {
Compute_bbox(const BBM& bbm)
: bbm(bbm)
{}

template<typename ConstPrimitiveIterator>
CGAL::Bbox_3 operator()(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond) const
{
CGAL::Bbox_3 bbox = get(bbm, first->id());
for(++first; first != beyond; ++first)
{
bbox += get(bbm, first->id());
}
return bbox;
}
BBM bbm;
};

template <class K>
void run(std::string input)
{
typedef typename K::Point_3 Point_3;
typedef CGAL::Surface_mesh<Point_3> Mesh;
typedef CGAL::AABB_face_graph_triangle_primitive<Mesh> Primitive;
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Tree;

Mesh tm;
std::ifstream(input) >> tm;

{
Tree tree(faces(tm).begin(), faces(tm).end(), tm);
CGAL::Timer time;
time.start();
tree.build();
time.stop();
std::cout << " build() time: " << time.time() << "\n";
}

{
Tree tree(faces(tm).begin(), faces(tm).end(), tm);
CGAL::Timer time;
time.start();

typedef CGAL::Pointer_property_map<CGAL::Bbox_3>::type BBM;
typedef CGAL::Pointer_property_map<CGAL::Epick::Point_3>::type RPM; // EPIC on purpose here

std::vector<CGAL::Bbox_3> v_bb;
std::vector<CGAL::Epick::Point_3> v_rp;

std::size_t nbf = num_faces(tm);
v_bb.resize(nbf);
v_rp.resize(nbf);
BBM bbm = CGAL::make_property_map(v_bb);
RPM rpm = CGAL::make_property_map(v_rp);

CGAL::Cartesian_converter<K, CGAL::Epick> to_input;
for(typename Mesh::Face_index f : tm.faces())
{
v_bb[f]=CGAL::Polygon_mesh_processing::face_bbox(f, tm);
v_rp[f]=to_input(tm.point(target(halfedge(f, tm), tm)));
}

Compute_bbox<BBM> compute_bbox(bbm);
Split_primitives<RPM> split_primitives(rpm);
tree.custom_build(compute_bbox, split_primitives);
time.stop();
std::cout << " custom_build() time: " << time.time() << "\n";
}
}

int main(int, char** argv)
{
std::cout << "Build with Epick\n";
run<CGAL::Epick>(argv[1]);
std::cout << "Build with Epeck\n";
run<CGAL::Epeck>(argv[1]);
return EXIT_SUCCESS;
}
24 changes: 12 additions & 12 deletions AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,62 +132,62 @@ typedef unspecified_type Equal_3;
/// @{

/*!
Returns the intersection detection functor.
returns the intersection detection functor.
*/
Do_intersect_3 do_intersect_3_object();

/*!
Returns the intersection constructor.
returns the intersection constructor.
*/
Intersect_3 intersect_3_object();

/*!
Returns the sphere constructor.
returns the sphere constructor.
*/
Construct_sphere_3 construct_sphere_3_object();

/*!
Returns the closest point constructor.
returns the closest point constructor.
*/
Construct_projected_point_3 construct_projected_point_3_object();

/*!
Returns the compare distance constructor.
returns the compare distance constructor.
*/
Compare_distance_3 compare_distance_3_object();

/*!
Returns the closest point constructor.
returns the closest point constructor.
*/
Has_on_bounded_side_3 has_on_bounded_side_3_object();

/*!
Returns the squared radius functor.
returns the squared radius functor.
*/
Compute_squared_radius_3 compute_squared_radius_3_object();

/*!
Returns the squared distance functor.
returns the squared distance functor.
*/
Compute_squared_distance_3 compute_squared_distance_3_object();

/*!
Returns the `Less_x_3` functor.
returns the `Less_x_3` functor.
*/
Less_x_3 less_x_3_object();

/*!
Returns the `Less_y_3` functor.
returns the `Less_y_3` functor.
*/
Less_y_3 less_y_3_object();

/*!
Returns the `Less_z_3` functor.
returns the `Less_z_3` functor.
*/
Less_z_3 less_z_3_object();

/*!
Returns the equal functor.
returns the equal functor.
*/
Equal_3 equal_3_object();

Expand Down
6 changes: 3 additions & 3 deletions AABB_tree/doc/AABB_tree/Concepts/AABBPrimitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,17 @@ typedef unspecified_type Id;
/// @{

/*!
Returns the datum (geometric object) represented by the primitive.
returns the datum (geometric object) represented by the primitive.
*/
Datum_reference datum();

/*!
Returns the corresponding identifier. This identifier is only used as a reference for the objects in the output of the `AABB_tree` methods.
returns the corresponding identifier. This identifier is only used as a reference for the objects in the output of the `AABB_tree` methods.
*/
Id id();

/*!
Returns a 3D point located on the geometric object represented by the primitive. This function is used to sort the primitives during the AABB tree construction as well as to construct the search KD-tree internal to the AABB tree used to accelerate distance queries.
returns a 3D point located on the geometric object represented by the primitive. This function is used to sort the primitives during the AABB tree construction as well as to construct the search KD-tree internal to the AABB tree used to accelerate distance queries.
*/
Point_reference reference_point();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,22 @@ typedef unspecified_type Shared_data;
/// \name Operations
/// @{
/*!
Returns the datum (geometric object) represented by the primitive.
returns the datum (geometric object) represented by the primitive.
*/
Datum_reference datum(const Shared_data& data);

/*!
Returns the corresponding identifier. This identifier is only used as a reference for the objects in the output of the `AABB_tree` methods.
returns the corresponding identifier. This identifier is only used as a reference for the objects in the output of the `AABB_tree` methods.
*/
Id id();

/*!
Returns a 3D point located on the geometric object represented by the primitive. This function is used to sort the primitives during the AABB tree construction as well as to construct the search KD-tree internal to the AABB tree used to accelerate distance queries.
returns a 3D point located on the geometric object represented by the primitive. This function is used to sort the primitives during the AABB tree construction as well as to construct the search KD-tree internal to the AABB tree used to accelerate distance queries.
*/
Point_reference reference_point(const Shared_data& data);

/*!
A static function responsible for the creation of the shared data of a primitive.
constructs the shared data of a primitive.
The parameter pack is such that there exists a constructor `template <class T1, class ... T> AABBPrimitiveWithSharedData (T1,T...)`.
*/
template <class ... T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class AABBRayIntersectionTraits {
typedef unspecified_type Intersection_distance;

/*!
Returns the intersection distance functor.
returns the intersection distance functor.
*/
Intersection_distance intersection_distance_object() const ;
};
18 changes: 9 additions & 9 deletions AABB_tree/doc/AABB_tree/Concepts/AABBTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,42 +164,42 @@ typedef unspecified_type Equal_3;
/// @{

/*!
Returns the primitive splitting functor.
returns the primitive splitting functor.
*/
Split_primitives split_primitives_object();

/*!
Returns the bounding box constructor.
returns the bounding box constructor.
*/
Compute_bbox compute_bbox_object();

/*!
Returns the intersection detection functor.
returns the intersection detection functor.
*/
Do_intersect do_intersect_object();

/*!
Returns the intersection constructor.
returns the intersection constructor.
*/
Intersection intersection_object();

/*!
Returns the distance comparison functor.
returns the distance comparison functor.
*/
Compare_distance compare_distance_object();

/*!
Returns the closest point constructor.
returns the closest point constructor.
*/
Closest_point closest_point_object();

/*!
Returns the squared distance functor.
returns the squared distance functor.
*/
Squared_distance squared_distance_object();

/*!
Returns the equal functor.
returns the equal functor.
*/
Equal_3 equal_3_object();

Expand All @@ -220,7 +220,7 @@ void set_shared_data(T ... t);
{}

/*!
Returns the shared data of the primitive constructed after a call to `set_shared_data`.
returns the shared data of the primitive constructed after a call to `set_shared_data`.
If no call to `set_shared_data` has been done, `Primitive::Shared_data()` is returned.
*/
const Primitive::Shared_data& shared_data() const;
Expand Down
13 changes: 7 additions & 6 deletions AABB_tree/doc/AABB_tree/aabb_tree.txt
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ inside the bounding box.
The experiments described above are neither exhaustive nor conclusive
as we have chosen one specific case where the input primitives are the
facets of a triangle surface polyhedron. Nevertheless we now provide
some general observations and advices about how to put the AABB tree
some general observations and advises about how to put the AABB tree
to use with satisfactory performances. While the tree construction
times and memory occupancy do not fluctuate much in our experiments
depending on the input surface triangle mesh, the performance
Expand Down Expand Up @@ -423,21 +423,22 @@ primitives at the leafs of the tree. The ball radius is then shrunk to
the distance between `p` and `q` for all remaining recursive
traversals of the tree. Efficiency is achieved through setting the
initial ball radius to a small value still guaranteed to intersect the
input primitives. This is achieved by constructing through the
function `AABB_tree::accelerate_distance_queries()` an internal secondary data
input primitives. This is achieved by constructing an internal secondary data
structure which provides a good hint to the algorithm at the beginning
of the traversal.
of the traversal (done by default).
Calling `do_not_accelerate_distance_queries()` will disable
the construction and the usage of this internal secondary data structure.

\section aabb_tree_history Design and Implementation History

Camille Wormser and Pierre Alliez started working on a data structure
for efficient collision detection in 2007. The generic design for
implementing both intersection and distance queries, and for generic
queries and primitives was developed by Camille Wormser. In 2009,
Pierre Alliez, St&eacute;phane Tayeb and Camille Wormser made the
Pierre Alliez, Stéphane Tayeb and Camille Wormser made the
implementation CGAL-compliant, with the help of Laurent Rineau for
optimizing the tree construction. The authors wish to thank Andreas
Fabri, Jane Tournois, Mariette Yvinec and Sylvain Lef&egrave;bvre for
Fabri, Jane Tournois, Mariette Yvinec and Sylvain Lefèbvre for
helpful comments and discussions.

*/
Expand Down
Loading