Merge pull request #5464 from mglisse/tri2

benchmark Delaunay 2d with NewKernel_d
This commit is contained in:
Laurent Rineau 2021-03-03 18:31:17 +01:00
commit 1a799c533a
14 changed files with 181 additions and 49 deletions

View File

@ -37,6 +37,10 @@ namespace CGAL {
// not, or we let all this up to the compiler optimizer to figure out ? // not, or we let all this up to the compiler optimizer to figure out ?
// - Some caching could be done at the Point_2 level. // - Some caching could be done at the Point_2 level.
// Protection is undocumented and currently always true, meaning that it
// assumes a default rounding mode of round-to-nearest. false would correspond
// to a default of round-towards-infinity, so interval arithmetic does not
// require protection but regular code may.
template <class EP, class AP, class C2E, class C2A, bool Protection = true> template <class EP, class AP, class C2E, class C2A, bool Protection = true>
class Filtered_predicate class Filtered_predicate

View File

@ -50,7 +50,7 @@ template<class R_,class Zero_> struct Construct_LA_vector
// Makes no sense for an unknown dimension. // Makes no sense for an unknown dimension.
return typename Constructor::Dimension()(this->kernel().dimension()); return typename Constructor::Dimension()(this->kernel().dimension());
} }
result_type operator()(result_type const& v)const{ result_type const& operator()(result_type const& v)const{
return v; return v;
} }
result_type operator()(result_type&& v)const{ result_type operator()(result_type&& v)const{
@ -137,7 +137,7 @@ template<class R_> struct Compute_cartesian_coordinate {
typedef typename Get_type<R, RT_tag>::type RT; typedef typename Get_type<R, RT_tag>::type RT;
typedef typename R::Vector_ first_argument_type; typedef typename R::Vector_ first_argument_type;
typedef int second_argument_type; typedef int second_argument_type;
typedef Tag_true Is_exact; typedef Tag_true Uses_no_arithmetic;
typedef decltype(std::declval<const first_argument_type>()[0]) result_type; typedef decltype(std::declval<const first_argument_type>()[0]) result_type;
template <typename index_type> template <typename index_type>
@ -153,7 +153,7 @@ template<class R_> struct Construct_cartesian_const_iterator {
typedef typename R::LA_vector S_; typedef typename R::LA_vector S_;
typedef typename R::Point_cartesian_const_iterator result_type; typedef typename R::Point_cartesian_const_iterator result_type;
// same as Vector // same as Vector
typedef Tag_true Is_exact; typedef Tag_true Uses_no_arithmetic;
result_type operator()(argument_type const& v,Begin_tag)const{ result_type operator()(argument_type const& v,Begin_tag)const{
return S_::vector_begin(v); return S_::vector_begin(v);
@ -282,7 +282,7 @@ template<class R_> struct PV_dimension {
typedef typename R::Vector_ argument_type; typedef typename R::Vector_ argument_type;
typedef int result_type; typedef int result_type;
typedef typename R::LA_vector LA; typedef typename R::LA_vector LA;
typedef Tag_true Is_exact; typedef Tag_true Uses_no_arithmetic;
template<class T> template<class T>
result_type operator()(T const& v) const { result_type operator()(T const& v) const {

View File

@ -42,7 +42,7 @@ template<> struct Functors_without_division<Dimension_tag<6> > {
}; };
// FIXME: // FIXME:
// - Is_exact (which should be renamed to Uses_no_arithmetic) predicates should not be filtered // - Uses_no_arithmetic predicates should not be filtered
// - Functors_without_division should be defined near/in the actual functors // - Functors_without_division should be defined near/in the actual functors
template < typename Base_, typename AK_, typename EK_, typename Pred_list = typeset_all > template < typename Base_, typename AK_, typename EK_, typename Pred_list = typeset_all >
@ -78,18 +78,24 @@ struct Cartesian_filter_K : public Base_
// TODO: only fix some types, based on some criterion? // TODO: only fix some types, based on some criterion?
template<class T> struct Type : Get_type<Kernel_base,T> {}; template<class T> struct Type : Get_type<Kernel_base,T> {};
template<class T,class D=void,class=typename Get_functor_category<Cartesian_filter_K,T>::type, bool=Pred_list::template contains<T>::value> struct Functor : template<class T,class D,bool=Uses_no_arithmetic<typename Get_functor<Kernel_base,T,D>::type>::value> struct Pred_helper {
Inherit_functor<Kernel_base,T,D> {};
template<class T,class D> struct Functor<T,D,Predicate_tag,true> {
typedef typename Get_functor<AK, T>::type AP; typedef typename Get_functor<AK, T>::type AP;
typedef typename Get_functor<EK, T>::type EP; typedef typename Get_functor<EK, T>::type EP;
typedef Filtered_predicate2<Cartesian_filter_K,EP,AP,C2E,C2A> type; typedef Filtered_predicate2<Cartesian_filter_K,EP,AP,C2E,C2A> type;
}; };
// Less_cartesian_coordinate doesn't usually need filtering
// This fixes the predicate, as opposed to Inherit_functor which would leave it open (is that good?)
template<class T,class D> struct Pred_helper<T,D,true> :
Get_functor<Kernel_base,T,D> {};
template<class T,class D=void,class=typename Get_functor_category<Cartesian_filter_K,T>::type, bool=Pred_list::template contains<T>::value> struct Functor :
Inherit_functor<Kernel_base,T,D> {};
template<class T,class D> struct Functor<T,D,Predicate_tag,true> :
Pred_helper<T,D> {};
// TODO: // TODO:
// template<class T> struct Functor<T,No_filter_tag,Predicate_tag> : // template<class T> struct Functor<T,No_filter_tag,Predicate_tag> :
// Kernel_base::template Functor<T,No_filter_tag> {}; // Kernel_base::template Functor<T,No_filter_tag> {};
// TODO:
// detect when Less_cartesian_coordinate doesn't need filtering
}; };
} //namespace CGAL } //namespace CGAL

View File

@ -15,37 +15,46 @@
#include <CGAL/Dimension.h> #include <CGAL/Dimension.h>
#include <CGAL/internal/Static_filters/tools.h> // bug, should be included by the next one #include <CGAL/internal/Static_filters/tools.h> // bug, should be included by the next one
#include <CGAL/internal/Static_filters/Orientation_2.h> #include <CGAL/internal/Static_filters/Orientation_2.h>
#include <CGAL/internal/Static_filters/Side_of_oriented_circle_2.h>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
namespace CGAL { namespace CGAL {
namespace SFA { // static filter adapter namespace SFA { // static filter adapter
// Note that this would be quite a bit simpler without stateful kernels // Note that this would be quite a bit simpler without stateful kernels
template <class Base_,class R_> struct Adapter_2 {
typedef typename Get_type<R_, Point_tag>::type Point;
typedef typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type CC;
typedef typename Get_functor<Base_, Orientation_of_points_tag>::type Orientation_base;
typedef typename Get_functor<Base_, Side_of_oriented_sphere_tag>::type Side_of_oriented_circle_base;
struct Point_2 {
R_ const&r; CC const&c; Point const& p;
Point_2(R_ const&r_, CC const&c_, Point const&p_):r(r_),c(c_),p(p_){}
decltype(auto) x()const{return c(p,0);}
decltype(auto) y()const{return c(p,1);}
};
struct Vector_2 {};
struct Circle_2 {};
struct Orientation_2 {
typedef typename Get_type<R_, Orientation_tag>::type result_type;
auto operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C)const{
Point const* t[3]={&A.p,&B.p,&C.p};
return Orientation_base(A.r)(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+3));
}
};
struct Side_of_oriented_circle_2 {
typedef typename Get_type<R_, Oriented_side_tag>::type result_type;
auto operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C, Point_2 const&D)const{
Point const* t[3]={&A.p,&B.p,&C.p};
return Side_of_oriented_circle_base(A.r)(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+3),D.p);
}
};
};
template <class Base_,class R_> struct Orientation_of_points_2 : private Store_kernel<R_> { template <class Base_,class R_> struct Orientation_of_points_2 : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Orientation_of_points_2) CGAL_FUNCTOR_INIT_STORE(Orientation_of_points_2)
typedef typename Get_type<R_, Point_tag>::type Point; typedef typename Get_type<R_, Point_tag>::type Point;
typedef typename Get_type<R_, Orientation_tag>::type result_type; typedef typename Get_type<R_, Orientation_tag>::type result_type;
typedef typename Get_type<R_, FT_tag>::type FT;
typedef typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type CC; typedef typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type CC;
typedef typename Get_functor<Base_, Orientation_of_points_tag>::type Orientation_base; typedef Adapter_2<Base_, R_> Adapter;
// TODO: Move this out for easy reuse
struct Adapter {
struct Point_2 {
R_ const&r; CC const&c; Point const& p;
Point_2(R_ const&r_, CC const&c_, Point const&p_):r(r_),c(c_),p(p_){}
// use result_of instead?
typename CC::result_type x()const{return c(p,0);}
typename CC::result_type y()const{return c(p,1);}
};
struct Vector_2 {};
struct Circle_2 {};
struct Orientation_2 {
typedef typename Orientation_of_points_2::result_type result_type;
result_type operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C)const{
Point const* t[3]={&A.p,&B.p,&C.p};
return Orientation_base(A.r)(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+3));
}
};
};
template<class Iter> result_type operator()(Iter f, Iter CGAL_assertion_code(e))const{ template<class Iter> result_type operator()(Iter f, Iter CGAL_assertion_code(e))const{
CC c(this->kernel()); CC c(this->kernel());
Point const& A=*f; Point const& A=*f;
@ -56,6 +65,22 @@ template <class Base_,class R_> struct Orientation_of_points_2 : private Store_k
return typename internal::Static_filters_predicates::Orientation_2<Adapter>()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C)); return typename internal::Static_filters_predicates::Orientation_2<Adapter>()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C));
} }
}; };
template <class Base_,class R_> struct Side_of_oriented_sphere_2 : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Side_of_oriented_sphere_2)
typedef typename Get_type<R_, Point_tag>::type Point;
typedef typename Get_type<R_, Oriented_side_tag>::type result_type;
typedef typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type CC;
typedef Adapter_2<Base_, R_> Adapter;
template<class Iter> result_type operator()(Iter f, Iter CGAL_assertion_code(e), Point const& D)const{
CC c(this->kernel());
Point const& A=*f;
Point const& B=*++f;
Point const& C=*++f;
CGAL_assertion(++f==e);
typedef typename Adapter::Point_2 P;
return typename internal::Static_filters_predicates::Side_of_oriented_circle_2<Adapter>()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C),P(this->kernel(),c,D));
}
};
} }
template <class Dim_ /* should be implicit */, class R_, class Derived_=Default> template <class Dim_ /* should be implicit */, class R_, class Derived_=Default>
@ -80,6 +105,9 @@ struct Cartesian_static_filters<Dimension_tag<2>, R_, Derived_> : public R_ {
// >::type // >::type
type; type;
}; };
template <class D> struct Functor <Side_of_oriented_sphere_tag,D> {
typedef SFA::Side_of_oriented_sphere_2<R_,Derived> type;
};
}; };
} }

