#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const std::size_t elements = 50000; const int runs = 10; template struct FilterP { const Tree* t; template bool operator()(const T& tt) { return !t->do_intersect(tt); } }; template std::size_t intersect(ForwardIterator b, ForwardIterator e, const Tree& tree, long& counter) { typedef typename Tree::AABB_traits::template Intersection_and_primitive_id::Type Obj_type; std::vector v; // bad educated guess v.reserve(elements); for(; b != e; ++b) { tree.all_intersections(*b, std::back_inserter(v)); std::optional o = tree.any_intersection(*b); if(o) ++counter; } return v.size(); } template std::tuple test(const char* name) { typedef typename K::FT FT; typedef typename K::Ray_3 Ray; typedef typename K::Line_3 Line; typedef typename K::Point_3 Point; typedef typename K::Segment_3 Segment; typedef CGAL::Polyhedron_3 Polyhedron; typedef CGAL::AABB_face_graph_triangle_primitive Primitive; typedef CGAL::AABB_traits Traits; typedef CGAL::AABB_tree Tree; std::ifstream ifs(name); Polyhedron polyhedron; ifs >> polyhedron; // Random seeded to 23, cube size equal to the magic number 2 CGAL::Random r(23); CGAL::Random_points_in_cube_3 > g( 2., r); std::vector points; points.reserve(elements * 2); std::copy_n(g, elements * 2, std::back_inserter(points)); // generate a bunch of happy random primitives std::vector lines; lines.reserve(elements); // forward for(std::size_t i = 0; i < points.size(); i += 2) { lines.push_back(Line(points[i], points[i + 1])); } std::vector rays; rays.reserve(elements); // backwards for(std::size_t i = points.size(); i != 0; i -= 2) { rays.push_back(Ray(points[i - 1], points[i - 2])); } std::vector segments; segments.reserve(elements); // from both sides for(std::size_t i = 0, j = points.size() - 1; i < j; ++i, --j) { segments.push_back(Segment(points[i], points[j])); } Tree tree(faces(polyhedron).first, faces(polyhedron).second, polyhedron); // filter all primitives that do not intersect FilterP p = { &tree }; lines.erase(std::remove_if(lines.begin(), lines.end(), p), lines.end()); rays.erase(std::remove_if(rays.begin(), rays.end(), p), rays.end()); segments.erase(std::remove_if(segments.begin(), segments.end(), p), segments.end()); std::tuple tu; { CGAL::Timer t; t.start(); for(int i = 0; i < runs; ++i) { long counter = 0L; tu = std::make_tuple(intersect(lines.begin(), lines.end(), tree, counter), intersect(rays.begin(), rays.end(), tree, counter), intersect(segments.begin(), segments.end(), tree, counter), // can't use counter here 0); std::get<3>(tu) = counter; } std::cout << t.time(); } return tu; } int main() { const char* filename = "data/finger.off"; std::cout << "| Simple cartesian float kernel | "; std::tuple t1 = test >(filename); std::cout << " | " << std::endl; std::cout << "| Cartesian float kernel | "; std::tuple t2 = test >(filename); std::cout << " | " << std::endl; std::cout << "| Simple cartesian double kernel |"; std::tuple t3 = test >(filename); std::cout << " | " << std::endl; std::cout << "| Cartesian double kernel |"; std::tuple t4 = test >(filename); std::cout << " | " << std::endl; std::cout << "| Epic kernel |"; std::tuple t5 = test(filename); std::cout << " | " << std::endl; std::size_t a, b, c; long d; std::tie(a, b, c, d) = t5; std::cout << a << " " << b << " " << c << " " << d << std::endl; std::tie(a, b, c, d) = t4; std::cout << a << " " << b << " " << c << " " << d << std::endl; std::tie(a, b, c, d) = t3; std::cout << a << " " << b << " " << c << " " << d << std::endl; std::tie(a, b, c, d) = t2; std::cout << a << " " << b << " " << c << " " << d << std::endl; std::tie(a, b, c, d) = t1; std::cout << a << " " << b << " " << c << " " << d << std::endl; return 0; }