mirror of https://github.com/CGAL/cgal
187 lines
5.2 KiB
C++
187 lines
5.2 KiB
C++
#include <iostream>
|
|
#include <fstream>
|
|
#include <algorithm>
|
|
#include <tuple>
|
|
|
|
#include <CGAL/Cartesian.h>
|
|
#include <CGAL/Simple_cartesian.h>
|
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
|
|
|
#include <CGAL/function_objects.h>
|
|
|
|
#include <CGAL/AABB_tree.h>
|
|
#include <CGAL/AABB_traits.h>
|
|
|
|
#include <CGAL/AABB_face_graph_triangle_primitive.h>
|
|
#include <CGAL/Polyhedron_3.h>
|
|
|
|
|
|
#include <CGAL/Timer.h>
|
|
|
|
#include <CGAL/Random.h>
|
|
#include <CGAL/point_generators_3.h>
|
|
#include <CGAL/algorithm.h>
|
|
|
|
|
|
const std::size_t elements = 50000;
|
|
const int runs = 10;
|
|
|
|
template<typename Tree>
|
|
struct FilterP {
|
|
const Tree* t;
|
|
|
|
template<typename T>
|
|
bool operator()(const T& tt) { return !t->do_intersect(tt); }
|
|
};
|
|
|
|
|
|
template<typename ForwardIterator, typename Tree>
|
|
std::size_t intersect(ForwardIterator b, ForwardIterator e, const Tree& tree, long& counter) {
|
|
typedef
|
|
typename Tree::AABB_traits::template Intersection_and_primitive_id<typename ForwardIterator::value_type>::Type
|
|
Obj_type;
|
|
|
|
std::vector<Obj_type> v;
|
|
// bad educated guess
|
|
v.reserve(elements);
|
|
for(; b != e; ++b) {
|
|
tree.all_intersections(*b, std::back_inserter(v));
|
|
std::optional<Obj_type> o = tree.any_intersection(*b);
|
|
if(o)
|
|
++counter;
|
|
}
|
|
|
|
return v.size();
|
|
}
|
|
|
|
template<typename K>
|
|
std::tuple<std::size_t, std::size_t, std::size_t, long> 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<K> Polyhedron;
|
|
|
|
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
|
|
typedef CGAL::AABB_traits<K, Primitive> Traits;
|
|
typedef CGAL::AABB_tree<Traits> 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<Point, CGAL::Creator_uniform_3<FT, Point> > g( 2., r);
|
|
|
|
std::vector<Point> points;
|
|
points.reserve(elements * 2);
|
|
std::copy_n(g, elements * 2, std::back_inserter(points));
|
|
|
|
// generate a bunch of happy random primitives
|
|
std::vector<Line> 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<Ray> 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<Segment> 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<Tree> 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<std::size_t, std::size_t, std::size_t, long> 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<std::size_t, std::size_t, std::size_t, long> t1 = test<CGAL::Simple_cartesian<float> >(filename);
|
|
std::cout << " | " << std::endl;
|
|
|
|
std::cout << "| Cartesian float kernel | ";
|
|
std::tuple<std::size_t, std::size_t, std::size_t, long> t2 = test<CGAL::Cartesian<float> >(filename);
|
|
std::cout << " | " << std::endl;
|
|
|
|
std::cout << "| Simple cartesian double kernel |";
|
|
std::tuple<std::size_t, std::size_t, std::size_t, long> t3 = test<CGAL::Simple_cartesian<double> >(filename);
|
|
std::cout << " | " << std::endl;
|
|
|
|
std::cout << "| Cartesian double kernel |";
|
|
std::tuple<std::size_t, std::size_t, std::size_t, long> t4 = test<CGAL::Cartesian<double> >(filename);
|
|
std::cout << " | " << std::endl;
|
|
|
|
std::cout << "| Epic kernel |";
|
|
std::tuple<std::size_t, std::size_t, std::size_t, long> t5 = test<CGAL::Exact_predicates_inexact_constructions_kernel>(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;
|
|
}
|