View File

@ -39,6 +39,11 @@ namespace CGAL {
// not, or we let all this up to the compiler optimizer to figure out ? // not, or we let all this up to the compiler optimizer to figure out ?
// - Some caching could be done at the Point_2 level. // - Some caching could be done at the Point_2 level.
// Protection has a different meaning than in Filtered_predicate, it says
// whether we need to set the rounding mode: some predicates only do
// comparisons and don't need it. Probably this should be done inside this
// class, based on Uses_no_arithmetic, but I have some doubts about C2A,
// converting a long long to Interval_nt requires protection.
template <class K, class EP, class AP, class C2E, class C2A, bool Protection = true> template <class K, class EP, class AP, class C2E, class C2A, bool Protection = true>
class Filtered_predicate2 class Filtered_predicate2
@ -87,7 +92,6 @@ public:
catch (Uncertain_conversion_exception&) {} catch (Uncertain_conversion_exception&) {}
} }
CGAL_BRANCH_PROFILER_BRANCH(tmp); CGAL_BRANCH_PROFILER_BRANCH(tmp);
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
return ep(c2e(std::forward<Args>(args))...); return ep(c2e(std::forward<Args>(args))...);
} }
}; };

View File

@ -79,10 +79,11 @@ template <class Base_> struct Kernel_2_interface : public Base_ {
Side_of_oriented_circle_2(Kernel const&k):sos(k){} Side_of_oriented_circle_2(Kernel const&k):sos(k){}
result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c, Point_2 const&d) { result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c, Point_2 const&d) {
//return sos(a,b,c,d); //return sos(a,b,c,d);
Point_2 const* t[4]={&a,&b,&c,&d}; Point_2 const* t[4]={&a,&b,&c};
return sos(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+4)); return sos(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+3), d);
} }
}; };
typedef typename Get_functor<Base, Construct_ttag<Point_tag> >::type Construct_point_2;
Less_x_2 less_x_2_object()const{ return Less_x_2(*this); } Less_x_2 less_x_2_object()const{ return Less_x_2(*this); }
Less_y_2 less_y_2_object()const{ return Less_y_2(*this); } Less_y_2 less_y_2_object()const{ return Less_y_2(*this); }
Compare_x_2 compare_x_2_object()const{ return Compare_x_2(*this); } Compare_x_2 compare_x_2_object()const{ return Compare_x_2(*this); }
@ -90,6 +91,7 @@ template <class Base_> struct Kernel_2_interface : public Base_ {
Compare_distance_2 compare_distance_2_object()const{ return Compare_distance_2(*this); } Compare_distance_2 compare_distance_2_object()const{ return Compare_distance_2(*this); }
Orientation_2 orientation_2_object()const{ return Orientation_2(*this); } Orientation_2 orientation_2_object()const{ return Orientation_2(*this); }
Side_of_oriented_circle_2 side_of_oriented_circle_2_object()const{ return Side_of_oriented_circle_2(*this); } Side_of_oriented_circle_2 side_of_oriented_circle_2_object()const{ return Side_of_oriented_circle_2(*this); }
Construct_point_2 construct_point_2_object()const{ return Construct_point_2(*this); }
}; };
} }

