From 729ba7be05a520bb679fdb76f3fb46b9773aebc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tayeb?= Date: Mon, 18 May 2009 14:26:29 +0000 Subject: [PATCH] Test suite code factorization. Minor fix (return type) in AABB_tree.h. --- .../CGAL/AABB_polyhedron_segment_primitive.h | 8 +- AABB_tree/include/CGAL/AABB_tree.h | 2 +- AABB_tree/test/AABB_tree/AABB_test_util.h | 187 ++++++++++++++---- .../AABB_tree/aabb_distance_edge_test.cpp | 69 +------ .../aabb_distance_triangle_hint_test.cpp | 94 +++------ .../AABB_tree/aabb_distance_triangle_test.cpp | 66 +------ .../aabb_intersection_triangle_test.cpp | 69 +------ 7 files changed, 207 insertions(+), 288 deletions(-) diff --git a/AABB_tree/include/CGAL/AABB_polyhedron_segment_primitive.h b/AABB_tree/include/CGAL/AABB_polyhedron_segment_primitive.h index 26fe1a2e6ed..0ef4b6d472d 100644 --- a/AABB_tree/include/CGAL/AABB_polyhedron_segment_primitive.h +++ b/AABB_tree/include/CGAL/AABB_polyhedron_segment_primitive.h @@ -40,16 +40,16 @@ namespace CGAL { typedef typename GeomTraits::Point_3 Point; typedef typename GeomTraits::Segment_3 Datum; typedef typename Polyhedron::Halfedge_handle Id; + /// Self + typedef AABB_polyhedron_segment_primitive Self; /// Constructor AABB_polyhedron_segment_primitive() {} AABB_polyhedron_segment_primitive(const Id& handle) : m_halfedge_handle(handle) { }; - AABB_polyhedron_segment_primitive(const AABB_polyhedron_segment_primitive& primitive) - { - m_halfedge_handle = primitive.id(); - } + AABB_polyhedron_segment_primitive(const Self& primitive) + : m_halfedge_handle(primitive.m_halfedge_handle) {} // Default destructor, copy constructor and assignment operator are ok diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 8bb69de7f92..2fdbbe895ca 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -505,7 +505,7 @@ namespace CGAL { template template - typename Tr::size_type + typename AABB_tree::size_type AABB_tree::number_of_intersected_primitives(const Query& query) const { Counting_traits traversal_traits; diff --git a/AABB_tree/test/AABB_tree/AABB_test_util.h b/AABB_tree/test/AABB_tree/AABB_test_util.h index 92ffc8a23dc..3ed817ad0e7 100644 --- a/AABB_tree/test/AABB_tree/AABB_test_util.h +++ b/AABB_tree/test/AABB_tree/AABB_test_util.h @@ -26,6 +26,9 @@ #include #include +#include +#include + double random_in(const double a, const double b) @@ -54,6 +57,7 @@ typename K::Vector_3 random_vector() return typename K::Vector_3(x,y,z); } + template void test_all_intersection_query_types(Tree& tree) { @@ -115,54 +119,163 @@ void test_all_intersection_query_types(Tree& tree) template void test_all_distance_query_types(Tree& tree) { - typedef typename K::FT FT; - typedef typename K::Ray_3 Ray; - typedef typename K::Point_3 Point; - typedef typename K::Vector_3 Vector; - typedef typename Tree::Primitive Primitive; - typedef typename Tree::Point_and_primitive_id Point_and_primitive_id; + typedef typename K::FT FT; + typedef typename K::Ray_3 Ray; + typedef typename K::Point_3 Point; + typedef typename K::Vector_3 Vector; + typedef typename Tree::Primitive Primitive; + typedef typename Tree::Point_and_primitive_id Point_and_primitive_id; - Point query = random_point_in(tree.bbox()); - Point_and_primitive_id hint = tree.any_reference_point_and_id(); + Point query = random_point_in(tree.bbox()); + Point_and_primitive_id hint = tree.any_reference_point_and_id(); - FT sqd1 = tree.squared_distance(query); - FT sqd2 = tree.squared_distance(query,hint.first); - if(sqd1 != sqd2) - std::cout << "warning: different distances with and without hint"; + FT sqd1 = tree.squared_distance(query); + FT sqd2 = tree.squared_distance(query,hint.first); + if(sqd1 != sqd2) + std::cout << "warning: different distances with and without hint"; - Point p1 = tree.closest_point(query); - Point p2 = tree.closest_point(query,hint.first); - if(sqd1 != sqd2) - std::cout << "warning: different closest points with and without hint (possible, in case there are more than one)"; + Point p1 = tree.closest_point(query); + Point p2 = tree.closest_point(query,hint.first); + if(sqd1 != sqd2) + std::cout << "warning: different closest points with and without hint (possible, in case there are more than one)"; - Point_and_primitive_id pp1 = tree.closest_point_and_primitive(query); - Point_and_primitive_id pp2 = tree.closest_point_and_primitive(query,hint); - if(pp1.second != pp2.second) - std::cout << "warning: different closest primitives with and without hint (possible, in case there are more than one)"; + Point_and_primitive_id pp1 = tree.closest_point_and_primitive(query); + Point_and_primitive_id pp2 = tree.closest_point_and_primitive(query,hint); + if(pp1.second != pp2.second) + std::cout << "warning: different closest primitives with and without hint (possible, in case there are more than one)"; } + template void test_distance_speed(Tree& tree) { - typedef typename K::FT FT; - typedef typename K::Ray_3 Ray; - typedef typename K::Point_3 Point; - typedef typename K::Vector_3 Vector; + typedef typename K::FT FT; + typedef typename K::Ray_3 Ray; + typedef typename K::Point_3 Point; + typedef typename K::Vector_3 Vector; - CGAL::Timer timer; - timer.start(); - unsigned int nb = 0; - while(timer.time() < 1.0) - { - // picks a random point in the tree bbox - Point query = random_point_in(tree.bbox()); - Point closest = tree.closest_point(query); - nb++; - } - double speed = (double)nb / timer.time(); - std::cout << speed << " distance queries/s" << std::endl; - timer.stop(); + CGAL::Timer timer; + timer.start(); + unsigned int nb = 0; + while(timer.time() < 1.0) + { + // picks a random point in the tree bbox + Point query = random_point_in(tree.bbox()); + Point closest = tree.closest_point(query); + nb++; + } + double speed = (double)nb / timer.time(); + std::cout << speed << " distance queries/s" << std::endl; + timer.stop(); } + +//------------------------------------------------------- +// Helpers +//------------------------------------------------------- +enum Primitive_type { + SEGMENT, TRIANGLE +}; + +/** + * Primitive_generator : designed to tell void test(const char* filename) + * some information about which primitive to use. + * + * Must define: + * type Primitive + * type iterator + * iterator begin(Polyhedron&) + * iterator end(Polyhedron&) + * + * begin & end are used to build the AABB_tree. + */ +template +struct Primitive_generator {}; + +template +struct Primitive_generator +{ + typedef CGAL::AABB_polyhedron_segment_primitive Primitive; + + typedef typename Polyhedron::Edge_iterator iterator; + iterator begin(Polyhedron& p) { return p.edges_begin(); } + iterator end(Polyhedron& p) { return p.edges_end(); } +}; + +template +struct Primitive_generator +{ + typedef CGAL::AABB_polyhedron_triangle_primitive Primitive; + + typedef typename Polyhedron::Facet_iterator iterator; + iterator begin(Polyhedron& p) { return p.facets_begin(); } + iterator end(Polyhedron& p) { return p.facets_end(); } +}; + + + +/** + * Declaration only, implementation should be given in .cpp file + */ +template +void test_impl(Tree& tree, Polyhedron& p); + + +/** + * Generic test method. Build AABB_tree and call test_impl() + */ +template +void test(const char *filename) +{ + typedef CGAL::Polyhedron_3 Polyhedron; + typedef Primitive_generator Pr_generator; + typedef typename Pr_generator::Primitive Pr; + typedef CGAL::AABB_traits Traits; + typedef CGAL::AABB_tree Tree; + + Polyhedron polyhedron; + std::ifstream ifs(filename); + ifs >> polyhedron; + + // constructs AABB tree and internal search KD-tree with + // the points of the polyhedron + Tree tree(Pr_generator().begin(polyhedron),Pr_generator().end(polyhedron)); + tree.accelerate_distance_queries(polyhedron.points_begin(),polyhedron.points_end()); + + // call all tests + test_impl(tree,polyhedron); +} + + +/** + * Generic test_kernel method. call test for various kernel K. + */ +template +void test_kernels(const char *filename) +{ + std::cout << std::endl; + std::cout << "Polyhedron " << filename << std::endl; + std::cout << "============================" << std::endl; + + std::cout << std::endl; + std::cout << "Simple cartesian float kernel" << std::endl; + test,Primitive>(filename); + + std::cout << std::endl; + std::cout << "Cartesian float kernel" << std::endl; + test,Primitive>(filename); + + std::cout << std::endl; + std::cout << "Simple cartesian double kernel" << std::endl; + test,Primitive>(filename); + + std::cout << std::endl; + std::cout << "Cartesian double kernel" << std::endl; + test,Primitive>(filename); + + std::cout << std::endl; + std::cout << "Epic kernel" << std::endl; + test(filename); +} diff --git a/AABB_tree/test/AABB_tree/aabb_distance_edge_test.cpp b/AABB_tree/test/AABB_tree/aabb_distance_edge_test.cpp index ea7f2e7ed49..ec9adea5d26 100644 --- a/AABB_tree/test/AABB_tree/aabb_distance_edge_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_distance_edge_test.cpp @@ -40,68 +40,19 @@ #include "AABB_test_util.h" -template -void test(const char *filename) +template +void test_impl(Tree& tree, Polyhedron&) { - typedef typename K::FT FT; - typedef typename K::Ray_3 Ray; - typedef typename K::Point_3 Point; - typedef typename K::Vector_3 Vector; - typedef typename K::Segment_3 Segment; - typedef CGAL::Polyhedron_3 Polyhedron; - typedef CGAL::AABB_polyhedron_segment_primitive Primitive; - typedef CGAL::AABB_traits Traits; - typedef CGAL::AABB_tree Tree; - - Polyhedron polyhedron; - std::ifstream ifs(filename); - ifs >> polyhedron; - - // constructs AABB tree - Tree tree(polyhedron.edges_begin(),polyhedron.edges_end()); - - // constructs internal search KD-tree with points from the polyhedron vertex points - tree.accelerate_distance_queries(polyhedron.points_begin(),polyhedron.points_end()); - - // call all tests - test_distance_speed(tree); - test_all_distance_query_types(tree); + test_distance_speed(tree); + test_all_distance_query_types(tree); } -void test_kernels(const char *filename) -{ - std::cout << std::endl; - std::cout << "Polyhedron " << filename << std::endl; - std::cout << "============================" << std::endl; - - std::cout << std::endl; - std::cout << "Simple cartesian float kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Cartesian float kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Simple cartesian double kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Cartesian double kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Epic kernel" << std::endl; - test(filename); -} - - int main(void) { - std::cout << "AABB distance tests" << std::endl; - test_kernels("./data/cube.off"); - test_kernels("./data/coverrear.off"); - test_kernels("./data/nested_spheres.off"); - test_kernels("./data/finger.off"); - return 0; + std::cout << "AABB distance tests" << std::endl; + test_kernels("./data/cube.off"); + test_kernels("./data/coverrear.off"); + test_kernels("./data/nested_spheres.off"); + test_kernels("./data/finger.off"); + return 0; } diff --git a/AABB_tree/test/AABB_tree/aabb_distance_triangle_hint_test.cpp b/AABB_tree/test/AABB_tree/aabb_distance_triangle_hint_test.cpp index 680fb4815e3..1e14b7d5c49 100644 --- a/AABB_tree/test/AABB_tree/aabb_distance_triangle_hint_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_distance_triangle_hint_test.cpp @@ -62,20 +62,20 @@ void test_hint_strategies(Tree& tree, CGAL::Polyhedron_3& polyhedron) std::vector queries; std::vector outputs1, outputs2, outputs3; - + queries.reserve(NBQ); outputs1.reserve(NBQ); outputs2.reserve(NBQ); outputs3.reserve(NBQ); - + // size_t common_min = NBQ; size_t counter; - + for(size_t i = 0; i < NBQ; ++i) queries.push_back(random_point_in(tree.bbox())); - + CGAL::spatial_sort(queries.begin(), queries.end()); - + CGAL::Timer timer; timer.start(); counter = 0; @@ -84,12 +84,12 @@ void test_hint_strategies(Tree& tree, CGAL::Polyhedron_3& polyhedron) ++counter; } timer.stop(); - double speed = static_cast(counter)/(counter == NBQ? timer.time(): 1.); + double speed = static_cast(counter)/(counter == NBQ? timer.time(): 1.); std::cout << "without hint: " << speed << " queries/s" << std::endl; timer.reset(); - + Point_and_primitive_id hint = tree.any_reference_point_and_id(); - + timer.start(); counter = 0; while(timer.time() < 1. && counter < NBQ) { @@ -97,94 +97,48 @@ void test_hint_strategies(Tree& tree, CGAL::Polyhedron_3& polyhedron) ++counter; } timer.stop(); - speed = static_cast(counter)/(counter == NBQ? timer.time(): 1.); + speed = static_cast(counter)/(counter == NBQ? timer.time(): 1.); std::cout << "with spatial sort: " << speed << " queries/s" << std::endl; - timer.reset(); - + timer.reset(); + tree.accelerate_distance_queries(polyhedron.points_begin(),polyhedron.points_end()); - - timer.start(); + + timer.start(); counter = 0; while(timer.time() < 1. && counter < NBQ) { outputs3.push_back(tree.closest_point_and_primitive(queries[counter]).second); ++counter; } timer.stop(); - speed = static_cast(counter)/(counter == NBQ? timer.time(): 1.); + speed = static_cast(counter)/(counter == NBQ? timer.time(): 1.); std::cout << "with KD-tree: " << speed << " queries/s" << std::endl << std::endl; - timer.stop(); + timer.stop(); std::cout << "Consistency:" << std::endl; if((counter = check_outputs(outputs1, outputs2, Id())) == 0) std::cout << " without hint and spatial sort are consistent" << std::endl; else std::cout << "WARNING, without hint and spatial sort have " << counter << " inconsistencies (closest point on vertex/edge?)" << std::endl; - + if((counter = check_outputs(outputs1, outputs3, Id())) == 0) std::cout << " without hint and with KD-tree are consistent (modulo hint case)" << std::endl; else std::cout << "WARNING, without hint and with KD-tree have " << counter << " inconsistencies (closest point on vertex/edge? the hint case has been excluded)" << std::endl; - + std::cout << std::endl; } -template -void test(const char *filename) +template +void test_impl(Tree& tree, Polyhedron& p) { - typedef typename K::FT FT; - typedef typename K::Ray_3 Ray; - typedef typename K::Point_3 Point; - typedef typename K::Vector_3 Vector; - typedef CGAL::Polyhedron_3 Polyhedron; - typedef CGAL::AABB_polyhedron_triangle_primitive Primitive; - typedef CGAL::AABB_traits Traits; - typedef CGAL::AABB_tree Tree; - - Polyhedron polyhedron; - std::ifstream ifs(filename); - ifs >> polyhedron; - - // constructs AABB tree and internal search KD-tree with - // the points of the polyhedron - Tree tree(polyhedron.facets_begin(),polyhedron.facets_end()); - - // tests hint strategies - test_hint_strategies(tree, polyhedron); + test_hint_strategies(tree, p); } -void test_kernels(const char *filename) -{ - std::cout << std::endl; - std::cout << "Polyhedron " << filename << std::endl; - std::cout << "============================" << std::endl; - - std::cout << std::endl; - std::cout << "Simple cartesian float kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Cartesian float kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Simple cartesian double kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Cartesian double kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Epic kernel" << std::endl; - test(filename); -} - - int main(void) { std::cout << "AABB hint strategies tests" << std::endl; - test_kernels("./data/cube.off"); - test_kernels("./data/coverrear.off"); - test_kernels("./data/nested_spheres.off"); - test_kernels("./data/finger.off"); + test_kernels("./data/cube.off"); + test_kernels("./data/coverrear.off"); + test_kernels("./data/nested_spheres.off"); + test_kernels("./data/finger.off"); return 0; } diff --git a/AABB_tree/test/AABB_tree/aabb_distance_triangle_test.cpp b/AABB_tree/test/AABB_tree/aabb_distance_triangle_test.cpp index 05b2434eeec..4a20b32371f 100644 --- a/AABB_tree/test/AABB_tree/aabb_distance_triangle_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_distance_triangle_test.cpp @@ -37,65 +37,19 @@ #include "AABB_test_util.h" -template -void test(const char *filename) +template +void test_impl(Tree& tree, Polyhedron&) { - typedef typename K::FT FT; - typedef typename K::Ray_3 Ray; - typedef typename K::Point_3 Point; - typedef typename K::Vector_3 Vector; - typedef CGAL::Polyhedron_3 Polyhedron; - typedef CGAL::AABB_polyhedron_triangle_primitive Primitive; - typedef CGAL::AABB_traits Traits; - typedef CGAL::AABB_tree Tree; - - Polyhedron polyhedron; - std::ifstream ifs(filename); - ifs >> polyhedron; - - // constructs AABB tree and internal search KD-tree with - // the points of the polyhedron - Tree tree(polyhedron.facets_begin(),polyhedron.facets_end()); - tree.accelerate_distance_queries(polyhedron.points_begin(),polyhedron.points_end()); - - // call all tests - test_distance_speed(tree); - test_all_distance_query_types(tree); -} - -void test_kernels(const char *filename) -{ - std::cout << std::endl; - std::cout << "Polyhedron " << filename << std::endl; - std::cout << "============================" << std::endl; - - std::cout << std::endl; - std::cout << "Simple cartesian float kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Cartesian float kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Simple cartesian double kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Cartesian double kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Epic kernel" << std::endl; - test(filename); + test_distance_speed(tree); + test_all_distance_query_types(tree); } int main(void) { - std::cout << "AABB distance tests" << std::endl; - test_kernels("./data/cube.off"); - test_kernels("./data/coverrear.off"); - test_kernels("./data/nested_spheres.off"); - test_kernels("./data/finger.off"); - return 0; + std::cout << "AABB distance tests" << std::endl; + test_kernels("./data/cube.off"); + test_kernels("./data/coverrear.off"); + test_kernels("./data/nested_spheres.off"); + test_kernels("./data/finger.off"); + return 0; } diff --git a/AABB_tree/test/AABB_tree/aabb_intersection_triangle_test.cpp b/AABB_tree/test/AABB_tree/aabb_intersection_triangle_test.cpp index 8b2509eadad..6507ee7163a 100644 --- a/AABB_tree/test/AABB_tree/aabb_intersection_triangle_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_intersection_triangle_test.cpp @@ -108,72 +108,19 @@ void test_speed(Tree& tree) test_speed_for_query(tree,SEGMENT_QUERY,"segment"); } -template -void test(const char *filename) +template +void test_impl(Tree& tree, Polyhedron&) { - typedef typename K::FT FT; - typedef typename K::Ray_3 Ray; - typedef typename K::Point_3 Point; - typedef typename K::Vector_3 Vector; - typedef CGAL::Polyhedron_3 Polyhedron; - typedef CGAL::AABB_polyhedron_triangle_primitive Primitive; - typedef CGAL::AABB_traits Traits; - typedef CGAL::AABB_tree Tree; - - // loads triangle polyhedral surface - Polyhedron polyhedron; - std::ifstream ifs(filename); - ifs >> polyhedron; - - // constructs tree - std::cout << "construct tree..."; - CGAL::Timer timer; - timer.start(); - Tree tree(polyhedron.facets_begin(),polyhedron.facets_end()); - timer.stop(); - std::cout << "done (" << timer.time() << " s)" << std::endl; - - // tests rebuilding - tree.rebuild(polyhedron.facets_begin(),polyhedron.facets_end()); - - // calls all tests - test_all_intersection_query_types(tree); - test_speed(tree); -} - -void test_kernels(const char *filename) -{ - std::cout << std::endl; - std::cout << "Polyhedron " << filename << std::endl; - std::cout << "============================" << std::endl; - - std::cout << std::endl; - std::cout << "Simple cartesian float kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Cartesian float kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Simple cartesian double kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Cartesian double kernel" << std::endl; - test >(filename); - - std::cout << std::endl; - std::cout << "Epic kernel" << std::endl; - test(filename); + test_all_intersection_query_types(tree); + test_speed(tree); } int main(void) { std::cout << "AABB intersection tests" << std::endl; - test_kernels("./data/cube.off"); - test_kernels("./data/coverrear.off"); - test_kernels("./data/nested_spheres.off"); - test_kernels("./data/finger.off"); + test_kernels("./data/cube.off"); + test_kernels("./data/coverrear.off"); + test_kernels("./data/nested_spheres.off"); + test_kernels("./data/finger.off"); return 0; }