View File

@ -76,10 +76,11 @@ template <class Base_> struct Kernel_3_interface : public Base_ {
Side_of_oriented_sphere_3(Kernel const&k):sos(k){} Side_of_oriented_sphere_3(Kernel const&k):sos(k){}
result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d, Point_3 const&e) { result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d, Point_3 const&e) {
//return sos(a,b,c,d); //return sos(a,b,c,d);
Point_3 const* t[5]={&a,&b,&c,&d,&e}; Point_3 const* t[5]={&a,&b,&c,&d};
return sos(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+5)); return sos(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+4),e);
} }
}; };
typedef typename Get_functor<Base, Construct_ttag<Point_tag> >::type Construct_point_3;
// I don't have the Coplanar predicates (yet) // I don't have the Coplanar predicates (yet)
@ -88,6 +89,7 @@ template <class Base_> struct Kernel_3_interface : public Base_ {
Compare_distance_3 compare_distance_3_object()const{ return Compare_distance_3(*this); } Compare_distance_3 compare_distance_3_object()const{ return Compare_distance_3(*this); }
Orientation_3 orientation_3_object()const{ return Orientation_3(*this); } Orientation_3 orientation_3_object()const{ return Orientation_3(*this); }
Side_of_oriented_sphere_3 side_of_oriented_sphere_3_object()const{ return Side_of_oriented_sphere_3(*this); } Side_of_oriented_sphere_3 side_of_oriented_sphere_3_object()const{ return Side_of_oriented_sphere_3(*this); }
Construct_point_3 construct_point_3_object()const{ return Construct_point_3(*this); }
}; };
} }

View File

@ -294,7 +294,9 @@ struct Lazy_cartesian :
template<class T,class D> struct Functor<T,D,Predicate_tag> { template<class T,class D> struct Functor<T,D,Predicate_tag> {
typedef typename Get_functor<Approximate_kernel, T>::type FA; typedef typename Get_functor<Approximate_kernel, T>::type FA;
typedef typename Get_functor<Exact_kernel, T>::type FE; typedef typename Get_functor<Exact_kernel, T>::type FE;
typedef Filtered_predicate2<Lazy_cartesian,FE,FA,C2E,C2A> type; // Careful if operator< for Interval_nt ever starts using arithmetic...
// Not done directly in Filtered_predicate2 because of C2A
typedef Filtered_predicate2<Lazy_cartesian,FE,FA,C2E,C2A,!Uses_no_arithmetic<FA>::value> type;
}; };
template<class T,class D> struct Functor<T,D,Compute_tag> { template<class T,class D> struct Functor<T,D,Compute_tag> {
typedef Lazy_construction2<T,Kernel> type; typedef Lazy_construction2<T,Kernel> type;

View File

@ -127,7 +127,7 @@ template <class R_> struct Hyperplane_translation {
CGAL_FUNCTOR_INIT_IGNORE(Hyperplane_translation) CGAL_FUNCTOR_INIT_IGNORE(Hyperplane_translation)
typedef typename Get_type<R_, Hyperplane_tag>::type Hyperplane; typedef typename Get_type<R_, Hyperplane_tag>::type Hyperplane;
typedef typename Get_type<R_, FT_tag>::type result_type; typedef typename Get_type<R_, FT_tag>::type result_type;
// TODO: Is_exact? // TODO: Uses_no_arithmetic?
result_type operator()(Hyperplane const&s)const{ result_type operator()(Hyperplane const&s)const{
return s.translation(); return s.translation();
} }

View File

@ -83,7 +83,7 @@ template <class R_> struct Squared_radius {
CGAL_FUNCTOR_INIT_IGNORE(Squared_radius) CGAL_FUNCTOR_INIT_IGNORE(Squared_radius)
typedef typename Get_type<R_, Sphere_tag>::type Sphere; typedef typename Get_type<R_, Sphere_tag>::type Sphere;
typedef typename Get_type<R_, FT_tag>::type const& result_type; typedef typename Get_type<R_, FT_tag>::type const& result_type;
// TODO: Is_exact? // TODO: Uses_no_arithmetic?
result_type operator()(Sphere const&s)const{ result_type operator()(Sphere const&s)const{
return s.squared_radius(); return s.squared_radius();
} }

View File

@ -1108,7 +1108,7 @@ template<class R_> struct Less_point_cartesian_coordinate : private Store_kernel
typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type Cc; typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type Cc;
// TODO: This is_exact thing should be reengineered. // TODO: This is_exact thing should be reengineered.
// the goal is to have a way to tell: don't filter this // the goal is to have a way to tell: don't filter this
typedef typename CGAL::Is_exact<Cc> Is_exact; typedef typename CGAL::Uses_no_arithmetic<Cc> Uses_no_arithmetic;
template<class V,class W,class I> template<class V,class W,class I>
result_type operator()(V const&a, W const&b, I i)const{ result_type operator()(V const&a, W const&b, I i)const{
@ -1128,7 +1128,7 @@ template<class R_> struct Compare_point_cartesian_coordinate : private Store_ker
typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type Cc; typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type Cc;
// TODO: This is_exact thing should be reengineered. // TODO: This is_exact thing should be reengineered.
// the goal is to have a way to tell: don't filter this // the goal is to have a way to tell: don't filter this
typedef typename CGAL::Is_exact<Cc> Is_exact; typedef typename CGAL::Uses_no_arithmetic<Cc> Uses_no_arithmetic;
template<class V,class W,class I> template<class V,class W,class I>
result_type operator()(V const&a, W const&b, I i)const{ result_type operator()(V const&a, W const&b, I i)const{
@ -1148,7 +1148,7 @@ template<class R_> struct Compare_lexicographically : private Store_kernel<R_> {
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI; typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
// TODO: This is_exact thing should be reengineered. // TODO: This is_exact thing should be reengineered.
// the goal is to have a way to tell: don't filter this // the goal is to have a way to tell: don't filter this
typedef typename CGAL::Is_exact<CI> Is_exact; typedef typename CGAL::Uses_no_arithmetic<CI> Uses_no_arithmetic;
template<class V,class W> template<class V,class W>
result_type operator()(V const&a, W const&b)const{ result_type operator()(V const&a, W const&b)const{
@ -1176,7 +1176,7 @@ template<class R_> struct Less_lexicographically : private Store_kernel<R_> {
typedef R_ R; typedef R_ R;
typedef typename Get_type<R, Bool_tag>::type result_type; typedef typename Get_type<R, Bool_tag>::type result_type;
typedef typename Get_functor<R, Compare_lexicographically_tag>::type CL; typedef typename Get_functor<R, Compare_lexicographically_tag>::type CL;
typedef typename CGAL::Is_exact<CL> Is_exact; typedef typename CGAL::Uses_no_arithmetic<CL> Uses_no_arithmetic;
template <class V, class W> template <class V, class W>
result_type operator() (V const&a, W const&b) const { result_type operator() (V const&a, W const&b) const {
@ -1194,7 +1194,7 @@ template<class R_> struct Less_or_equal_lexicographically : private Store_kernel
typedef R_ R; typedef R_ R;
typedef typename Get_type<R, Bool_tag>::type result_type; typedef typename Get_type<R, Bool_tag>::type result_type;
typedef typename Get_functor<R, Compare_lexicographically_tag>::type CL; typedef typename Get_functor<R, Compare_lexicographically_tag>::type CL;
typedef typename CGAL::Is_exact<CL> Is_exact; typedef typename CGAL::Uses_no_arithmetic<CL> Uses_no_arithmetic;
template <class V, class W> template <class V, class W>
result_type operator() (V const&a, W const&b) const { result_type operator() (V const&a, W const&b) const {
@ -1214,7 +1214,7 @@ template<class R_> struct Equal_points : private Store_kernel<R_> {
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI; typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
// TODO: This is_exact thing should be reengineered. // TODO: This is_exact thing should be reengineered.
// the goal is to have a way to tell: don't filter this // the goal is to have a way to tell: don't filter this
typedef typename CGAL::Is_exact<CI> Is_exact; typedef typename CGAL::Uses_no_arithmetic<CI> Uses_no_arithmetic;
template<class V,class W> template<class V,class W>
result_type operator()(V const&a, W const&b)const{ result_type operator()(V const&a, W const&b)const{

View File

@ -24,7 +24,7 @@ namespace CGAL {
template<class T> \ template<class T> \
struct Is_pretty<T,true> : T::Is_pretty {} struct Is_pretty<T,true> : T::Is_pretty {}
CGAL_STRAWBERRY(Is_exact); CGAL_STRAWBERRY(Uses_no_arithmetic);
CGAL_STRAWBERRY(Is_fast); CGAL_STRAWBERRY(Is_fast);
CGAL_STRAWBERRY(Is_stored); CGAL_STRAWBERRY(Is_stored);
#undef CGAL_STRAWBERRY #undef CGAL_STRAWBERRY

View File

@ -18,13 +18,20 @@ find_package(CGAL REQUIRED)
find_package(Eigen3) find_package(Eigen3)
include(CGAL_Eigen3_support) include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support) if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program("Epick_d.cpp") file(
target_link_libraries(Epick_d PUBLIC CGAL::Eigen3_support) GLOB cppfiles
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach(cppfile ${cppfiles})
get_filename_component(target ${cppfile} NAME_WE)
create_single_source_cgal_program("${cppfile}")
target_link_libraries(${target} PUBLIC CGAL::Eigen3_support)
endforeach()
else() else()
message( message(
STATUS STATUS
"NOTICE: This program requires the Eigen3 library, and will not be compiled." "NOTICE: These programs require the Eigen3 library, and will not be compiled."
) )
endif() endif()

View File

@ -0,0 +1,77 @@
// Benchmark on the construction of Delaunay 2D with Epick (Kernel_23) vs
// something based on NewKernel_d that uses Eigen::Vector2d as Point_2.
#if __cpp_aligned_new >= 201606L
#if 1
#define CGAL_NEWKERNEL_D_USE_EIGEN_VECTOR 1
#include <CGAL/Epick_d.h>
#include <CGAL/NewKernel_d/Kernel_2_interface.h>
#include <CGAL/Triangulation_structural_filtering_traits.h>
namespace CGAL {
struct Epick_2_help1
: Cartesian_filter_K<
Cartesian_base_d<double, CGAL::Dimension_tag<2>>,
Cartesian_base_d<Interval_nt_advanced, CGAL::Dimension_tag<2>>,
Cartesian_base_d<internal::Exact_field_selector<double>::Type, CGAL::Dimension_tag<2>>
>
{
};
struct Epick_2_help2
: Cartesian_filter_K<
Epick_2_help1,
Cartesian_base_d<Interval_nt_advanced, CGAL::Dimension_tag<2>>,
Cartesian_base_d<internal::Exact_ring_selector<double>::Type, CGAL::Dimension_tag<2>>,
Functors_without_division<CGAL::Dimension_tag<2>>::type
>
{ };
struct Epick_2
: Kernel_2_interface<Cartesian_static_filters<CGAL::Dimension_tag<2>,Epick_2_help2>>
{ };
template <>
struct Triangulation_structural_filtering_traits<Epick_2> {
typedef Tag_true Use_structural_filtering_tag;
};
}
typedef CGAL::Epick_2 K;
static_assert(std::is_same<K::Point_2, Eigen::Vector2d>::value, "");
#else
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
#endif
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Timer.h>
#include <iostream>
#include <random>
#include <stdlib.h>
typedef CGAL::Delaunay_triangulation_2<K> DT;
typedef DT::Point Point_2;
int main(int argc,char** argv)
{
int n = (argc > 1) ? atoi(argv[1]) : 100000;
std::vector<Point_2> points;
points.reserve( n );
std::mt19937 gen(1234);
std::uniform_real_distribution<> dis(1.0, 2.0);
for(int i=0;i<n;++i)points.emplace_back(dis(gen),dis(gen));
CGAL::Timer timer;
timer.start();
DT dt;
dt.insert(points.begin(), points.end());
timer.stop();
std::size_t N = dt.number_of_vertices();
std::cout << N << " points of type " << typeid(Point_2).name() << std::endl;
std::cout << timer.time() << " seconds\n";
}
#else
#include <iostream>
int main(){
std::cerr << "This program requires C++17 or later.\n";
}
#endif