mirror of https://github.com/CGAL/cgal
Merge branch 'Tangential_complex-cjamin-old' into Tangential_complex-cjamin
This commit is contained in:
commit
42f726bf24
|
|
@ -204,7 +204,7 @@ launch()
|
||||||
/*mesher_->initialize();
|
/*mesher_->initialize();
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while ( ! mesher_->is_algorithm_done() && continue_ )
|
while ( ! mesher_->is_algorithm_done() && continue_ )
|
||||||
|
|
|
||||||
|
|
@ -2651,7 +2651,7 @@ rebuild_restricted_delaunay(OutdatedCells& outdated_cells,
|
||||||
|
|
||||||
# ifdef CGAL_MESH_3_PROFILING
|
# ifdef CGAL_MESH_3_PROFILING
|
||||||
std::cerr << std::endl << " Updating cells...";
|
std::cerr << std::endl << " Updating cells...";
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
size_t num_cells = c3t3_.number_of_cells_in_complex();
|
size_t num_cells = c3t3_.number_of_cells_in_complex();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,7 @@ private:
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
std::cerr << "Computing moves...";
|
std::cerr << "Computing moves...";
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -688,7 +688,7 @@ operator()(int nb_iterations, Visitor visitor)
|
||||||
running_time_.start();
|
running_time_.start();
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Fill set containing moving vertices
|
// Fill set containing moving vertices
|
||||||
|
|
@ -896,7 +896,7 @@ update_mesh(const Moves_vector& moves,
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
std::cerr << "Moving vertices...";
|
std::cerr << "Moving vertices...";
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
|
|
||||||
|
|
@ -320,7 +320,7 @@ Mesher_3<C3T3,MC,MD>::refine_mesh(std::string dump_after_refine_surface_prefix)
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
std::cerr << "Refining facets..." << std::endl;
|
std::cerr << "Refining facets..." << std::endl;
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
facets_mesher_.refine(facets_visitor_);
|
facets_mesher_.refine(facets_visitor_);
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
|
|
@ -476,7 +476,7 @@ initialize()
|
||||||
{
|
{
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
std::cerr << "Initializing... ";
|
std::cerr << "Initializing... ";
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
//=====================================
|
//=====================================
|
||||||
// Bounding box estimation
|
// Bounding box estimation
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ protected:
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
protected:
|
protected:
|
||||||
WallClockTimer m_timer;
|
Wall_clock_timer m_timer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,10 @@
|
||||||
// TBB timers
|
// TBB timers
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
#include <tbb/tick_count.h>
|
#include <tbb/tick_count.h>
|
||||||
struct WallClockTimer
|
struct Wall_clock_timer
|
||||||
{
|
{
|
||||||
tbb::tick_count t;
|
tbb::tick_count t;
|
||||||
WallClockTimer()
|
Wall_clock_timer()
|
||||||
{
|
{
|
||||||
t = tbb::tick_count::now();
|
t = tbb::tick_count::now();
|
||||||
}
|
}
|
||||||
|
|
@ -48,10 +48,10 @@
|
||||||
#else
|
#else
|
||||||
#include <CGAL/Real_timer.h>
|
#include <CGAL/Real_timer.h>
|
||||||
|
|
||||||
struct WallClockTimer
|
struct Wall_clock_timer
|
||||||
{
|
{
|
||||||
CGAL::Real_timer t;
|
CGAL::Real_timer t;
|
||||||
WallClockTimer()
|
Wall_clock_timer()
|
||||||
{
|
{
|
||||||
t.start();
|
t.start();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -632,7 +632,7 @@ scan_triangulation_impl()
|
||||||
typedef typename Tr::Finite_cells_iterator Finite_cell_iterator;
|
typedef typename Tr::Finite_cells_iterator Finite_cell_iterator;
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -882,7 +882,7 @@ scan_triangulation_impl()
|
||||||
typedef typename Tr::Finite_facets_iterator Finite_facet_iterator;
|
typedef typename Tr::Finite_facets_iterator Finite_facet_iterator;
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_VERY_VERBOSE
|
#ifdef CGAL_MESH_3_VERY_VERBOSE
|
||||||
|
|
|
||||||
|
|
@ -797,7 +797,7 @@ operator()(Visitor visitor)
|
||||||
running_time_.start();
|
running_time_.start();
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Build priority queue (we use one queue for all steps)
|
// Build priority queue (we use one queue for all steps)
|
||||||
|
|
|
||||||
|
|
@ -453,7 +453,7 @@ public: // methods
|
||||||
operator()(Visitor visitor = Visitor())
|
operator()(Visitor visitor = Visitor())
|
||||||
{
|
{
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Mesh_optimization_return_code ret =
|
Mesh_optimization_return_code ret =
|
||||||
|
|
@ -964,7 +964,7 @@ pump_vertices(double sliver_criterion_limit,
|
||||||
Visitor& visitor)
|
Visitor& visitor)
|
||||||
{
|
{
|
||||||
#ifdef CGAL_MESH_3_PROFILING
|
#ifdef CGAL_MESH_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
init(sliver_criterion_limit);
|
init(sliver_criterion_limit);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright (c) 2014
|
||||||
|
// INRIA Saclay-Ile de France (France)
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 3 of the License,
|
||||||
|
// or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
// Author(s) : Marc Glisse
|
||||||
|
|
||||||
|
#ifndef CGAL_EPECK_D_H
|
||||||
|
#define CGAL_EPECK_D_H
|
||||||
|
#include <CGAL/NewKernel_d/Cartesian_base.h>
|
||||||
|
#include <CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h>
|
||||||
|
#include <CGAL/NewKernel_d/Kernel_d_interface.h>
|
||||||
|
#include <CGAL/internal/Exact_type_selector.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
#define CGAL_BASE \
|
||||||
|
Cartesian_base_d<internal::Exact_field_selector<double>::Type, Dim>
|
||||||
|
template<class Dim>
|
||||||
|
struct Epeck_d_help1
|
||||||
|
: CGAL_BASE
|
||||||
|
{
|
||||||
|
CGAL_CONSTEXPR Epeck_d_help1(){}
|
||||||
|
CGAL_CONSTEXPR Epeck_d_help1(int d):CGAL_BASE(d){}
|
||||||
|
};
|
||||||
|
#undef CGAL_BASE
|
||||||
|
#define CGAL_BASE \
|
||||||
|
Kernel_d_interface< \
|
||||||
|
Cartesian_wrap< \
|
||||||
|
Epeck_d_help1<Dim>, \
|
||||||
|
Epeck_d<Dim> > >
|
||||||
|
template<class Dim>
|
||||||
|
struct Epeck_d
|
||||||
|
: CGAL_BASE
|
||||||
|
{
|
||||||
|
CGAL_CONSTEXPR Epeck_d(){}
|
||||||
|
CGAL_CONSTEXPR Epeck_d(int d):CGAL_BASE(d){}
|
||||||
|
};
|
||||||
|
#undef CGAL_BASE
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -30,7 +30,7 @@ namespace CGAL {
|
||||||
|
|
||||||
template < typename Base_, typename AK_, typename EK_ >
|
template < typename Base_, typename AK_, typename EK_ >
|
||||||
struct Cartesian_filter_K : public Base_,
|
struct Cartesian_filter_K : public Base_,
|
||||||
private Store_kernel<AK_>, private Store_kernel2<EK_>
|
private Store_kernel<AK_>, private Store_kernel2<EK_>
|
||||||
{
|
{
|
||||||
CGAL_CONSTEXPR Cartesian_filter_K(){}
|
CGAL_CONSTEXPR Cartesian_filter_K(){}
|
||||||
CGAL_CONSTEXPR Cartesian_filter_K(int d):Base_(d){}
|
CGAL_CONSTEXPR Cartesian_filter_K(int d):Base_(d){}
|
||||||
|
|
@ -61,11 +61,11 @@ struct Cartesian_filter_K : public Base_,
|
||||||
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> struct Functor :
|
template<class T,class D=void,class=typename Get_functor_category<Cartesian_filter_K,T>::type> struct Functor :
|
||||||
Inherit_functor<Kernel_base,T,D> {};
|
Inherit_functor<Kernel_base,T,D> {};
|
||||||
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<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<EP,AP,C2E,C2A> type;
|
typedef Filtered_predicate2<EP,AP,C2E,C2A> type;
|
||||||
};
|
};
|
||||||
// TODO:
|
// TODO:
|
||||||
// template<class T> struct Functor<T,No_filter_tag,Predicate_tag> :
|
// template<class T> struct Functor<T,No_filter_tag,Predicate_tag> :
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,8 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
|
||||||
typedef typename Get_functor<Base, Point_dimension_tag>::type Point_dimension_d;
|
typedef typename Get_functor<Base, Point_dimension_tag>::type Point_dimension_d;
|
||||||
typedef typename Get_functor<Base, Side_of_oriented_sphere_tag>::type Side_of_oriented_sphere_d;
|
typedef typename Get_functor<Base, Side_of_oriented_sphere_tag>::type Side_of_oriented_sphere_d;
|
||||||
typedef typename Get_functor<Base, Power_test_tag>::type Power_test_d;
|
typedef typename Get_functor<Base, Power_test_tag>::type Power_test_d;
|
||||||
|
typedef typename Get_functor<Base, Power_center_tag>::type Power_center_d;
|
||||||
|
typedef typename Get_functor<Base, Power_distance_tag>::type Power_distance_d;
|
||||||
typedef typename Get_functor<Base, Contained_in_affine_hull_tag>::type Contained_in_affine_hull_d;
|
typedef typename Get_functor<Base, Contained_in_affine_hull_tag>::type Contained_in_affine_hull_d;
|
||||||
typedef typename Get_functor<Base, Construct_flat_orientation_tag>::type Construct_flat_orientation_d;
|
typedef typename Get_functor<Base, Construct_flat_orientation_tag>::type Construct_flat_orientation_d;
|
||||||
typedef typename Get_functor<Base, In_flat_orientation_tag>::type In_flat_orientation_d;
|
typedef typename Get_functor<Base, In_flat_orientation_tag>::type In_flat_orientation_d;
|
||||||
|
|
@ -73,6 +75,7 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
|
||||||
typedef typename Get_functor<Base, In_flat_power_test_tag>::type In_flat_power_test_d;
|
typedef typename Get_functor<Base, In_flat_power_test_tag>::type In_flat_power_test_d;
|
||||||
typedef typename Get_functor<Base, Point_to_vector_tag>::type Point_to_vector_d;
|
typedef typename Get_functor<Base, Point_to_vector_tag>::type Point_to_vector_d;
|
||||||
typedef typename Get_functor<Base, Vector_to_point_tag>::type Vector_to_point_d;
|
typedef typename Get_functor<Base, Vector_to_point_tag>::type Vector_to_point_d;
|
||||||
|
typedef typename Get_functor<Base, Translated_point_tag>::type Translated_point_d;
|
||||||
typedef typename Get_functor<Base, Scaled_vector_tag>::type Scaled_vector_d;
|
typedef typename Get_functor<Base, Scaled_vector_tag>::type Scaled_vector_d;
|
||||||
typedef typename Get_functor<Base, Difference_of_vectors_tag>::type Difference_of_vectors_d;
|
typedef typename Get_functor<Base, Difference_of_vectors_tag>::type Difference_of_vectors_d;
|
||||||
typedef typename Get_functor<Base, Difference_of_points_tag>::type Difference_of_points_d;
|
typedef typename Get_functor<Base, Difference_of_points_tag>::type Difference_of_points_d;
|
||||||
|
|
@ -188,6 +191,8 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
|
||||||
Point_of_sphere_d point_of_sphere_d_object()const{ return Point_of_sphere_d(*this); }
|
Point_of_sphere_d point_of_sphere_d_object()const{ return Point_of_sphere_d(*this); }
|
||||||
Side_of_oriented_sphere_d side_of_oriented_sphere_d_object()const{ return Side_of_oriented_sphere_d(*this); }
|
Side_of_oriented_sphere_d side_of_oriented_sphere_d_object()const{ return Side_of_oriented_sphere_d(*this); }
|
||||||
Power_test_d power_test_d_object()const{ return Power_test_d(*this); }
|
Power_test_d power_test_d_object()const{ return Power_test_d(*this); }
|
||||||
|
Power_center_d power_center_d_object()const{ return Power_center_d(*this); }
|
||||||
|
Power_distance_d power_distance_d_object()const{ return Power_distance_d(*this); }
|
||||||
Side_of_bounded_sphere_d side_of_bounded_sphere_d_object()const{ return Side_of_bounded_sphere_d(*this); }
|
Side_of_bounded_sphere_d side_of_bounded_sphere_d_object()const{ return Side_of_bounded_sphere_d(*this); }
|
||||||
Contained_in_affine_hull_d contained_in_affine_hull_d_object()const{ return Contained_in_affine_hull_d(*this); }
|
Contained_in_affine_hull_d contained_in_affine_hull_d_object()const{ return Contained_in_affine_hull_d(*this); }
|
||||||
Contained_in_linear_hull_d contained_in_linear_hull_d_object()const{ return Contained_in_linear_hull_d(*this); }
|
Contained_in_linear_hull_d contained_in_linear_hull_d_object()const{ return Contained_in_linear_hull_d(*this); }
|
||||||
|
|
@ -198,6 +203,7 @@ template <class Base_> struct Kernel_d_interface : public Base_ {
|
||||||
In_flat_power_test_d in_flat_power_test_d_object()const{ return In_flat_power_test_d(*this); }
|
In_flat_power_test_d in_flat_power_test_d_object()const{ return In_flat_power_test_d(*this); }
|
||||||
Point_to_vector_d point_to_vector_d_object()const{ return Point_to_vector_d(*this); }
|
Point_to_vector_d point_to_vector_d_object()const{ return Point_to_vector_d(*this); }
|
||||||
Vector_to_point_d vector_to_point_d_object()const{ return Vector_to_point_d(*this); }
|
Vector_to_point_d vector_to_point_d_object()const{ return Vector_to_point_d(*this); }
|
||||||
|
Translated_point_d translated_point_d_object()const{ return Translated_point_d(*this); }
|
||||||
Scaled_vector_d scaled_vector_d_object()const{ return Scaled_vector_d(*this); }
|
Scaled_vector_d scaled_vector_d_object()const{ return Scaled_vector_d(*this); }
|
||||||
Difference_of_vectors_d difference_of_vectors_d_object()const{ return Difference_of_vectors_d(*this); }
|
Difference_of_vectors_d difference_of_vectors_d_object()const{ return Difference_of_vectors_d(*this); }
|
||||||
Difference_of_points_d difference_of_points_d_object()const{ return Difference_of_points_d(*this); }
|
Difference_of_points_d difference_of_points_d_object()const{ return Difference_of_points_d(*this); }
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ template <class R_> struct Construct_sphere : Store_kernel<R_> {
|
||||||
}
|
}
|
||||||
template <class Iter>
|
template <class Iter>
|
||||||
result_type operator()(Iter f, Iter e)const{
|
result_type operator()(Iter f, Iter e)const{
|
||||||
typedef typename Get_type<R_, Point_tag>::type Point;
|
|
||||||
typename Get_functor<R_, Construct_circumcenter_tag>::type cc(this->kernel());
|
typename Get_functor<R_, Construct_circumcenter_tag>::type cc(this->kernel());
|
||||||
typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());
|
typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,33 @@ template <class R_> struct Point_weight {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class R_> struct Power_distance : private Store_kernel<R_> {
|
||||||
|
CGAL_FUNCTOR_INIT_STORE(Power_distance)
|
||||||
|
typedef typename Get_type<R_, Weighted_point_tag>::type first_argument_type;
|
||||||
|
typedef first_argument_type second_argument_type;
|
||||||
|
typedef typename Get_type<R_, FT_tag>::type result_type;
|
||||||
|
|
||||||
|
result_type operator()(first_argument_type const&a, second_argument_type const&b)const{
|
||||||
|
typename Get_functor<R_, Point_drop_weight_tag>::type pdw(this->kernel());
|
||||||
|
typename Get_functor<R_, Point_weight_tag>::type pw(this->kernel());
|
||||||
|
typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());
|
||||||
|
return sd(pdw(a),pdw(b))-pw(a)-pw(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class R_> struct Power_distance_to_point : private Store_kernel<R_> {
|
||||||
|
CGAL_FUNCTOR_INIT_STORE(Power_distance_to_point)
|
||||||
|
typedef typename Get_type<R_, Weighted_point_tag>::type first_argument_type;
|
||||||
|
typedef typename Get_type<R_, Point_tag>::type second_argument_type;
|
||||||
|
typedef typename Get_type<R_, FT_tag>::type result_type;
|
||||||
|
|
||||||
|
result_type operator()(first_argument_type const&a, second_argument_type const&b)const{
|
||||||
|
typename Get_functor<R_, Point_drop_weight_tag>::type pdw(this->kernel());
|
||||||
|
typename Get_functor<R_, Point_weight_tag>::type pw(this->kernel());
|
||||||
|
typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());
|
||||||
|
return sd(pdw(a),b)-pw(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<class R_> struct Power_test : private Store_kernel<R_> {
|
template<class R_> struct Power_test : private Store_kernel<R_> {
|
||||||
CGAL_FUNCTOR_INIT_STORE(Power_test)
|
CGAL_FUNCTOR_INIT_STORE(Power_test)
|
||||||
typedef R_ R;
|
typedef R_ R;
|
||||||
|
|
@ -114,6 +141,56 @@ template<class R_> struct In_flat_power_test : private Store_kernel<R_> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Construct a point at (weighted) distance 0 from all the input
|
||||||
|
template <class R_> struct Power_center : Store_kernel<R_> {
|
||||||
|
CGAL_FUNCTOR_INIT_STORE(Power_center)
|
||||||
|
typedef typename Get_type<R_, Weighted_point_tag>::type WPoint;
|
||||||
|
typedef WPoint result_type;
|
||||||
|
typedef typename Get_type<R_, Point_tag>::type Point;
|
||||||
|
typedef typename Get_type<R_, FT_tag>::type FT;
|
||||||
|
template <class Iter>
|
||||||
|
result_type operator()(Iter f, Iter e)const{
|
||||||
|
// 2*(x-y).c == (x^2-wx^2)-(y^2-wy^2)
|
||||||
|
typedef typename R_::LA LA;
|
||||||
|
typedef typename LA::Square_matrix Matrix;
|
||||||
|
typedef typename LA::Vector Vec;
|
||||||
|
typedef typename LA::Construct_vector CVec;
|
||||||
|
typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
|
||||||
|
typename Get_functor<R_, Construct_ttag<Point_tag> >::type cp(this->kernel());
|
||||||
|
typename Get_functor<R_, Point_dimension_tag>::type pd(this->kernel());
|
||||||
|
typename Get_functor<R_, Squared_distance_to_origin_tag>::type sdo(this->kernel());
|
||||||
|
typename Get_functor<R_, Power_distance_to_point_tag>::type pdp(this->kernel());
|
||||||
|
typename Get_functor<R_, Point_drop_weight_tag>::type pdw(this->kernel());
|
||||||
|
typename Get_functor<R_, Point_weight_tag>::type pw(this->kernel());
|
||||||
|
typename Get_functor<R_, Construct_ttag<Weighted_point_tag> >::type cwp(this->kernel());
|
||||||
|
|
||||||
|
WPoint const& wp0 = *f;
|
||||||
|
Point const& p0 = pdw(wp0);
|
||||||
|
int d = pd(p0);
|
||||||
|
FT const& n0 = sdo(p0) - pw(wp0);
|
||||||
|
Matrix m(d,d);
|
||||||
|
Vec b = typename CVec::Dimension()(d);
|
||||||
|
// Write the point coordinates in lines.
|
||||||
|
int i;
|
||||||
|
for(i=0; ++f!=e; ++i) {
|
||||||
|
WPoint const& wp=*f;
|
||||||
|
Point const& p=pdw(wp);
|
||||||
|
FT const& np = sdo(p) - pw(wp);
|
||||||
|
for(int j=0;j<d;++j) {
|
||||||
|
m(i,j)=2*(c(p,j)-c(p0,j));
|
||||||
|
b[i] = np - n0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CGAL_assertion (i == d);
|
||||||
|
Vec res = typename CVec::Dimension()(d);;
|
||||||
|
//std::cout << "Mat: " << m << "\n Vec: " << one << std::endl;
|
||||||
|
LA::solve(res, CGAL_MOVE(m), CGAL_MOVE(b));
|
||||||
|
//std::cout << "Sol: " << res << std::endl;
|
||||||
|
Point center = cp(d,LA::vector_begin(res),LA::vector_end(res));
|
||||||
|
FT const& r2 = pdp (wp0, center);
|
||||||
|
return cwp(CGAL_MOVE(center), r2);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
CGAL_KD_DEFAULT_TYPE(Weighted_point_tag,(CGAL::KerD::Weighted_point<K>),(Point_tag),());
|
CGAL_KD_DEFAULT_TYPE(Weighted_point_tag,(CGAL::KerD::Weighted_point<K>),(Point_tag),());
|
||||||
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Weighted_point_tag>,(CartesianDKernelFunctors::Construct_weighted_point<K>),(Weighted_point_tag,Point_tag),());
|
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Weighted_point_tag>,(CartesianDKernelFunctors::Construct_weighted_point<K>),(Weighted_point_tag,Point_tag),());
|
||||||
|
|
@ -121,5 +198,8 @@ CGAL_KD_DEFAULT_FUNCTOR(Point_drop_weight_tag,(CartesianDKernelFunctors::Point_d
|
||||||
CGAL_KD_DEFAULT_FUNCTOR(Point_weight_tag,(CartesianDKernelFunctors::Point_weight<K>),(Weighted_point_tag,Point_tag),());
|
CGAL_KD_DEFAULT_FUNCTOR(Point_weight_tag,(CartesianDKernelFunctors::Point_weight<K>),(Weighted_point_tag,Point_tag),());
|
||||||
CGAL_KD_DEFAULT_FUNCTOR(Power_test_tag,(CartesianDKernelFunctors::Power_test<K>),(Weighted_point_tag),(Power_test_raw_tag,Point_drop_weight_tag,Point_weight_tag));
|
CGAL_KD_DEFAULT_FUNCTOR(Power_test_tag,(CartesianDKernelFunctors::Power_test<K>),(Weighted_point_tag),(Power_test_raw_tag,Point_drop_weight_tag,Point_weight_tag));
|
||||||
CGAL_KD_DEFAULT_FUNCTOR(In_flat_power_test_tag,(CartesianDKernelFunctors::In_flat_power_test<K>),(Weighted_point_tag),(In_flat_power_test_raw_tag,Point_drop_weight_tag,Point_weight_tag));
|
CGAL_KD_DEFAULT_FUNCTOR(In_flat_power_test_tag,(CartesianDKernelFunctors::In_flat_power_test<K>),(Weighted_point_tag),(In_flat_power_test_raw_tag,Point_drop_weight_tag,Point_weight_tag));
|
||||||
|
CGAL_KD_DEFAULT_FUNCTOR(Power_distance_tag,(CartesianDKernelFunctors::Power_distance<K>),(Weighted_point_tag,Point_tag),(Squared_distance_tag,Point_drop_weight_tag,Point_weight_tag));
|
||||||
|
CGAL_KD_DEFAULT_FUNCTOR(Power_distance_to_point_tag,(CartesianDKernelFunctors::Power_distance_to_point<K>),(Weighted_point_tag,Point_tag),(Squared_distance_tag,Point_drop_weight_tag,Point_weight_tag));
|
||||||
|
CGAL_KD_DEFAULT_FUNCTOR(Power_center_tag,(CartesianDKernelFunctors::Power_center<K>),(Weighted_point_tag,Point_tag),(Compute_point_cartesian_coordinate_tag,Construct_ttag<Point_tag>,Construct_ttag<Weighted_point_tag>,Point_dimension_tag,Squared_distance_to_origin_tag,Point_drop_weight_tag,Point_weight_tag,Power_distance_to_point_tag));
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,8 @@ namespace CGAL {
|
||||||
CGAL_DECL_COMPUTE(Hyperplane_translation);
|
CGAL_DECL_COMPUTE(Hyperplane_translation);
|
||||||
CGAL_DECL_COMPUTE(Value_at);
|
CGAL_DECL_COMPUTE(Value_at);
|
||||||
CGAL_DECL_COMPUTE(Point_weight);
|
CGAL_DECL_COMPUTE(Point_weight);
|
||||||
|
CGAL_DECL_COMPUTE(Power_distance);
|
||||||
|
CGAL_DECL_COMPUTE(Power_distance_to_point);
|
||||||
#undef CGAL_DECL_COMPUTE
|
#undef CGAL_DECL_COMPUTE
|
||||||
|
|
||||||
#define CGAL_DECL_ITER_OBJ(X,Y,Z,C) struct X##_tag {}; \
|
#define CGAL_DECL_ITER_OBJ(X,Y,Z,C) struct X##_tag {}; \
|
||||||
|
|
@ -269,6 +271,7 @@ namespace CGAL {
|
||||||
CGAL_DECL_CONSTRUCT(Construct_max_vertex,Point);
|
CGAL_DECL_CONSTRUCT(Construct_max_vertex,Point);
|
||||||
CGAL_DECL_CONSTRUCT(Construct_circumcenter,Point);
|
CGAL_DECL_CONSTRUCT(Construct_circumcenter,Point);
|
||||||
CGAL_DECL_CONSTRUCT(Point_drop_weight,Point);
|
CGAL_DECL_CONSTRUCT(Point_drop_weight,Point);
|
||||||
|
CGAL_DECL_CONSTRUCT(Power_center,Weighted_point);
|
||||||
#undef CGAL_DECL_CONSTRUCT
|
#undef CGAL_DECL_CONSTRUCT
|
||||||
#if 0
|
#if 0
|
||||||
#define CGAL_DECL_ITER_CONSTRUCT(X,Y) struct X##_tag {}; \
|
#define CGAL_DECL_ITER_CONSTRUCT(X,Y) struct X##_tag {}; \
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <CGAL/NewKernel_d/Types/Weighted_point.h>
|
#include <CGAL/NewKernel_d/Types/Weighted_point.h>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
//typedef CGAL::Cartesian_base_d<double,CGAL::Dimension_tag<2> > K0;
|
//typedef CGAL::Cartesian_base_d<double,CGAL::Dimension_tag<2> > K0;
|
||||||
//typedef CGAL::Cartesian_base_d<CGAL::Interval_nt_advanced,CGAL::Dimension_tag<2> > KA;
|
//typedef CGAL::Cartesian_base_d<CGAL::Interval_nt_advanced,CGAL::Dimension_tag<2> > KA;
|
||||||
|
|
@ -74,6 +75,7 @@ void test2(){
|
||||||
typedef typename K1::Ray_d R;
|
typedef typename K1::Ray_d R;
|
||||||
typedef typename K1::Iso_box_d IB;
|
typedef typename K1::Iso_box_d IB;
|
||||||
typedef typename K1::Flat_orientation_d FO;
|
typedef typename K1::Flat_orientation_d FO;
|
||||||
|
typedef typename K1::Weighted_point_d WP;
|
||||||
|
|
||||||
//typedef K1::Construct_point CP;
|
//typedef K1::Construct_point CP;
|
||||||
typedef typename K1::Construct_point_d CP;
|
typedef typename K1::Construct_point_d CP;
|
||||||
|
|
@ -125,6 +127,13 @@ void test2(){
|
||||||
typedef typename K1::Construct_min_vertex_d CmV;
|
typedef typename K1::Construct_min_vertex_d CmV;
|
||||||
typedef typename K1::Construct_max_vertex_d CMV;
|
typedef typename K1::Construct_max_vertex_d CMV;
|
||||||
typedef typename K1::Compute_squared_radius_d SR;
|
typedef typename K1::Compute_squared_radius_d SR;
|
||||||
|
typedef typename K1::Translated_point_d TP;
|
||||||
|
typedef typename K1::Power_center_d PC;
|
||||||
|
typedef typename K1::Power_distance_d PoD;
|
||||||
|
typedef typename K1::Weighted_point_d WP;
|
||||||
|
typedef typename K1::Construct_weighted_point_d CWP;
|
||||||
|
typedef typename K1::Point_drop_weight_d PDW;
|
||||||
|
typedef typename K1::Point_weight_d PW;
|
||||||
|
|
||||||
CGAL_USE_TYPE(AT);
|
CGAL_USE_TYPE(AT);
|
||||||
CGAL_USE_TYPE(D);
|
CGAL_USE_TYPE(D);
|
||||||
|
|
@ -186,6 +195,12 @@ void test2(){
|
||||||
CmV cmv Kinit(construct_min_vertex_d_object);
|
CmV cmv Kinit(construct_min_vertex_d_object);
|
||||||
CMV cMv Kinit(construct_max_vertex_d_object);
|
CMV cMv Kinit(construct_max_vertex_d_object);
|
||||||
SR sr Kinit(compute_squared_radius_d_object);
|
SR sr Kinit(compute_squared_radius_d_object);
|
||||||
|
TP tp Kinit(translated_point_d_object);
|
||||||
|
PC pc Kinit(power_center_d_object);
|
||||||
|
CWP cwp Kinit(construct_weighted_point_d_object);
|
||||||
|
PDW pdw Kinit(point_drop_weight_d_object);
|
||||||
|
PW pw Kinit(point_weight_d_object);
|
||||||
|
PoD pod Kinit(power_distance_d_object);
|
||||||
|
|
||||||
CGAL_USE(bc);
|
CGAL_USE(bc);
|
||||||
CGAL_USE(pol);
|
CGAL_USE(pol);
|
||||||
|
|
@ -193,11 +208,12 @@ void test2(){
|
||||||
CGAL_USE(cd);
|
CGAL_USE(cd);
|
||||||
CGAL_USE(cli);
|
CGAL_USE(cli);
|
||||||
CGAL_USE(cr);
|
CGAL_USE(cr);
|
||||||
|
using std::abs;
|
||||||
P a=cp(3,4);
|
P a=cp(3,4);
|
||||||
assert(pd(a)==2);
|
assert(pd(a)==2);
|
||||||
assert(pv(a)[1]==4);
|
assert(pv(a)[1]==4);
|
||||||
P b=vp(cv(5,6,7));
|
P b=vp(cv(5,6,7));
|
||||||
assert(fabs(b[0]-5./7)<.0001);
|
assert(abs(b[0]-5./7)<.0001);
|
||||||
assert(lc(b,a,1));
|
assert(lc(b,a,1));
|
||||||
assert(!lc(a,b,0));
|
assert(!lc(a,b,0));
|
||||||
int rr[]={3,5,2};
|
int rr[]={3,5,2};
|
||||||
|
|
@ -211,8 +227,8 @@ void test2(){
|
||||||
assert(cl(a,c)==CGAL::SMALLER);
|
assert(cl(a,c)==CGAL::SMALLER);
|
||||||
assert(ll(b,c));
|
assert(ll(b,c));
|
||||||
assert(cl(c,b)==CGAL::LARGER);
|
assert(cl(c,b)==CGAL::LARGER);
|
||||||
assert(fabs(m(a,c)[0]-3)<.0001);
|
assert(abs(m(a,c)[0]-3)<.0001);
|
||||||
assert(fabs(m(a,c)[1]-4.5)<.0001);
|
assert(abs(m(a,c)[1]-4.5)<.0001);
|
||||||
P d=cp(r,r+3,CGAL::Homogeneous_tag());
|
P d=cp(r,r+3,CGAL::Homogeneous_tag());
|
||||||
S s=cs(c,d);
|
S s=cs(c,d);
|
||||||
std::cout << cc(a,1) << std::endl;
|
std::cout << cc(a,1) << std::endl;
|
||||||
|
|
@ -267,9 +283,9 @@ void test2(){
|
||||||
assert(v.size()==1);
|
assert(v.size()==1);
|
||||||
assert(lr(tab3+0,tab3+2)==1);
|
assert(lr(tab3+0,tab3+2)==1);
|
||||||
H h=ch(tab2+1,tab2+3,tab2[0]);
|
H h=ch(tab2+1,tab2+3,tab2[0]);
|
||||||
assert(fabs(va(h,x2)-1)<.0001);
|
assert(abs(va(h,x2)-1)<.0001);
|
||||||
assert(fabs(va(h,x3)-1)<.0001);
|
assert(abs(va(h,x3)-1)<.0001);
|
||||||
assert(fabs(va(h,x1)+1)<.0001);
|
assert(abs(va(h,x1)+1)<.0001);
|
||||||
H h2=ch(tab2+1,tab2+3,x1,CGAL::ON_POSITIVE_SIDE);
|
H h2=ch(tab2+1,tab2+3,x1,CGAL::ON_POSITIVE_SIDE);
|
||||||
assert(hops(h2,x1));
|
assert(hops(h2,x1));
|
||||||
assert(os(h2,x1)==CGAL::ON_POSITIVE_SIDE);
|
assert(os(h2,x1)==CGAL::ON_POSITIVE_SIDE);
|
||||||
|
|
@ -330,20 +346,35 @@ void test2(){
|
||||||
Sp sp = csp(tabz+0,tabz+3);
|
Sp sp = csp(tabz+0,tabz+3);
|
||||||
P cent0=cos(sp);
|
P cent0=cos(sp);
|
||||||
P cent1=cos(tabz+0,tabz+3);
|
P cent1=cos(tabz+0,tabz+3);
|
||||||
assert(fabs(cent0[0]-2)<.0001);
|
assert(abs(cent0[0]-2)<.0001);
|
||||||
assert(fabs(cent0[1]+3)<.0001);
|
assert(abs(cent0[1]+3)<.0001);
|
||||||
assert(fabs(cent1[0]-2)<.0001);
|
assert(abs(cent1[0]-2)<.0001);
|
||||||
assert(fabs(cent1[1]+3)<.0001);
|
assert(abs(cent1[1]+3)<.0001);
|
||||||
assert(fabs(sp.squared_radius()-25)<.0001);
|
assert(abs(sp.squared_radius()-25)<.0001);
|
||||||
|
#if 1
|
||||||
|
// Fails for an exact kernel
|
||||||
P psp0=ps(sp,0);
|
P psp0=ps(sp,0);
|
||||||
P psp1=ps(sp,1);
|
P psp1=ps(sp,1);
|
||||||
P psp2=ps(sp,2);
|
P psp2=ps(sp,2);
|
||||||
assert(!ed(psp0,psp1));
|
assert(!ed(psp0,psp1));
|
||||||
assert(!ed(psp0,psp2));
|
assert(!ed(psp0,psp2));
|
||||||
assert(!ed(psp2,psp1));
|
assert(!ed(psp2,psp1));
|
||||||
assert(fabs(sd(cent0,psp0)-25)<.0001);
|
assert(abs(sd(cent0,psp0)-25)<.0001);
|
||||||
assert(fabs(sd(cent0,psp1)-25)<.0001);
|
assert(abs(sd(cent0,psp1)-25)<.0001);
|
||||||
assert(fabs(sd(cent0,psp2)-25)<.0001);
|
assert(abs(sd(cent0,psp2)-25)<.0001);
|
||||||
|
#endif
|
||||||
|
P x2py1 = tp(x2,y1);
|
||||||
|
assert(x2py1[1]==-2);
|
||||||
|
WP tw[]={cwp(cp(5,0),1.5),cwp(cp(2,std::sqrt(3)),1),cwp(cp(2,-std::sqrt(3)),1)};
|
||||||
|
WP xw=pc(tw+0,tw+3);
|
||||||
|
assert(abs(pod(xw,tw[0]))<.0001);
|
||||||
|
assert(abs(pod(xw,tw[1]))<.0001);
|
||||||
|
assert(abs(pod(xw,tw[2]))<.0001);
|
||||||
|
assert(pdw(xw)[0]<2.95);
|
||||||
|
assert(pdw(xw)[0]>2.5);
|
||||||
|
assert(pw(xw)<2.95);
|
||||||
|
assert(pw(xw)>2.5);
|
||||||
|
|
||||||
|
|
||||||
P tl=cp(2,5);
|
P tl=cp(2,5);
|
||||||
P br=cp(4,-1);
|
P br=cp(4,-1);
|
||||||
|
|
@ -449,6 +480,7 @@ void test3(){
|
||||||
PD pd Kinit(point_dimension_d_object);
|
PD pd Kinit(point_dimension_d_object);
|
||||||
AI ai Kinit(affinely_independent_d_object);
|
AI ai Kinit(affinely_independent_d_object);
|
||||||
SBDS sbds Kinit(side_of_bounded_sphere_d_object);
|
SBDS sbds Kinit(side_of_bounded_sphere_d_object);
|
||||||
|
using std::abs;
|
||||||
P a; // Triangulation needs this :-(
|
P a; // Triangulation needs this :-(
|
||||||
a=cp(2,3,4);
|
a=cp(2,3,4);
|
||||||
assert(pd(a)==3);
|
assert(pd(a)==3);
|
||||||
|
|
@ -472,7 +504,7 @@ void test3(){
|
||||||
std::cout << *i << ' ';
|
std::cout << *i << ' ';
|
||||||
std::cout << '\n';
|
std::cout << '\n';
|
||||||
P e=cp(-2,3,0);
|
P e=cp(-2,3,0);
|
||||||
assert(fabs(sd(e,a)-32)<.0001);
|
assert(abs(sd(e,a)-32)<.0001);
|
||||||
P tab[]={a,b,c,d,e};
|
P tab[]={a,b,c,d,e};
|
||||||
std::cout << po (&tab[0],tab+4) << ' ';
|
std::cout << po (&tab[0],tab+4) << ' ';
|
||||||
std::cout << sos(&tab[0],tab+5) << ' ';
|
std::cout << sos(&tab[0],tab+5) << ' ';
|
||||||
|
|
|
||||||
|
|
@ -91,16 +91,26 @@ public:
|
||||||
|
|
||||||
struct Construct_cartesian_const_iterator_d: public Base_traits::Construct_cartesian_const_iterator_d{
|
struct Construct_cartesian_const_iterator_d: public Base_traits::Construct_cartesian_const_iterator_d{
|
||||||
PointPropertyMap ppmap;
|
PointPropertyMap ppmap;
|
||||||
using Base_traits::Construct_cartesian_const_iterator_d::operator();
|
|
||||||
|
|
||||||
Construct_cartesian_const_iterator_d(const typename Base_traits::Construct_cartesian_const_iterator_d& base, const PointPropertyMap& ppmap_)
|
Construct_cartesian_const_iterator_d(const typename Base_traits::Construct_cartesian_const_iterator_d& base, const PointPropertyMap& ppmap_)
|
||||||
:Base_traits::Construct_cartesian_const_iterator_d(base), ppmap(ppmap_){}
|
:Base_traits::Construct_cartesian_const_iterator_d(base), ppmap(ppmap_){}
|
||||||
|
|
||||||
typename Base_traits::Cartesian_const_iterator_d operator()(const Point_with_info& p) const
|
typename Base_traits::Cartesian_const_iterator_d operator()(const Point_with_info& p) const
|
||||||
{ return this->operator() (get(ppmap,p)); }
|
{ return Base_traits::Construct_cartesian_const_iterator_d::operator() (get(ppmap,p)); }
|
||||||
|
|
||||||
typename Base_traits::Cartesian_const_iterator_d operator()(const Point_with_info& p, int) const
|
typename Base_traits::Cartesian_const_iterator_d operator()(const Point_with_info& p, int) const
|
||||||
{ return this->operator() (get(ppmap,p),0); }
|
{ return Base_traits::Construct_cartesian_const_iterator_d::operator() (get(ppmap,p),0); }
|
||||||
|
|
||||||
|
// These 2 additional operators forward the call to Base_traits.
|
||||||
|
// This is needed because of an undocumented requirement of
|
||||||
|
// Orthogonal_k_neighbor_search and Orthogonal_incremental_neighbor_search:
|
||||||
|
// Traits::Construct_cartesian_const_iterator should be callable
|
||||||
|
// on the query point type
|
||||||
|
typename Base_traits::Cartesian_const_iterator_d operator()(const typename Base_traits::Point_d& p) const
|
||||||
|
{ return Base_traits::Construct_cartesian_const_iterator_d::operator() (p); }
|
||||||
|
|
||||||
|
typename Base_traits::Cartesian_const_iterator_d operator()(const typename Base_traits::Point_d& p, int) const
|
||||||
|
{ return Base_traits::Construct_cartesian_const_iterator_d::operator() (p,0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Construct_iso_box_d: public Base::Construct_iso_box_d{
|
struct Construct_iso_box_d: public Base::Construct_iso_box_d{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
# Created by the script cgal_create_cmake_script
|
||||||
|
# This is the CMake script for compiling a CGAL application.
|
||||||
|
|
||||||
|
|
||||||
|
project( Tangential_complex_benchmark )
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 2.6.2)
|
||||||
|
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6)
|
||||||
|
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3)
|
||||||
|
cmake_policy(VERSION 2.8.4)
|
||||||
|
else()
|
||||||
|
cmake_policy(VERSION 2.6)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Creates a new CMake option, turned ON by default
|
||||||
|
option(ACTIVATE_MSVC_PRECOMPILED_HEADERS
|
||||||
|
"Activate precompiled headers in MSVC"
|
||||||
|
OFF)
|
||||||
|
|
||||||
|
# Macro to add precompiled headers for MSVC
|
||||||
|
# This function does two things:
|
||||||
|
# 1. Enable precompiled headers on each file which is listed in "SourcesVar".
|
||||||
|
# 2. Add the content of "PrecompiledSource" (e.g. "StdAfx.cpp") to "SourcesVar".
|
||||||
|
MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
|
||||||
|
IF(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS)
|
||||||
|
GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
|
||||||
|
SET(Sources ${${SourcesVar}})
|
||||||
|
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
|
||||||
|
PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\"")
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${Sources}
|
||||||
|
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeaders}\" /FI\"${PrecompiledHeader}\"")
|
||||||
|
# Add precompiled header to SourcesVar
|
||||||
|
LIST(APPEND ${SourcesVar} ${PrecompiledSource})
|
||||||
|
ENDIF(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS)
|
||||||
|
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
|
||||||
|
|
||||||
|
# The compiler might need more memory because of precompiled headers
|
||||||
|
if(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS AND NOT(MSVC_VERSION LESS 1310))
|
||||||
|
set(CGAL_C_FLAGS "${CGAL_C_FLAGS} /Zm1000")
|
||||||
|
set(CGAL_CXX_FLAGS "${CGAL_CXX_FLAGS} /Zm1000")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(CGAL QUIET COMPONENTS Core )
|
||||||
|
|
||||||
|
if ( CGAL_FOUND )
|
||||||
|
include( ${CGAL_USE_FILE} )
|
||||||
|
|
||||||
|
find_package( TBB QUIET )
|
||||||
|
|
||||||
|
if( TBB_FOUND )
|
||||||
|
include(${TBB_USE_FILE})
|
||||||
|
list(APPEND CGAL_3RD_PARTY_LIBRARIES ${TBB_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
include( CGAL_CreateSingleSourceCGALProgram )
|
||||||
|
|
||||||
|
find_package(Eigen3 3.1.0)
|
||||||
|
if (EIGEN3_FOUND)
|
||||||
|
include( ${EIGEN3_USE_FILE} )
|
||||||
|
include_directories (BEFORE "../../include")
|
||||||
|
include_directories (BEFORE "include")
|
||||||
|
|
||||||
|
set (SOURCE_FILES "benchmark_tc.cpp")
|
||||||
|
ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" SOURCE_FILES)
|
||||||
|
create_single_source_cgal_program( ${SOURCE_FILES} )
|
||||||
|
|
||||||
|
else()
|
||||||
|
message(STATUS "NOTICE: Some of the executables in this directory need Eigen 3.1 (or greater) and will not be compiled.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
else()
|
||||||
|
message(STATUS "This program requires the CGAL library, and will not be compiled.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
// Build the precompiled headers.
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef STDAFX_H
|
||||||
|
#define STDAFX_H
|
||||||
|
|
||||||
|
// CGAL
|
||||||
|
#include <CGAL/Tangential_complex/config.h>
|
||||||
|
#include <CGAL/Epick_d.h>
|
||||||
|
#include <CGAL/Regular_triangulation_euclidean_traits.h>
|
||||||
|
#include <CGAL/Regular_triangulation.h>
|
||||||
|
#include <CGAL/Delaunay_triangulation.h>
|
||||||
|
#include <CGAL/Tangential_complex/utilities.h>
|
||||||
|
#include <CGAL/Tangential_complex/Point_cloud.h>
|
||||||
|
#include <CGAL/Combination_enumerator.h>
|
||||||
|
|
||||||
|
#endif //STDAFX_H
|
||||||
|
|
@ -0,0 +1,236 @@
|
||||||
|
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL: $
|
||||||
|
// $Id: $
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Clement Jamin
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
template<typename value_type = std::string>
|
||||||
|
class Simple_XML_exporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef value_type Value_type;
|
||||||
|
typedef std::vector<value_type> Element;
|
||||||
|
typedef std::map<std::string, value_type> Element_with_map;
|
||||||
|
typedef std::vector<Element> List_of_elements;
|
||||||
|
|
||||||
|
Simple_XML_exporter(
|
||||||
|
const std::string &list_name,
|
||||||
|
const std::string &element_name,
|
||||||
|
const std::vector<std::string> &subelement_names,
|
||||||
|
bool add_timestamp = true)
|
||||||
|
: m_list_name(list_name),
|
||||||
|
m_element_name(element_name),
|
||||||
|
m_subelement_names(subelement_names),
|
||||||
|
m_add_timestamp(add_timestamp)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool add_element(const Element &element)
|
||||||
|
{
|
||||||
|
if (element.size() == m_subelement_names.size())
|
||||||
|
{
|
||||||
|
m_list_of_elements.push_back(element);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: element.size() == m_subelement_names.size()" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_element(Element_with_map &element)
|
||||||
|
{
|
||||||
|
Element elt;
|
||||||
|
|
||||||
|
std::vector<std::string>::const_iterator
|
||||||
|
it_subelement_name = m_subelement_names.begin();
|
||||||
|
std::vector<std::string>::const_iterator
|
||||||
|
it_subelement_name_end = m_subelement_names.end();
|
||||||
|
for ( ; it_subelement_name != it_subelement_name_end ; ++it_subelement_name)
|
||||||
|
{
|
||||||
|
elt.push_back(element[*it_subelement_name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return add_element(elt);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool export_to_xml(const std::string &filename) const
|
||||||
|
{
|
||||||
|
std::ofstream xmlfile;
|
||||||
|
xmlfile.open(filename.c_str());
|
||||||
|
xmlfile << "<?xml version='1.0'?>" << std::endl;
|
||||||
|
xmlfile << "<" << m_list_name << ">" << std::endl;
|
||||||
|
|
||||||
|
typename List_of_elements::const_iterator it_element = m_list_of_elements.begin();
|
||||||
|
typename List_of_elements::const_iterator it_element_end = m_list_of_elements.end();
|
||||||
|
for (int id = 1 ; it_element != it_element_end ; ++it_element, ++id)
|
||||||
|
{
|
||||||
|
xmlfile << " <" << m_element_name << ">" << std::endl;
|
||||||
|
std::vector<std::string>::const_iterator
|
||||||
|
it_subelement_name = m_subelement_names.begin();
|
||||||
|
std::vector<std::string>::const_iterator
|
||||||
|
it_subelement_name_end = m_subelement_names.end();
|
||||||
|
|
||||||
|
if (m_add_timestamp)
|
||||||
|
xmlfile << " <id> " << time(NULL) << " </id>" << std::endl;
|
||||||
|
|
||||||
|
for (int i = 0 ;
|
||||||
|
it_subelement_name != it_subelement_name_end ;
|
||||||
|
++it_subelement_name, ++i)
|
||||||
|
{
|
||||||
|
xmlfile
|
||||||
|
<< " <" << *it_subelement_name << "> "
|
||||||
|
<< (*it_element)[i]
|
||||||
|
<< " </" << *it_subelement_name << ">" << std::endl;
|
||||||
|
}
|
||||||
|
xmlfile << " </" << m_element_name << ">" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlfile << "</" << m_list_name << ">" << std::endl;
|
||||||
|
xmlfile.close();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string m_list_name;
|
||||||
|
std::string m_element_name;
|
||||||
|
std::vector<std::string> m_subelement_names;
|
||||||
|
List_of_elements m_list_of_elements;
|
||||||
|
bool m_add_timestamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename value_type = std::string>
|
||||||
|
class Streaming_XML_exporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef value_type Value_type;
|
||||||
|
typedef std::vector<value_type> Element;
|
||||||
|
typedef std::map<std::string, value_type> Element_with_map;
|
||||||
|
typedef std::vector<Element> List_of_elements;
|
||||||
|
|
||||||
|
Streaming_XML_exporter(
|
||||||
|
const std::string &filename,
|
||||||
|
const std::string &list_name,
|
||||||
|
const std::string &element_name,
|
||||||
|
const std::vector<std::string> &subelement_names,
|
||||||
|
bool add_timestamp = true)
|
||||||
|
: m_list_name(list_name),
|
||||||
|
m_element_name(element_name),
|
||||||
|
m_subelement_names(subelement_names),
|
||||||
|
m_add_timestamp(add_timestamp)
|
||||||
|
{
|
||||||
|
m_xml_fstream.open(filename.c_str());
|
||||||
|
if (m_xml_fstream.good())
|
||||||
|
{
|
||||||
|
m_xml_fstream << "<?xml version='1.0'?>" << std::endl;
|
||||||
|
m_xml_fstream << "<" << m_list_name << ">" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Could not open file '" << filename << "'." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Streaming_XML_exporter()
|
||||||
|
{
|
||||||
|
close_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_file()
|
||||||
|
{
|
||||||
|
m_xml_fstream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_element(const Element &element)
|
||||||
|
{
|
||||||
|
if (element.size() == m_subelement_names.size())
|
||||||
|
{
|
||||||
|
m_xml_fstream << " <" << m_element_name << ">" << std::endl;
|
||||||
|
std::vector<std::string>::const_iterator
|
||||||
|
it_subelement_name = m_subelement_names.begin();
|
||||||
|
std::vector<std::string>::const_iterator
|
||||||
|
it_subelement_name_end = m_subelement_names.end();
|
||||||
|
|
||||||
|
if (m_add_timestamp)
|
||||||
|
{
|
||||||
|
m_xml_fstream << " <id> " << time(NULL) << " </id>" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ;
|
||||||
|
it_subelement_name != it_subelement_name_end ;
|
||||||
|
++it_subelement_name, ++i)
|
||||||
|
{
|
||||||
|
m_xml_fstream
|
||||||
|
<< " <" << *it_subelement_name << "> "
|
||||||
|
<< element[i]
|
||||||
|
<< " </" << *it_subelement_name << ">" << std::endl;
|
||||||
|
}
|
||||||
|
m_xml_fstream << " </" << m_element_name << ">" << std::endl;
|
||||||
|
|
||||||
|
// Save current pointer position
|
||||||
|
std::ofstream::streampos pos = m_xml_fstream.tellp();
|
||||||
|
// Close the XML file (temporarily) so that the XML file is always correct
|
||||||
|
m_xml_fstream << "</" << m_list_name << ">" << std::endl;
|
||||||
|
// Restore the pointer position so that the next "add_element" will overwrite
|
||||||
|
// the end of the file
|
||||||
|
m_xml_fstream.seekp(pos);
|
||||||
|
|
||||||
|
m_xml_fstream.flush();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: element.size() == m_subelement_names.size()" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_element(Element_with_map &element)
|
||||||
|
{
|
||||||
|
Element elt;
|
||||||
|
|
||||||
|
std::vector<std::string>::const_iterator
|
||||||
|
it_subelement_name = m_subelement_names.begin();
|
||||||
|
std::vector<std::string>::const_iterator
|
||||||
|
it_subelement_name_end = m_subelement_names.end();
|
||||||
|
for ( ; it_subelement_name != it_subelement_name_end ; ++it_subelement_name)
|
||||||
|
{
|
||||||
|
elt.push_back(element[*it_subelement_name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return add_element(elt);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::ofstream m_xml_fstream;
|
||||||
|
std::string m_list_name;
|
||||||
|
std::string m_element_name;
|
||||||
|
std::vector<std::string> m_subelement_names;
|
||||||
|
bool m_add_timestamp;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
#---------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
# Input PARAM1 PARAM2 PARAM3 NUM_P AMB INTR SPARSITY PERTURB ADD_HDIM COLLAPSE FIX_TIME_LIMIT NUM_ITERATIONS
|
||||||
|
#---------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#---------------------------------------------------------------- Alpha TC tests ------------------------------------------------------------------------
|
||||||
|
#generate_sphere_d 1 1 - 50 2 1 0.005 N Y N 3 1 #OK
|
||||||
|
#generate_torus_d N - - 15 2 1 0.05 N Y N 10 1
|
||||||
|
#generate_sphere_d 0.302 3 - 50 3 2 0.005 N Y N 60 1 #OK
|
||||||
|
#generate_sphere_d 0.302 2 - 300 2 1 0.005 N Y N 60 1
|
||||||
|
#generate_torus_3D 2 1 N 200 3 2 0.05 N Y N 600 1 #OK => tetraedra only
|
||||||
|
#data/fandisk.txt - - - 0 3 2 0.005 Y Y N 5 1
|
||||||
|
generate_torus_d N 1 - 50 4 2 0.05 N Y N 3 1 #NOT OK: various errors
|
||||||
|
#generate_torus_d Y 1 - 2500 4 2 0.05 N Y N 3 1 #NOT OK
|
||||||
|
#generate_torus_d N - - 30 6 3 0.05 N Y N 300 1
|
||||||
|
#generate_moment_curve 0 1 - 10 3 1 0.005 N Y N 60 1
|
||||||
|
#generate_two_spheres_d 3 4 - 500 3 2 0.05 N Y N 10 1 #OK
|
||||||
|
#generate_klein_bottle_4D 40 15 - 500 4 2 0.2 N Y N 60 1
|
||||||
|
|
||||||
|
#---------------------------------------------------------------- Fixed-alpha TC tests ------------------------------------------------------------------------
|
||||||
|
#generate_sphere_d 0.302 - - 70 2 1 0.005 N N N 60 1
|
||||||
|
#generate_sphere_d 0.304 0 - 100 3 2 0.05 N N N 60 1
|
||||||
|
#generate_sphere_d 3 0 - 100 4 3 0.05 N N N 60 1
|
||||||
|
#generate_sphere_d 3 0 - 1000 5 4 0.05 N N N 60 1
|
||||||
|
#generate_two_spheres_d 3 4 - 1000 3 2 0.05 N N N 10 1
|
||||||
|
#generate_two_spheres_d 3 10 - 1000 4 3 0.05 N N N 10 1
|
||||||
|
#generate_two_spheres_d 3 10 - 2000 5 4 0.05 N N N 10 1
|
||||||
|
#generate_3sphere_and_circle_d 3 - - 100000 5 3 0.05 N N N 7000 1
|
||||||
|
#generate_plane - - - 100 4 3 0.005 N N N 3000 1
|
||||||
|
#generate_plane - - - 10 5 4 0.005 N N N 3000 1
|
||||||
|
#generate_klein_bottle_4D 40 15 - 500 4 2 0.2 N N N 60 1
|
||||||
|
#generate_klein_bottle_4D 40 15 - 2000 4 2 0.2 N N N 60 1
|
||||||
|
#generate_klein_bottle_4D 8 5 - 5000 4 2 0.2 N N N 60 1 #Takes forever
|
||||||
|
#generate_torus_3D 2 1 Y 150 3 2 0.05 N N N 600 1
|
||||||
|
#generate_torus_3D 2 1 N 100000 3 2 0.55 N N N 600 1
|
||||||
|
#generate_torus_d N - - 18 2 1 0.01 N N N 30 1
|
||||||
|
#generate_torus_d N - - 50000 2 1 0.7 N N N 30 1
|
||||||
|
#generate_torus_d Y - - 2 2 1 0 N N N 30 1
|
||||||
|
#generate_torus_d Y - - 15 4 2 0.05 N N N 30 1
|
||||||
|
#generate_torus_d N 0 - 150 4 2 0.05 N N N 10 1
|
||||||
|
#generate_torus_d N - - 20000 4 2 1.0 N N N 30 1
|
||||||
|
#generate_torus_d Y 0 - 5000 6 3 0.05 N N N 300 1
|
||||||
|
#generate_torus_d N - - 20000 6 3 0.05 N N N 60 1
|
||||||
|
#generate_torus_d N - - 100000 6 3 0.05 N N N 3000 1
|
||||||
|
#generate_torus_d N - - 1000000 6 3 0.3 N N N 3000 1
|
||||||
|
#generate_torus_d Y - - 1000 8 4 0.05 N N N 60 1
|
||||||
|
#data/SO3_10000.txt - - - 0 9 3 0.1 N N N 60 1
|
||||||
|
|
||||||
|
#---------------------------------------------------------- Spatial search benchmarking --------------------------------------------------------------
|
||||||
|
#generate_torus_3D 2 1 Y 10000 3 2 0 Y N N 600 1
|
||||||
|
#data/buddha_100kv.txt - - - 0 3 2 0 N Y N 120 1
|
||||||
|
#generate_torus_d N - - 10000 30 15 0 Y N N 3600 1
|
||||||
|
#generate_torus_d N - - 100000 12 6 0 Y N N 3600 1
|
||||||
|
#data/SO3_50000.txt - - - 0 9 3 0 Y N N 60 1
|
||||||
|
#data/Cy8.txt - - - 0 24 2 0 N Y N 60 1
|
||||||
|
#generate_sphere_d 0.5 - - 10000 2 1 0 N N Y 60 1
|
||||||
|
#generate_sphere_d 0.5 - - 10000 3 2 0 N N Y 60 1
|
||||||
|
#generate_sphere_d 0.5 - - 10000 4 3 0 N N Y 60 1
|
||||||
|
#generate_sphere_d 0.5 - - 10000 5 4 0 N N Y 60 1
|
||||||
|
#generate_sphere_d 0.5 - - 10000 6 5 0 N N Y 60 1
|
||||||
|
#generate_sphere_d 0.5 - - 10000 7 6 0 N N Y 60 1
|
||||||
|
|
||||||
|
#---------------------------------------------------------- Very small cases for Debug mode --------------------------------------------------------------
|
||||||
|
#generate_sphere_d 4 - - 20 3 2 0.05 N Y N 60 1
|
||||||
|
#generate_sphere_d 3 - - 70 3 2 0.05 N Y N 60 1
|
||||||
|
#generate_sphere_d 3 - - 1000 3 2 0.05 N Y N 60 1
|
||||||
|
#generate_sphere_d 3 - - 70 4 3 0.05 N Y N 60 1
|
||||||
|
#generate_sphere_d 3 - - 70 5 4 0.05 N Y N 60 1
|
||||||
|
#generate_klein_bottle_variant_5D 4 3 - 70 5 2 0.05 N Y N 60 1
|
||||||
|
#data/SO3_10000.txt - - - 0 9 3 0.7 N Y N 60 1
|
||||||
|
#generate_moment_curve 0 1 - 30 3 1 0.005 N Y N 60 1
|
||||||
|
|
||||||
|
#------------------------------------------------------------------ From files --------------------------------------------------------------------------
|
||||||
|
#data/SO3_50000.txt - - - 0 9 3 0.05 Y Y N 60 1
|
||||||
|
#data/SO3_10000.txt - - - 0 9 3 0.05 Y N N 60 1
|
||||||
|
#data/cube3D_eps_0.1.txt - - - 0 3 2 0.05 N Y N 3000 1
|
||||||
|
#data/cube4D_eps_0.1.txt - - - 0 4 3 0.05 N Y N 3000 1
|
||||||
|
#data/cube5D_eps_0.1.txt - - - 0 5 4 0.05 N Y N 3000 1
|
||||||
|
#data/Cy8.txt - - - 0 24 2 0.1 N Y N 60 1
|
||||||
|
#data/Kl.txt - - - 0 5 2 0.05 N Y N 60 1
|
||||||
|
#data/S3.txt - - - 0 4 3 0.05 N Y N 60 1
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------- 3D meshes -----------------------------------------------------------------------
|
||||||
|
#data/buddha_100kv.txt - - - 0 3 2 0.005 N Y N 120 1
|
||||||
|
#data/fandisk.txt - - - 0 3 2 0.01 N Y N 60 1
|
||||||
|
#data/fertility.txt - - - 0 3 2 0.4 N Y N 60 1
|
||||||
|
#data/bunny.txt - - - 0 3 2 0.5 N Y N 60 1
|
||||||
|
#data/blob.txt - - - 0 3 2 0.01 N Y N 60 1
|
||||||
|
#data/3holes.txt - - - 0 3 2 0.01 N Y N 60 1
|
||||||
|
#data/785_hand_2500v.txt - - - 0 3 2 0.01 N Y N 60 1
|
||||||
|
#data/785_hand_50kv.txt - - - 0 3 2 0.01 N Y N 60 1
|
||||||
|
#data/bumpy_sphere.txt - - - 0 3 2 0.01 N Y N 60 1
|
||||||
|
|
||||||
|
#----------------------------------------------------------- Generated point sets -----------------------------------------------------------------------
|
||||||
|
#generate_sphere_d 3 - - 4 3 2 0.05 N Y N 3000 1
|
||||||
|
#generate_sphere_d 3 - - 30000 2 1 0.005 N Y N 3000 1
|
||||||
|
#generate_sphere_d 3 - - 30000 3 2 0.005 N Y N 3000 1
|
||||||
|
#generate_sphere_d 3 - - 30000 4 3 0.05 N Y N 3000 1
|
||||||
|
#generate_sphere_d 3 0 - 3000 3 2 0.005 N Y N 60 1
|
||||||
|
#generate_sphere_d 3 4 - 3000 3 2 0.005 N Y N 60 1
|
||||||
|
#generate_sphere_d 3 7 - 3000 3 2 0.005 N Y N 60 1
|
||||||
|
#generate_plane - - - 30000 3 2 0.005 N Y N 3000 1
|
||||||
|
#generate_moment_curve 0 1 - 30000 6 1 0.005 N Y N 60 1
|
||||||
|
#generate_klein_bottle_4D 4 3 - 1000 4 2 0.1 N Y N 60 1
|
||||||
|
#generate_klein_bottle_variant_5D 4 3 - 30000 5 2 0.05 N Y N 60 1
|
||||||
|
#generate_klein_bottle_4D 8 5 - 5000 4 2 0.2 N Y N 60 1 #Takes forever
|
||||||
|
|
||||||
|
#----------------------------------------------------------- Performance testing ------------------------------------------------------------------------
|
||||||
|
# TC: 5.55 / 1st fix step : 0.2
|
||||||
|
#data/fertility.txt - - - 0 3 2 0.1 N Y N 100 1
|
||||||
|
|
@ -0,0 +1,781 @@
|
||||||
|
//#undef CGAL_LINKED_WITH_TBB // CJTODO TEMP
|
||||||
|
|
||||||
|
// Without TBB_USE_THREADING_TOOL Intel Inspector XE will report false positives in Intel TBB
|
||||||
|
// (http://software.intel.com/en-us/articles/compiler-settings-for-threading-error-analysis-in-intel-inspector-xe/)
|
||||||
|
#ifdef _DEBUG
|
||||||
|
# define TBB_USE_THREADING_TOOL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <CGAL/assertions_behaviour.h>
|
||||||
|
#include <CGAL/Epick_d.h>
|
||||||
|
#include <CGAL/Tangential_complex.h>
|
||||||
|
#include <CGAL/Random.h>
|
||||||
|
#include <CGAL/Mesh_3/Profiling_tools.h>
|
||||||
|
|
||||||
|
#include "../../test/Tangential_complex/testing_utilities.h"
|
||||||
|
|
||||||
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
#include <boost/algorithm/string/trim_all.hpp>
|
||||||
|
#include <boost/range/adaptor/strided.hpp>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
#include <fstream>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
# include <tbb/task_scheduler_init.h>
|
||||||
|
#endif
|
||||||
|
#include "XML_exporter.h"
|
||||||
|
#define CGAL_TC_EXPORT_PERFORMANCE_DATA
|
||||||
|
#define CGAL_TC_SET_PERFORMANCE_DATA(value_name, value) \
|
||||||
|
XML_perf_data::set(value_name, value);
|
||||||
|
|
||||||
|
const char * const BENCHMARK_SCRIPT_FILENAME = "benchmark_script.txt";
|
||||||
|
|
||||||
|
typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> Kernel;
|
||||||
|
typedef Kernel::FT FT;
|
||||||
|
typedef Kernel::Point_d Point;
|
||||||
|
typedef CGAL::Tangential_complex<
|
||||||
|
Kernel, CGAL::Dynamic_dimension_tag,
|
||||||
|
CGAL::Parallel_tag> TC;
|
||||||
|
|
||||||
|
//#define JUST_BENCHMARK_SPATIAL_SEARCH // CJTODO: test
|
||||||
|
//#define CHECK_IF_ALL_SIMPLICES_ARE_IN_THE_AMBIENT_DELAUNAY
|
||||||
|
#define TC_INPUT_STRIDES 3 // only take one point every TC_INPUT_STRIDES points
|
||||||
|
#define TC_NO_EXPORT
|
||||||
|
|
||||||
|
#ifdef JUST_BENCHMARK_SPATIAL_SEARCH
|
||||||
|
std::ofstream spatial_search_csv_file("benchmark_spatial_search.csv");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class XML_perf_data
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Streaming_XML_exporter<std::string> XML_exporter;
|
||||||
|
|
||||||
|
XML_perf_data(const std::string &filename)
|
||||||
|
: m_xml(filename, "ContainerPerformance", "Perf",
|
||||||
|
construct_subelements_names())
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~XML_perf_data()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static XML_perf_data &get()
|
||||||
|
{
|
||||||
|
static XML_perf_data singleton(build_filename());
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Value_type>
|
||||||
|
static void set(const std::string &name, Value_type value)
|
||||||
|
{
|
||||||
|
get().set_data(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void commit()
|
||||||
|
{
|
||||||
|
get().commit_current_element();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static std::string build_filename()
|
||||||
|
{
|
||||||
|
std::stringstream sstr;
|
||||||
|
sstr << "perf_logs/Performance_log_" << time(0) << ".xml";
|
||||||
|
return sstr.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> construct_subelements_names()
|
||||||
|
{
|
||||||
|
std::vector<std::string> subelements;
|
||||||
|
subelements.push_back("Input");
|
||||||
|
subelements.push_back("Intrinsic_dim");
|
||||||
|
subelements.push_back("Ambient_dim");
|
||||||
|
subelements.push_back("Sparsity");
|
||||||
|
subelements.push_back("Num_points_in_input");
|
||||||
|
subelements.push_back("Num_points");
|
||||||
|
subelements.push_back("Initial_num_inconsistent_local_tr");
|
||||||
|
subelements.push_back("Best_num_inconsistent_local_tr");
|
||||||
|
subelements.push_back("Final_num_inconsistent_local_tr");
|
||||||
|
subelements.push_back("Init_time");
|
||||||
|
subelements.push_back("Comput_time");
|
||||||
|
subelements.push_back("Perturb_successful");
|
||||||
|
subelements.push_back("Perturb_time");
|
||||||
|
subelements.push_back("Perturb_steps");
|
||||||
|
subelements.push_back("Add_higher_dim_simpl_time");
|
||||||
|
subelements.push_back("Result_pure_pseudomanifold");
|
||||||
|
subelements.push_back("Result_num_wrong_dim_simplices");
|
||||||
|
subelements.push_back("Result_num_wrong_number_of_cofaces");
|
||||||
|
subelements.push_back("Result_num_unconnected_stars");
|
||||||
|
subelements.push_back("Info");
|
||||||
|
|
||||||
|
return subelements;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_data(const std::string &name, const std::string &value)
|
||||||
|
{
|
||||||
|
m_current_element[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Value_type>
|
||||||
|
void set_data(const std::string &name, Value_type value)
|
||||||
|
{
|
||||||
|
std::stringstream sstr;
|
||||||
|
sstr << value;
|
||||||
|
set_data(name, sstr.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void commit_current_element()
|
||||||
|
{
|
||||||
|
m_xml.add_element(m_current_element);
|
||||||
|
m_current_element.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
XML_exporter m_xml;
|
||||||
|
XML_exporter::Element_with_map m_current_element;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Test_dim
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Test_dim(
|
||||||
|
int min_allowed_dim = 0,
|
||||||
|
int max_allowed_dim = std::numeric_limits<int>::max())
|
||||||
|
: m_min_allowed_dim(min_allowed_dim), m_max_allowed_dim(max_allowed_dim)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename Simplex>
|
||||||
|
bool operator()(Simplex const& s)
|
||||||
|
{
|
||||||
|
return s.size() - 1 >= m_min_allowed_dim
|
||||||
|
&& s.size() - 1 <= m_max_allowed_dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_min_allowed_dim;
|
||||||
|
int m_max_allowed_dim;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TC>
|
||||||
|
bool export_to_off(
|
||||||
|
TC const& tc,
|
||||||
|
std::string const& input_name_stripped,
|
||||||
|
std::string const& suffix,
|
||||||
|
bool color_inconsistencies = false,
|
||||||
|
typename TC::Simplicial_complex const* p_complex = NULL,
|
||||||
|
std::set<std::set<std::size_t> > const *p_simpl_to_color_in_red = NULL,
|
||||||
|
std::set<std::set<std::size_t> > const *p_simpl_to_color_in_green = NULL,
|
||||||
|
std::set<std::set<std::size_t> > const *p_simpl_to_color_in_blue = NULL)
|
||||||
|
{
|
||||||
|
#ifdef TC_NO_EXPORT
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
if (tc.intrinsic_dimension() <= 3)
|
||||||
|
{
|
||||||
|
std::stringstream output_filename;
|
||||||
|
output_filename << "output/" << input_name_stripped << "_"
|
||||||
|
<< tc.intrinsic_dimension() << "_in_R"
|
||||||
|
<< tc.ambient_dimension() << "_"
|
||||||
|
<< tc.number_of_vertices() << "v"
|
||||||
|
<< suffix << ".off";
|
||||||
|
std::ofstream off_stream(output_filename.str().c_str());
|
||||||
|
|
||||||
|
if (p_complex)
|
||||||
|
{
|
||||||
|
#ifndef TC_NO_EXPORT
|
||||||
|
tc.export_to_off(
|
||||||
|
*p_complex, off_stream,
|
||||||
|
p_simpl_to_color_in_red,
|
||||||
|
p_simpl_to_color_in_green,
|
||||||
|
p_simpl_to_color_in_blue);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*#ifdef CGAL_ALPHA_TC
|
||||||
|
TC::Simplicial_complex complex;
|
||||||
|
tc.export_TC(complex, false);
|
||||||
|
tc.export_to_off(
|
||||||
|
complex, off_stream,
|
||||||
|
p_simpl_to_color_in_red,
|
||||||
|
p_simpl_to_color_in_green,
|
||||||
|
p_simpl_to_color_in_blue);
|
||||||
|
#else*/
|
||||||
|
tc.export_to_off(
|
||||||
|
off_stream, color_inconsistencies,
|
||||||
|
p_simpl_to_color_in_red,
|
||||||
|
p_simpl_to_color_in_green,
|
||||||
|
p_simpl_to_color_in_blue);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void make_tc(std::vector<Point> &points,
|
||||||
|
int intrinsic_dim,
|
||||||
|
double sparsity = 0.,
|
||||||
|
bool perturb = true,
|
||||||
|
bool add_high_dim_simpl = false,
|
||||||
|
bool collapse = false,
|
||||||
|
double time_limit_for_perturb = 0.,
|
||||||
|
const char *input_name = "tc")
|
||||||
|
{
|
||||||
|
Kernel k;
|
||||||
|
|
||||||
|
// CJTODO TEMP TEST
|
||||||
|
//TC::Simplicial_complex compl;
|
||||||
|
//{std::size_t ss[] = {0, 1, 2}; compl.add_simplex(std::set<std::size_t>(ss, ss + 3)); }
|
||||||
|
//{std::size_t ss[] = {0, 2, 3}; compl.add_simplex(std::set<std::size_t>(ss, ss + 3)); }
|
||||||
|
//{std::size_t ss[] = {0, 3, 4}; compl.add_simplex(std::set<std::size_t>(ss, ss + 3)); }
|
||||||
|
//{std::size_t ss[] = {0, 4, 1}; compl.add_simplex(std::set<std::size_t>(ss, ss + 3)); }
|
||||||
|
//{std::size_t ss[] = {0, 5, 6}; compl.add_simplex(std::set<std::size_t>(ss, ss + 3)); }
|
||||||
|
//compl.is_pure_pseudomanifold(2, 7, false, 10);
|
||||||
|
|
||||||
|
//TC::Simplicial_complex compl;
|
||||||
|
//{std::size_t ss[] = {0, 1, 2, 5}; compl.add_simplex(std::set<std::size_t>(ss, ss + 4)); }
|
||||||
|
//{std::size_t ss[] = {0, 2, 3, 5}; compl.add_simplex(std::set<std::size_t>(ss, ss + 4)); }
|
||||||
|
//{std::size_t ss[] = {0, 3, 4, 5}; compl.add_simplex(std::set<std::size_t>(ss, ss + 4)); }
|
||||||
|
//{std::size_t ss[] = {0, 4, 1, 5}; compl.add_simplex(std::set<std::size_t>(ss, ss + 4)); }
|
||||||
|
//{std::size_t ss[] = {0, 1, 2, 6}; compl.add_simplex(std::set<std::size_t>(ss, ss + 4)); }
|
||||||
|
//{std::size_t ss[] = {0, 2, 3, 6}; compl.add_simplex(std::set<std::size_t>(ss, ss + 4)); }
|
||||||
|
//{std::size_t ss[] = {0, 3, 4, 6}; compl.add_simplex(std::set<std::size_t>(ss, ss + 4)); }
|
||||||
|
//{std::size_t ss[] = {0, 4, 1, 6}; compl.add_simplex(std::set<std::size_t>(ss, ss + 4)); }
|
||||||
|
//{std::size_t ss[] = {0, 4, 7, 8}; compl.add_simplex(std::set<std::size_t>(ss, ss + 4)); }
|
||||||
|
//compl.is_pure_pseudomanifold(3, 9, false, 10);
|
||||||
|
// /CJTODO TEMP TEST
|
||||||
|
|
||||||
|
#ifdef JUST_BENCHMARK_SPATIAL_SEARCH
|
||||||
|
benchmark_spatial_search(points, k, spatial_search_csv_file);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Init
|
||||||
|
//===========================================================================
|
||||||
|
Wall_clock_timer t;
|
||||||
|
|
||||||
|
// Get input_name_stripped
|
||||||
|
std::string input_name_stripped(input_name);
|
||||||
|
size_t slash_index = input_name_stripped.find_last_of('/');
|
||||||
|
if (slash_index == std::string::npos)
|
||||||
|
slash_index = input_name_stripped.find_last_of('\\');
|
||||||
|
if (slash_index == std::string::npos)
|
||||||
|
slash_index = 0;
|
||||||
|
else
|
||||||
|
++slash_index;
|
||||||
|
input_name_stripped = input_name_stripped.substr(
|
||||||
|
slash_index, input_name_stripped.find_last_of('.') - slash_index);
|
||||||
|
|
||||||
|
int ambient_dim = k.point_dimension_d_object()(*points.begin());
|
||||||
|
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Num_points_in_input", points.size());
|
||||||
|
|
||||||
|
#ifdef USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||||
|
std::vector<Point> points_not_sparse = points;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Sparsify point set if requested
|
||||||
|
//===========================================================================
|
||||||
|
if (sparsity != 0.)
|
||||||
|
{
|
||||||
|
std::size_t num_points_before = points.size();
|
||||||
|
points = sparsify_point_set(k, points, sparsity*sparsity);
|
||||||
|
std::cerr << "Number of points before/after sparsification: "
|
||||||
|
<< num_points_before << " / " << points.size() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Sparsity", sparsity);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Num_points", points.size());
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Compute Tangential Complex
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
#ifdef USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||||
|
TC tc(points.begin(), points.end(), sparsity, intrinsic_dim,
|
||||||
|
points_not_sparse.begin(), points_not_sparse.end(), k);
|
||||||
|
#else
|
||||||
|
TC tc(points.begin(), points.end(), sparsity, intrinsic_dim, k);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
double init_time = t.elapsed(); t.reset();
|
||||||
|
|
||||||
|
tc.compute_tangential_complex();
|
||||||
|
double computation_time = t.elapsed(); t.reset();
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// CJTODO TEMP
|
||||||
|
//===========================================================================
|
||||||
|
/*{
|
||||||
|
TC::Simplicial_complex complex;
|
||||||
|
int max_dim = tc.export_TC(complex, false);
|
||||||
|
complex.display_stats();
|
||||||
|
|
||||||
|
std::stringstream output_filename;
|
||||||
|
output_filename << "output/" << input_name_stripped << "_" << intrinsic_dim
|
||||||
|
<< "_in_R" << ambient_dim << "_ALPHA_COMPLEX.off";
|
||||||
|
std::ofstream off_stream(output_filename.str().c_str());
|
||||||
|
tc.export_to_off(complex, off_stream);
|
||||||
|
|
||||||
|
// Collapse
|
||||||
|
complex.collapse(max_dim);
|
||||||
|
{
|
||||||
|
std::stringstream output_filename;
|
||||||
|
output_filename << "output/" << input_name_stripped << "_" << intrinsic_dim
|
||||||
|
<< "_in_R" << ambient_dim << "_AFTER_COLLAPSE.off";
|
||||||
|
std::ofstream off_stream(output_filename.str().c_str());
|
||||||
|
tc.export_to_off(complex, off_stream);
|
||||||
|
}
|
||||||
|
std::size_t num_wrong_dim_simplices,
|
||||||
|
num_wrong_number_of_cofaces,
|
||||||
|
num_unconnected_stars;
|
||||||
|
bool pure_manifold = complex.is_pure_pseudomanifold(
|
||||||
|
intrinsic_dim, tc.number_of_vertices(), false, 1,
|
||||||
|
&num_wrong_dim_simplices, &num_wrong_number_of_cofaces,
|
||||||
|
&num_unconnected_stars);
|
||||||
|
complex.display_stats();
|
||||||
|
}
|
||||||
|
return;*/
|
||||||
|
// CJTODO TEMP ===========================
|
||||||
|
|
||||||
|
#ifdef CHECK_IF_ALL_SIMPLICES_ARE_IN_THE_AMBIENT_DELAUNAY
|
||||||
|
if (ambient_dim <= 4)
|
||||||
|
tc.check_if_all_simplices_are_in_the_ambient_delaunay();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//tc.check_correlation_between_inconsistencies_and_fatness();
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Export to OFF
|
||||||
|
//===========================================================================
|
||||||
|
t.reset();
|
||||||
|
double export_before_time =
|
||||||
|
(export_to_off(tc, input_name_stripped, "_BEFORE_FIX") ? t.elapsed() : -1);
|
||||||
|
t.reset();
|
||||||
|
|
||||||
|
unsigned int num_perturb_steps = 0;
|
||||||
|
double perturb_time = -1;
|
||||||
|
double export_after_perturb_time = -1.;
|
||||||
|
CGAL::Fix_inconsistencies_status perturb_ret = CGAL::FIX_NOT_PERFORMED;
|
||||||
|
if (perturb)
|
||||||
|
{
|
||||||
|
//=========================================================================
|
||||||
|
// Try to fix inconsistencies by perturbing points
|
||||||
|
//=========================================================================
|
||||||
|
t.reset();
|
||||||
|
std::size_t initial_num_inconsistent_local_tr;
|
||||||
|
std::size_t best_num_inconsistent_local_tr;
|
||||||
|
std::size_t final_num_inconsistent_local_tr;
|
||||||
|
perturb_ret = tc.fix_inconsistencies_using_perturbation(
|
||||||
|
num_perturb_steps, initial_num_inconsistent_local_tr,
|
||||||
|
best_num_inconsistent_local_tr, final_num_inconsistent_local_tr,
|
||||||
|
time_limit_for_perturb);
|
||||||
|
perturb_time = t.elapsed(); t.reset();
|
||||||
|
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Initial_num_inconsistent_local_tr",
|
||||||
|
initial_num_inconsistent_local_tr);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Best_num_inconsistent_local_tr",
|
||||||
|
best_num_inconsistent_local_tr);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Final_num_inconsistent_local_tr",
|
||||||
|
final_num_inconsistent_local_tr);
|
||||||
|
|
||||||
|
//tc.check_correlation_between_inconsistencies_and_fatness();
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
// Export to OFF
|
||||||
|
//=========================================================================
|
||||||
|
t.reset();
|
||||||
|
bool exported = export_to_off(tc, input_name_stripped, "_AFTER_FIX", true);
|
||||||
|
double export_after_perturb_time = (exported ? t.elapsed() : -1);
|
||||||
|
t.reset();
|
||||||
|
|
||||||
|
//std::string fn = "output/inc_stars/";
|
||||||
|
//fn += input_name_stripped;
|
||||||
|
//tc.export_inconsistent_stars_to_OFF_files(fn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Initial_num_inconsistent_local_tr", "N/A");
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Best_num_inconsistent_local_tr", "N/A");
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Final_num_inconsistent_local_tr", "N/A");
|
||||||
|
}
|
||||||
|
|
||||||
|
int max_dim = -1;
|
||||||
|
double fix2_time = -1;
|
||||||
|
double export_after_fix2_time = -1.;
|
||||||
|
TC::Simplicial_complex complex;
|
||||||
|
if (add_high_dim_simpl)
|
||||||
|
{
|
||||||
|
//=========================================================================
|
||||||
|
// Try to fix inconsistencies by adding higher-dimension simplices
|
||||||
|
//=========================================================================
|
||||||
|
t.reset();
|
||||||
|
// Try to solve the remaining inconstencies
|
||||||
|
#ifdef CGAL_ALPHA_TC
|
||||||
|
tc.solve_inconsistencies_using_alpha_TC();
|
||||||
|
#else
|
||||||
|
tc.check_and_solve_inconsistencies_by_adding_higher_dim_simplices();
|
||||||
|
#endif
|
||||||
|
fix2_time = t.elapsed(); t.reset();
|
||||||
|
max_dim = tc.export_TC(complex, false);
|
||||||
|
/*std::set<std::set<std::size_t> > not_delaunay_simplices;
|
||||||
|
if (ambient_dim <= 4)
|
||||||
|
{
|
||||||
|
tc.check_if_all_simplices_are_in_the_ambient_delaunay(
|
||||||
|
&complex, true, ¬_delaunay_simplices);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
// Export to OFF
|
||||||
|
//=========================================================================
|
||||||
|
t.reset();
|
||||||
|
bool exported = export_to_off(
|
||||||
|
tc, input_name_stripped, "_AFTER_FIX2", false, &complex);
|
||||||
|
double export_after_fix2_time = (exported ? t.elapsed() : -1);
|
||||||
|
t.reset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
max_dim = tc.export_TC(complex, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
complex.display_stats();
|
||||||
|
|
||||||
|
// Export to OFF with higher-dim simplices colored
|
||||||
|
std::set<std::set<std::size_t> > higher_dim_simplices;
|
||||||
|
complex.get_simplices_matching_test(
|
||||||
|
Test_dim(intrinsic_dim + 1),
|
||||||
|
std::inserter(higher_dim_simplices, higher_dim_simplices.begin()));
|
||||||
|
export_to_off(
|
||||||
|
tc, input_name_stripped, "_BEFORE_COLLAPSE", false, &complex,
|
||||||
|
&higher_dim_simplices);
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Collapse
|
||||||
|
//===========================================================================
|
||||||
|
if (collapse)
|
||||||
|
complex.collapse(max_dim);
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Is the result a pure pseudomanifold?
|
||||||
|
//===========================================================================
|
||||||
|
std::size_t num_wrong_dim_simplices,
|
||||||
|
num_wrong_number_of_cofaces,
|
||||||
|
num_unconnected_stars;
|
||||||
|
std::set<std::set<std::size_t> > wrong_dim_simplices;
|
||||||
|
std::set<std::set<std::size_t> > wrong_number_of_cofaces_simplices;
|
||||||
|
std::set<std::set<std::size_t> > unconnected_stars_simplices;
|
||||||
|
bool is_pure_pseudomanifold = complex.is_pure_pseudomanifold(
|
||||||
|
intrinsic_dim, tc.number_of_vertices(), false, 1,
|
||||||
|
&num_wrong_dim_simplices, &num_wrong_number_of_cofaces,
|
||||||
|
&num_unconnected_stars,
|
||||||
|
&wrong_dim_simplices, &wrong_number_of_cofaces_simplices,
|
||||||
|
&unconnected_stars_simplices);
|
||||||
|
|
||||||
|
// Stats about the simplices
|
||||||
|
complex.display_stats();
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Export to OFF
|
||||||
|
//===========================================================================
|
||||||
|
t.reset();
|
||||||
|
bool exported = export_to_off(
|
||||||
|
tc, input_name_stripped, "_AFTER_COLLAPSE", false, &complex,
|
||||||
|
&wrong_dim_simplices, &wrong_number_of_cofaces_simplices,
|
||||||
|
&unconnected_stars_simplices);
|
||||||
|
std::cerr
|
||||||
|
<< " OFF colors:" << std::endl
|
||||||
|
<< " * Red: wrong dim simplices" << std::endl
|
||||||
|
<< " * Green: wrong number of cofaces simplices" << std::endl
|
||||||
|
<< " * Blue: not-connected stars" << std::endl;
|
||||||
|
double export_after_collapse_time = (exported ? t.elapsed() : -1);
|
||||||
|
t.reset();
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Display info
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
std::cerr << std::endl
|
||||||
|
<< "================================================" << std::endl
|
||||||
|
<< "Number of vertices: " << tc.number_of_vertices() << std::endl
|
||||||
|
<< "Pure pseudomanifold: " << (is_pure_pseudomanifold ? "YES" : "NO") << std::endl
|
||||||
|
<< "Computation times (seconds): " << std::endl
|
||||||
|
<< " * Tangential complex: " << init_time + computation_time << std::endl
|
||||||
|
<< " - Init + kd-tree = " << init_time << std::endl
|
||||||
|
<< " - TC computation = " << computation_time << std::endl
|
||||||
|
<< " * Export to OFF (before perturb): " << export_before_time << std::endl
|
||||||
|
<< " * Fix inconsistencies 1: " << perturb_time
|
||||||
|
<< " (" << num_perturb_steps << " steps) ==> "
|
||||||
|
<< (perturb_ret == CGAL::TC_FIXED ? "FIXED" : "NOT fixed") << std::endl
|
||||||
|
<< " * Fix inconsistencies 2: " << fix2_time << std::endl
|
||||||
|
<< " * Export to OFF (after perturb): " << export_after_perturb_time << std::endl
|
||||||
|
<< " * Export to OFF (after fix2): "<< export_after_fix2_time << std::endl
|
||||||
|
<< " * Export to OFF (after collapse): "
|
||||||
|
<< export_after_collapse_time << std::endl
|
||||||
|
<< "================================================" << std::endl
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Export info
|
||||||
|
//===========================================================================
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Init_time", init_time);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Comput_time", computation_time);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Perturb_successful",
|
||||||
|
(perturb_ret == CGAL::TC_FIXED ? "Y" : "N"));
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Perturb_time", perturb_time);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Perturb_steps", num_perturb_steps);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Add_higher_dim_simpl_time", fix2_time);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Result_pure_pseudomanifold",
|
||||||
|
(is_pure_pseudomanifold ? "Y" : "N"));
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Result_num_wrong_dim_simplices",
|
||||||
|
num_wrong_dim_simplices);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Result_num_wrong_number_of_cofaces",
|
||||||
|
num_wrong_number_of_cofaces);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Result_num_unconnected_stars",
|
||||||
|
num_unconnected_stars);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Info", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
CGAL::set_error_behaviour(CGAL::ABORT);
|
||||||
|
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
# ifdef _DEBUG
|
||||||
|
int num_threads = 1;
|
||||||
|
# else
|
||||||
|
int num_threads = 10;
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned int seed = static_cast<unsigned int>(time(NULL));
|
||||||
|
CGAL::default_random = CGAL::Random(seed);
|
||||||
|
std::cerr << "Random seed = " << seed << std::endl;
|
||||||
|
|
||||||
|
std::ifstream script_file;
|
||||||
|
script_file.open(BENCHMARK_SCRIPT_FILENAME);
|
||||||
|
// Script?
|
||||||
|
// Script file format: each line gives
|
||||||
|
// - Filename (point set) or "generate_XXX" (point set generation)
|
||||||
|
// - Ambient dim
|
||||||
|
// - Intrinsic dim
|
||||||
|
// - Number of iterations with these parameters
|
||||||
|
if (script_file.is_open())
|
||||||
|
{
|
||||||
|
int i = 1;
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
# ifdef BENCHMARK_WITH_1_TO_MAX_THREADS
|
||||||
|
for(num_threads = 1 ;
|
||||||
|
num_threads <= tbb::task_scheduler_init::default_num_threads() ;
|
||||||
|
++num_threads)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
/*for (Concurrent_mesher_config::get().num_work_items_per_batch = 5 ;
|
||||||
|
Concurrent_mesher_config::get().num_work_items_per_batch < 100 ;
|
||||||
|
Concurrent_mesher_config::get().num_work_items_per_batch += 5)*/
|
||||||
|
{
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
tbb::task_scheduler_init init(
|
||||||
|
num_threads > 0 ? num_threads : tbb::task_scheduler_init::automatic);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::cerr << "Script file '" << BENCHMARK_SCRIPT_FILENAME << "' found." << std::endl;
|
||||||
|
script_file.seekg(0);
|
||||||
|
while (script_file.good())
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::getline(script_file, line);
|
||||||
|
if (line.size() > 1 && line[0] != '#')
|
||||||
|
{
|
||||||
|
boost::replace_all(line, "\t", " ");
|
||||||
|
boost::trim_all(line);
|
||||||
|
std::cerr << std::endl << std::endl;
|
||||||
|
std::cerr << "*****************************************" << std::endl;
|
||||||
|
std::cerr << "******* " << line << std::endl;
|
||||||
|
std::cerr << "*****************************************" << std::endl;
|
||||||
|
std::stringstream sstr(line);
|
||||||
|
|
||||||
|
std::string input;
|
||||||
|
std::string param1;
|
||||||
|
std::string param2;
|
||||||
|
std::string param3;
|
||||||
|
std::size_t num_points;
|
||||||
|
int ambient_dim;
|
||||||
|
int intrinsic_dim;
|
||||||
|
double sparsity;
|
||||||
|
char perturb, add_high_dim_simpl, collapse;
|
||||||
|
double time_limit_for_perturb;
|
||||||
|
int num_iteration;
|
||||||
|
sstr >> input;
|
||||||
|
sstr >> param1;
|
||||||
|
sstr >> param2;
|
||||||
|
sstr >> param3;
|
||||||
|
sstr >> num_points;
|
||||||
|
sstr >> ambient_dim;
|
||||||
|
sstr >> intrinsic_dim;
|
||||||
|
sstr >> sparsity;
|
||||||
|
sstr >> perturb;
|
||||||
|
sstr >> add_high_dim_simpl;
|
||||||
|
sstr >> collapse;
|
||||||
|
sstr >> time_limit_for_perturb;
|
||||||
|
sstr >> num_iteration;
|
||||||
|
|
||||||
|
for (int j = 0 ; j < num_iteration ; ++j)
|
||||||
|
{
|
||||||
|
std::string input_stripped = input;
|
||||||
|
size_t slash_index = input_stripped.find_last_of('/');
|
||||||
|
if (slash_index == std::string::npos)
|
||||||
|
slash_index = input_stripped.find_last_of('\\');
|
||||||
|
if (slash_index == std::string::npos)
|
||||||
|
slash_index = 0;
|
||||||
|
else
|
||||||
|
++slash_index;
|
||||||
|
input_stripped = input_stripped.substr(
|
||||||
|
slash_index, input_stripped.find_last_of('.') - slash_index);
|
||||||
|
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Input", input_stripped);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Ambient_dim", ambient_dim);
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Intrinsic_dim", intrinsic_dim);
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA(
|
||||||
|
"Num_threads",
|
||||||
|
(num_threads == -1 ? tbb::task_scheduler_init::default_num_threads() : num_threads));
|
||||||
|
#else
|
||||||
|
CGAL_TC_SET_PERFORMANCE_DATA("Num_threads", "N/A");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::cerr << std::endl << "TC #" << i << "..." << std::endl;
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_PROFILING
|
||||||
|
Wall_clock_timer t_gen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<Point> points;
|
||||||
|
|
||||||
|
if (input == "generate_moment_curve")
|
||||||
|
{
|
||||||
|
points = generate_points_on_moment_curve<Kernel>(
|
||||||
|
num_points, ambient_dim,
|
||||||
|
std::atof(param1.c_str()), std::atof(param2.c_str()));
|
||||||
|
}
|
||||||
|
else if (input == "generate_plane")
|
||||||
|
{
|
||||||
|
points = generate_points_on_plane<Kernel>(
|
||||||
|
num_points, intrinsic_dim, ambient_dim);
|
||||||
|
}
|
||||||
|
else if (input == "generate_sphere_d")
|
||||||
|
{
|
||||||
|
points = generate_points_on_sphere_d<Kernel>(
|
||||||
|
num_points, ambient_dim,
|
||||||
|
std::atof(param1.c_str()), // radius
|
||||||
|
std::atof(param2.c_str())); // radius_noise_percentage
|
||||||
|
}
|
||||||
|
else if (input == "generate_two_spheres_d")
|
||||||
|
{
|
||||||
|
points = generate_points_on_two_spheres_d<Kernel>(
|
||||||
|
num_points, ambient_dim,
|
||||||
|
std::atof(param1.c_str()),
|
||||||
|
std::atof(param2.c_str()),
|
||||||
|
std::atof(param3.c_str()));
|
||||||
|
}
|
||||||
|
else if (input == "generate_3sphere_and_circle_d")
|
||||||
|
{
|
||||||
|
CGAL_assertion(intrinsic_dim == 3);
|
||||||
|
CGAL_assertion(ambient_dim == 5);
|
||||||
|
points = generate_points_on_3sphere_and_circle<Kernel>(
|
||||||
|
num_points,
|
||||||
|
std::atof(param1.c_str()));
|
||||||
|
}
|
||||||
|
else if (input == "generate_torus_3D")
|
||||||
|
{
|
||||||
|
points = generate_points_on_torus_3D<Kernel>(
|
||||||
|
num_points,
|
||||||
|
std::atof(param1.c_str()),
|
||||||
|
std::atof(param2.c_str()),
|
||||||
|
param3 == "Y");
|
||||||
|
}
|
||||||
|
else if (input == "generate_torus_d")
|
||||||
|
{
|
||||||
|
points = generate_points_on_torus_d<Kernel>(
|
||||||
|
num_points,
|
||||||
|
intrinsic_dim,
|
||||||
|
param1 == "Y", // uniform
|
||||||
|
std::atof(param2.c_str())); // radius_noise_percentage
|
||||||
|
}
|
||||||
|
else if (input == "generate_klein_bottle_3D")
|
||||||
|
{
|
||||||
|
points = generate_points_on_klein_bottle_3D<Kernel>(
|
||||||
|
num_points,
|
||||||
|
std::atof(param1.c_str()), std::atof(param2.c_str()));
|
||||||
|
}
|
||||||
|
else if (input == "generate_klein_bottle_4D")
|
||||||
|
{
|
||||||
|
points = generate_points_on_klein_bottle_4D<Kernel>(
|
||||||
|
num_points,
|
||||||
|
std::atof(param1.c_str()), std::atof(param2.c_str()));
|
||||||
|
}
|
||||||
|
else if (input == "generate_klein_bottle_variant_5D")
|
||||||
|
{
|
||||||
|
points = generate_points_on_klein_bottle_variant_5D<Kernel>(
|
||||||
|
num_points,
|
||||||
|
std::atof(param1.c_str()), std::atof(param2.c_str()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
load_points_from_file<Point>(
|
||||||
|
input, std::back_inserter(points)/*, 600*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_PROFILING
|
||||||
|
std::cerr << "Point set generated/loaded in " << t_gen.elapsed()
|
||||||
|
<< " seconds." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!points.empty())
|
||||||
|
{
|
||||||
|
#if defined(TC_INPUT_STRIDES) && TC_INPUT_STRIDES > 1
|
||||||
|
auto p = points | boost::adaptors::strided(TC_INPUT_STRIDES); // CJTODO C++11 (auto)
|
||||||
|
std::vector<Point> points(p.begin(), p.end());
|
||||||
|
std::cerr << "****************************************\n"
|
||||||
|
<< "WARNING: taking 1 point every " << TC_INPUT_STRIDES
|
||||||
|
<< " points.\n"
|
||||||
|
<< "****************************************\n";
|
||||||
|
#endif
|
||||||
|
make_tc(points, intrinsic_dim, sparsity, // strided: CJTODO TEMP
|
||||||
|
perturb=='Y', add_high_dim_simpl=='Y', collapse=='Y',
|
||||||
|
time_limit_for_perturb, input.c_str());
|
||||||
|
|
||||||
|
std::cerr << "TC #" << i++ << " done." << std::endl;
|
||||||
|
std::cerr << std::endl << "---------------------------------"
|
||||||
|
<< std::endl << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "TC #" << i++ << ": no points loaded." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
XML_perf_data::commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
script_file.seekg(0);
|
||||||
|
script_file.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
script_file.close();
|
||||||
|
}
|
||||||
|
// Or not script?
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Script file '" << BENCHMARK_SCRIPT_FILENAME << "' NOT found." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
system("pause");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,391 @@
|
||||||
|
// Copyright (c) 2014 INRIA Sophia-Antipolis (France)
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL: $
|
||||||
|
// $Id: $
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Clement Jamin
|
||||||
|
|
||||||
|
#ifndef POINT_CLOUD_H
|
||||||
|
#define POINT_CLOUD_H
|
||||||
|
|
||||||
|
#include <CGAL/basic.h>
|
||||||
|
#include <CGAL/Dimension.h>
|
||||||
|
|
||||||
|
#include <CGAL/Orthogonal_k_neighbor_search.h>
|
||||||
|
#include <CGAL/Orthogonal_incremental_neighbor_search.h>
|
||||||
|
#include <CGAL/Search_traits.h>
|
||||||
|
#include <CGAL/Search_traits_adapter.h>
|
||||||
|
#include <CGAL/property_map.h>
|
||||||
|
|
||||||
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
#include <boost/iterator/zip_iterator.hpp>
|
||||||
|
#include <boost/iterator/counting_iterator.hpp>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_ANN_IS_AVAILABLE
|
||||||
|
# include <ANN/ANN.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_NANOFLANN_IS_AVAILABLE
|
||||||
|
# include "nanoflann.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace Tangential_complex_ {
|
||||||
|
|
||||||
|
template <typename K, typename Point_container_>
|
||||||
|
class Point_cloud_data_structure
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename Point_container_::value_type Point;
|
||||||
|
typedef K Kernel;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
|
||||||
|
typedef CGAL::Search_traits<
|
||||||
|
FT, Point,
|
||||||
|
typename Kernel::Cartesian_const_iterator_d,
|
||||||
|
typename Kernel::Construct_cartesian_const_iterator_d> Traits_base;
|
||||||
|
// using a pointer as a special property map type
|
||||||
|
typedef CGAL::Search_traits_adapter<
|
||||||
|
std::ptrdiff_t, Point*, Traits_base> STraits;
|
||||||
|
|
||||||
|
typedef CGAL::Orthogonal_k_neighbor_search<STraits> K_neighbor_search;
|
||||||
|
typedef typename K_neighbor_search::Tree Tree;
|
||||||
|
typedef typename K_neighbor_search::Distance Distance;
|
||||||
|
typedef typename K_neighbor_search::iterator KNS_iterator;
|
||||||
|
typedef K_neighbor_search KNS_range;
|
||||||
|
|
||||||
|
typedef CGAL::Orthogonal_incremental_neighbor_search<
|
||||||
|
STraits, Distance, CGAL::Sliding_midpoint<STraits>, Tree>
|
||||||
|
Incremental_neighbor_search;
|
||||||
|
typedef typename Incremental_neighbor_search::iterator INS_iterator;
|
||||||
|
typedef Incremental_neighbor_search INS_range;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
Point_cloud_data_structure(Point_container_ const& points)
|
||||||
|
: m_points(points),
|
||||||
|
m_tree(boost::counting_iterator<std::ptrdiff_t>(0),
|
||||||
|
boost::counting_iterator<std::ptrdiff_t>(points.size()),
|
||||||
|
typename Tree::Splitter(),
|
||||||
|
STraits((Point*)&(points[0])) )
|
||||||
|
{
|
||||||
|
// Build the tree now (we don't want to wait for the first query)
|
||||||
|
m_tree.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
Point_cloud_data_structure(
|
||||||
|
Point_container_ const& points,
|
||||||
|
std::size_t begin_idx, std::size_t past_the_end_idx)
|
||||||
|
: m_points(points),
|
||||||
|
m_tree(
|
||||||
|
boost::counting_iterator<std::ptrdiff_t>(begin_idx),
|
||||||
|
boost::counting_iterator<std::ptrdiff_t>(past_the_end_idx),
|
||||||
|
typename Tree::Splitter(),
|
||||||
|
STraits((Point*)&(points[0])) )
|
||||||
|
{
|
||||||
|
// Build the tree now (we don't want to wait for the first query)
|
||||||
|
m_tree.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Point_container_ &points()
|
||||||
|
{
|
||||||
|
return m_points;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Point_container_ &points() const
|
||||||
|
{
|
||||||
|
return m_points;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Be careful, this function invalidates the tree,
|
||||||
|
// which will be recomputed at the next query
|
||||||
|
void insert(std::ptrdiff_t point_idx)
|
||||||
|
{
|
||||||
|
m_tree.insert(point_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
KNS_range query_ANN(const
|
||||||
|
Point &sp,
|
||||||
|
unsigned int k,
|
||||||
|
bool sorted = true) const
|
||||||
|
{
|
||||||
|
// Initialize the search structure, and search all N points
|
||||||
|
// Note that we need to pass the Distance explicitly since it needs to
|
||||||
|
// know the property map
|
||||||
|
K_neighbor_search search(
|
||||||
|
m_tree,
|
||||||
|
sp,
|
||||||
|
k,
|
||||||
|
FT(0),
|
||||||
|
true,
|
||||||
|
Distance_adapter<std::ptrdiff_t,Point*,Euclidean_distance<Traits_base> >(
|
||||||
|
(Point*)&(m_points[0])),
|
||||||
|
sorted);
|
||||||
|
|
||||||
|
return search;
|
||||||
|
}
|
||||||
|
|
||||||
|
INS_range query_incremental_ANN(const Point &sp) const
|
||||||
|
{
|
||||||
|
// Initialize the search structure, and search all N points
|
||||||
|
// Note that we need to pass the Distance explicitly since it needs to
|
||||||
|
// know the property map
|
||||||
|
Incremental_neighbor_search search(
|
||||||
|
m_tree,
|
||||||
|
sp,
|
||||||
|
FT(0),
|
||||||
|
true,
|
||||||
|
Distance_adapter<std::ptrdiff_t,Point*,Euclidean_distance<Traits_base> >(
|
||||||
|
(Point*)&(m_points[0])) );
|
||||||
|
|
||||||
|
return search;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Point_container_ const& m_points;
|
||||||
|
Tree m_tree;
|
||||||
|
};
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//*****************************************************************************
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_NANOFLANN_IS_AVAILABLE
|
||||||
|
|
||||||
|
// "dataset to kd-tree" adaptor class
|
||||||
|
template <typename K, typename Point_container_>
|
||||||
|
class Point_cloud_adaptator__nanoflann
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename Point_container_::value_type Point;
|
||||||
|
typedef typename CGAL::Kernel_traits<Point>::type Kernel;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
|
||||||
|
/// The constructor that sets the data set source
|
||||||
|
Point_cloud_adaptator__nanoflann(Point_container_ const& points, Kernel const& k)
|
||||||
|
: m_points(points), m_k(k)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// CRTP helper method
|
||||||
|
inline Point_container_ const& points() const
|
||||||
|
{
|
||||||
|
return m_points;
|
||||||
|
}
|
||||||
|
inline Point_container_& points()
|
||||||
|
{
|
||||||
|
return m_points;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must return the number of data points
|
||||||
|
inline size_t kdtree_get_point_count() const
|
||||||
|
{
|
||||||
|
return m_points.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the distance between the vector "p1[0:size-1]"
|
||||||
|
// and the data point with index "idx_p2" stored in the class:
|
||||||
|
inline FT kdtree_distance(
|
||||||
|
const FT *p1, const size_t idx_p2, size_t size) const
|
||||||
|
{
|
||||||
|
Point sp(p1, p1 + size);
|
||||||
|
return m_k.squared_distance_d_object()(sp, points()[idx_p2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the dim'th component of the idx'th point in the class:
|
||||||
|
// Since this is inlined and the "dim" argument is typically an
|
||||||
|
// immediate value, the "if/else's" are actually solved at compile time.
|
||||||
|
inline FT kdtree_get_pt(const size_t idx, int dim) const
|
||||||
|
{
|
||||||
|
return m_k.compute_coordinate_d_object()(points()[idx], dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional bounding-box computation: return false to default to a standard
|
||||||
|
// bbox computation loop.
|
||||||
|
// Return true if the BBOX was already computed by the class and returned
|
||||||
|
// in "bb" so it can be avoided to redo it again.
|
||||||
|
// Look at bb.size() to find out the expected dimensionality
|
||||||
|
// (e.g. 2 or 3 for point clouds)
|
||||||
|
template <class Bbox>
|
||||||
|
bool kdtree_get_bbox(Bbox &bb) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Kernel const& kernel() const
|
||||||
|
{
|
||||||
|
return m_k;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Point_container_ const& m_points; //!< A const ref to the data set origin
|
||||||
|
Kernel const& m_k; //!< A const ref to the kernel
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename K, typename Point_container_>
|
||||||
|
class Point_cloud_data_structure__nanoflann
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename Point_container_::value_type Point;
|
||||||
|
typedef typename K Kernel;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
/// "points" must not be empty
|
||||||
|
Point_cloud_data_structure__nanoflann(
|
||||||
|
Point_container_ const& points, Kernel const& k)
|
||||||
|
: m_adaptor(points, k),
|
||||||
|
m_kd_tree(k.point_dimension_d_object()(*points.begin()),
|
||||||
|
m_adaptor,
|
||||||
|
nanoflann::KDTreeSingleIndexAdaptorParams(10 /* max leaf */) )
|
||||||
|
{
|
||||||
|
m_kd_tree.buildIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Point_container_ &points()
|
||||||
|
{
|
||||||
|
return m_adaptor.points();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Point_container_ &points() const
|
||||||
|
{
|
||||||
|
return m_adaptor.points();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void query_ANN(const Point &sp,
|
||||||
|
std::size_t k,
|
||||||
|
size_t *neighbor_indices,
|
||||||
|
FT *squared_distance) const
|
||||||
|
{
|
||||||
|
std::vector<FT> sp_vec(
|
||||||
|
m_adaptor.kernel().construct_cartesian_const_iterator_d_object()(sp),
|
||||||
|
m_adaptor.kernel().construct_cartesian_const_iterator_d_object()(sp, 0));
|
||||||
|
nanoflann::KNNResultSet<FT> result_set(k);
|
||||||
|
result_set.init(neighbor_indices, squared_distance);
|
||||||
|
m_kd_tree.findNeighbors(result_set,
|
||||||
|
&sp_vec[0],
|
||||||
|
nanoflann::SearchParams());
|
||||||
|
|
||||||
|
/*std::cout << "knnSearch(nn="<< num_results <<"): \n";
|
||||||
|
for (int i = 0 ; i < num_results ; ++i)
|
||||||
|
{
|
||||||
|
std::cout << " * neighbor_indices = " << neighbor_indices [i]
|
||||||
|
<< " (out_dist_sqr = " << squared_distance[i] << ")"
|
||||||
|
<< std::endl;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void query_ball(const Point &sp,
|
||||||
|
const FT radius,
|
||||||
|
std::vector<std::pair<std::size_t, FT> > &neighbors,
|
||||||
|
bool sort_output = true)
|
||||||
|
{
|
||||||
|
std::vector<FT> sp_vec(
|
||||||
|
m_adaptor.kernel().construct_cartesian_const_iterator_d_object()(sp),
|
||||||
|
m_adaptor.kernel().construct_cartesian_const_iterator_d_object()(sp, 0));
|
||||||
|
m_kd_tree.radiusSearch(&sp_vec[0],
|
||||||
|
radius,
|
||||||
|
neighbors,
|
||||||
|
nanoflann::SearchParams(32, 0.f, sort_output));
|
||||||
|
|
||||||
|
/*std::cout << "radiusSearch(num="<< neighbors.size() <<"): \n";
|
||||||
|
for (const auto idx_and_dist : neighbors)
|
||||||
|
{
|
||||||
|
std::cout << " * neighbor_indices = " << idx_and_dist.first
|
||||||
|
<< " (out_dist_sqr = " << idx_and_dist.second << ")"
|
||||||
|
<< std::endl;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef Point_cloud_adaptator__nanoflann<Kernel, Point_container_> Adaptor;
|
||||||
|
typedef nanoflann::KDTreeSingleIndexAdaptor<
|
||||||
|
nanoflann::L2_Simple_Adaptor<FT, Adaptor> ,
|
||||||
|
Adaptor,
|
||||||
|
-1 // dim
|
||||||
|
> Kd_tree;
|
||||||
|
|
||||||
|
Adaptor m_adaptor;
|
||||||
|
Kd_tree m_kd_tree;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //CGAL_TC_NANOFLANN_IS_AVAILABLE
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//*****************************************************************************
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_ANN_IS_AVAILABLE
|
||||||
|
|
||||||
|
template <typename K, typename Point_container_>
|
||||||
|
class Point_cloud_data_structure__ANN
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename Point_container_::value_type Point;
|
||||||
|
typedef K Kernel;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
Point_cloud_data_structure__ANN(
|
||||||
|
Point_container_ const& points, Kernel const& k)
|
||||||
|
: m_dim(k.point_dimension_d_object()(*points.begin())),
|
||||||
|
m_k(k),
|
||||||
|
m_points(annAllocPts(points.size(), m_dim)),
|
||||||
|
m_tree(m_points, points.size(), m_dim)
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < points.size() ; ++i)
|
||||||
|
{
|
||||||
|
for (int j = 0 ; j < m_dim ; ++j)
|
||||||
|
m_points[i][j] = m_k.compute_coordinate_d_object()(points[i], j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void query_ANN(
|
||||||
|
Point const& p,
|
||||||
|
unsigned int k,
|
||||||
|
ANNidxArray neighbors_indices,
|
||||||
|
ANNdistArray neighbors_sq_distances)
|
||||||
|
{
|
||||||
|
// Create an ANN query point
|
||||||
|
ANNpoint query_pt = annAllocPt(m_dim);
|
||||||
|
for (int j = 0 ; j < m_dim ; ++j)
|
||||||
|
query_pt[j] = m_k.compute_coordinate_d_object()(p, j);
|
||||||
|
|
||||||
|
m_tree.annkSearch( // search
|
||||||
|
query_pt, // query point
|
||||||
|
k, // number of near neighbors
|
||||||
|
neighbors_indices, // nearest neighbors (returned)
|
||||||
|
neighbors_sq_distances, // distance (returned)
|
||||||
|
0); // error bound
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_dim;
|
||||||
|
Kernel const& m_k;
|
||||||
|
ANNpointArray m_points;
|
||||||
|
ANNkd_tree m_tree;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CGAL_TC_ANN_IS_AVAILABLE
|
||||||
|
|
||||||
|
} // namespace Tangential_complex_
|
||||||
|
} //namespace CGAL
|
||||||
|
|
||||||
|
#endif // POINT_CLOUD_H
|
||||||
|
|
@ -0,0 +1,526 @@
|
||||||
|
// Copyright (c) 2014 INRIA Sophia-Antipolis (France)
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL: $
|
||||||
|
// $Id: $
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Clement Jamin
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SIMPLICIAL_COMPLEX_H
|
||||||
|
#define SIMPLICIAL_COMPLEX_H
|
||||||
|
|
||||||
|
#include <CGAL/Tangential_complex/config.h>
|
||||||
|
#include <CGAL/Tangential_complex/utilities.h>
|
||||||
|
|
||||||
|
#include <CGAL/basic.h>
|
||||||
|
#include <CGAL/iterator.h>
|
||||||
|
|
||||||
|
// For is_pure_pseudomanifold
|
||||||
|
#include <boost/graph/graph_traits.hpp>
|
||||||
|
#include <boost/graph/adjacency_list.hpp>
|
||||||
|
#include <boost/graph/connected_components.hpp>
|
||||||
|
#include <boost/container/flat_map.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace Tangential_complex_ {
|
||||||
|
|
||||||
|
class Simplicial_complex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::set<std::size_t> Simplex;
|
||||||
|
typedef std::set<Simplex> Simplex_range;
|
||||||
|
|
||||||
|
void add_simplex(
|
||||||
|
const std::set<std::size_t> &s, bool perform_checks = true)
|
||||||
|
{
|
||||||
|
if (perform_checks)
|
||||||
|
{
|
||||||
|
unsigned int num_pts = static_cast<int>(s.size());
|
||||||
|
std::vector<Complex::iterator> to_erase;
|
||||||
|
bool check_higher_dim_simpl = true;
|
||||||
|
for (Complex::iterator it_simplex = m_complex.begin(),
|
||||||
|
it_simplex_end = m_complex.end() ;
|
||||||
|
it_simplex != it_simplex_end ;
|
||||||
|
++it_simplex)
|
||||||
|
{
|
||||||
|
// Check if the simplex is not already in a higher dim simplex
|
||||||
|
if (check_higher_dim_simpl
|
||||||
|
&& it_simplex->size() > num_pts
|
||||||
|
&& std::includes(it_simplex->begin(), it_simplex->end(),
|
||||||
|
s.begin(), s.end()))
|
||||||
|
{
|
||||||
|
// No need to insert it, then
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check if the simplex includes some lower-dim simplices
|
||||||
|
if (it_simplex->size() < num_pts
|
||||||
|
&& std::includes(s.begin(), s.end(),
|
||||||
|
it_simplex->begin(), it_simplex->end()))
|
||||||
|
{
|
||||||
|
to_erase.push_back(it_simplex);
|
||||||
|
// We don't need to check higher-sim simplices any more
|
||||||
|
check_higher_dim_simpl = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (std::vector<Complex::iterator>::const_iterator it= to_erase.begin();
|
||||||
|
it != to_erase.end() ; ++it)
|
||||||
|
{
|
||||||
|
m_complex.erase(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_complex.insert(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Simplex_range &simplex_range() const
|
||||||
|
{
|
||||||
|
return m_complex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
m_complex.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Test, typename Output_it>
|
||||||
|
void get_simplices_matching_test(Test test, Output_it out)
|
||||||
|
{
|
||||||
|
for (Complex::const_iterator it_simplex = m_complex.begin(),
|
||||||
|
it_simplex_end = m_complex.end() ;
|
||||||
|
it_simplex != it_simplex_end ;
|
||||||
|
++it_simplex)
|
||||||
|
{
|
||||||
|
if (test(*it_simplex))
|
||||||
|
*out++ = *it_simplex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When a simplex S has only one co-face C, we can remove S and C
|
||||||
|
// without changing the topology
|
||||||
|
void collapse(int max_simplex_dim, bool quiet = false)
|
||||||
|
{
|
||||||
|
#ifdef CGAL_TC_VERBOSE
|
||||||
|
if (!quiet)
|
||||||
|
std::cerr << "Collapsing... ";
|
||||||
|
#endif
|
||||||
|
// We note k = max_simplex_dim - 1
|
||||||
|
int k = max_simplex_dim - 1;
|
||||||
|
|
||||||
|
typedef Complex::iterator Simplex_iterator;
|
||||||
|
typedef std::vector<Simplex_iterator> Simplex_iterator_list;
|
||||||
|
typedef std::map<Simplex, Simplex_iterator_list> Cofaces_map;
|
||||||
|
|
||||||
|
std::size_t num_collapsed_maximal_simplices = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
num_collapsed_maximal_simplices = 0;
|
||||||
|
// Create a map associating each non-maximal k-faces to the list of its
|
||||||
|
// maximal cofaces
|
||||||
|
Cofaces_map cofaces_map;
|
||||||
|
for (Complex::const_iterator it_simplex = m_complex.begin(),
|
||||||
|
it_simplex_end = m_complex.end() ;
|
||||||
|
it_simplex != it_simplex_end ;
|
||||||
|
++it_simplex)
|
||||||
|
{
|
||||||
|
if (it_simplex->size() > k + 1)
|
||||||
|
{
|
||||||
|
std::vector<Simplex> k_faces;
|
||||||
|
// Get the k-faces composing the simplex
|
||||||
|
combinations(*it_simplex, k + 1, std::back_inserter(k_faces));
|
||||||
|
for (const auto &comb : k_faces) // CJTODO C++1
|
||||||
|
cofaces_map[comb].push_back(it_simplex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each non-maximal k-face F, if F has only one maximal coface Cf:
|
||||||
|
// - Look for the other k-faces F2, F3... of Cf in the map and:
|
||||||
|
// * if the list contains only Cf, clear the list (we don't remove the
|
||||||
|
// list since it creates troubles with the iterators) and add the F2,
|
||||||
|
// F3... to the complex
|
||||||
|
// * otherwise, remove Cf from the associated list
|
||||||
|
// - Remove Cf from the complex
|
||||||
|
for (Cofaces_map::const_iterator it_map_elt = cofaces_map.begin(),
|
||||||
|
it_map_end = cofaces_map.end() ;
|
||||||
|
it_map_elt != it_map_end ;
|
||||||
|
++it_map_elt)
|
||||||
|
{
|
||||||
|
if (it_map_elt->second.size() == 1)
|
||||||
|
{
|
||||||
|
std::vector<Simplex> k_faces;
|
||||||
|
const Simplex_iterator_list::value_type &it_Cf =
|
||||||
|
*it_map_elt->second.begin();
|
||||||
|
CGAL_assertion(it_Cf->size() == max_simplex_dim + 1);
|
||||||
|
// Get the k-faces composing the simplex
|
||||||
|
combinations(*it_Cf, k + 1, std::back_inserter(k_faces));
|
||||||
|
for (const auto &f2 : k_faces) // CJTODO C++1
|
||||||
|
{
|
||||||
|
// Skip F
|
||||||
|
if (f2 != it_map_elt->first)
|
||||||
|
{
|
||||||
|
Cofaces_map::iterator it_comb_in_map = cofaces_map.find(f2);
|
||||||
|
if (it_comb_in_map->second.size() == 1)
|
||||||
|
{
|
||||||
|
it_comb_in_map->second.clear();
|
||||||
|
m_complex.insert(f2);
|
||||||
|
}
|
||||||
|
else // it_comb_in_map->second.size() > 1
|
||||||
|
{
|
||||||
|
Simplex_iterator_list::iterator it = std::find(
|
||||||
|
it_comb_in_map->second.begin(),
|
||||||
|
it_comb_in_map->second.end(),
|
||||||
|
it_Cf);
|
||||||
|
CGAL_assertion(it != it_comb_in_map->second.end());
|
||||||
|
it_comb_in_map->second.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_complex.erase(it_Cf);
|
||||||
|
++num_collapsed_maximal_simplices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Repeat until no maximal simplex got removed
|
||||||
|
} while (num_collapsed_maximal_simplices > 0);
|
||||||
|
|
||||||
|
// Collapse the lower dimension simplices
|
||||||
|
if (k > 0)
|
||||||
|
collapse(max_simplex_dim - 1, true);
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_VERBOSE
|
||||||
|
if (!quiet)
|
||||||
|
std::cerr << "done." << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_stats() const
|
||||||
|
{
|
||||||
|
std::cerr << "==========================================================\n";
|
||||||
|
std::cerr << "Complex stats:\n";
|
||||||
|
|
||||||
|
if (m_complex.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "No simplices.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Number of simplex for each dimension
|
||||||
|
std::map<int, std::size_t> simplex_stats;
|
||||||
|
|
||||||
|
for (Complex::const_iterator it_simplex = m_complex.begin(),
|
||||||
|
it_simplex_end = m_complex.end() ;
|
||||||
|
it_simplex != it_simplex_end ;
|
||||||
|
++it_simplex)
|
||||||
|
{
|
||||||
|
++simplex_stats[static_cast<int>(it_simplex->size()) - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::map<int, std::size_t>::const_iterator it_map = simplex_stats.begin() ;
|
||||||
|
it_map != simplex_stats.end() ; ++it_map)
|
||||||
|
{
|
||||||
|
std::cerr << " * " << it_map->first << "-simplices: "
|
||||||
|
<< it_map->second << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "==========================================================\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// verbose_level = 0, 1 or 2
|
||||||
|
bool is_pure_pseudomanifold__do_not_check_if_stars_are_connected(
|
||||||
|
int simplex_dim,
|
||||||
|
bool exit_at_the_first_problem = false,
|
||||||
|
int verbose_level = 0,
|
||||||
|
std::size_t *p_num_wrong_dim_simplices = NULL,
|
||||||
|
std::size_t *p_num_wrong_number_of_cofaces = NULL)
|
||||||
|
{
|
||||||
|
typedef std::set<std::size_t> K_1_face;
|
||||||
|
typedef std::map<K_1_face, std::size_t> Cofaces_map;
|
||||||
|
|
||||||
|
std::size_t num_wrong_dim_simplices = 0;
|
||||||
|
std::size_t num_wrong_number_of_cofaces = 0;
|
||||||
|
|
||||||
|
// Counts the number of cofaces of each K_1_face
|
||||||
|
|
||||||
|
// Create a map associating each non-maximal k-faces to the list of its
|
||||||
|
// maximal cofaces
|
||||||
|
Cofaces_map cofaces_map;
|
||||||
|
for (Complex::const_iterator it_simplex = m_complex.begin(),
|
||||||
|
it_simplex_end = m_complex.end() ;
|
||||||
|
it_simplex != it_simplex_end ;
|
||||||
|
++it_simplex)
|
||||||
|
{
|
||||||
|
if (it_simplex->size() != simplex_dim + 1)
|
||||||
|
{
|
||||||
|
if (verbose_level >= 2)
|
||||||
|
std::cerr << "Found a simplex with dim = "
|
||||||
|
<< it_simplex->size() - 1 << std::endl;
|
||||||
|
++num_wrong_dim_simplices;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<K_1_face> k_1_faces;
|
||||||
|
// Get the facets composing the simplex
|
||||||
|
combinations(
|
||||||
|
*it_simplex, simplex_dim, std::back_inserter(k_1_faces));
|
||||||
|
for (const auto &k_1_face : k_1_faces) // CJTODO C++1
|
||||||
|
{
|
||||||
|
++cofaces_map[k_1_face];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Cofaces_map::const_iterator it_map_elt = cofaces_map.begin(),
|
||||||
|
it_map_end = cofaces_map.end() ;
|
||||||
|
it_map_elt != it_map_end ;
|
||||||
|
++it_map_elt)
|
||||||
|
{
|
||||||
|
if (it_map_elt->second != 2)
|
||||||
|
{
|
||||||
|
if (verbose_level >= 2)
|
||||||
|
std::cerr << "Found a k-1-face with "
|
||||||
|
<< it_map_elt->second << " cofaces\n";
|
||||||
|
|
||||||
|
if (exit_at_the_first_problem)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
++num_wrong_number_of_cofaces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = num_wrong_dim_simplices == 0 && num_wrong_number_of_cofaces == 0;
|
||||||
|
|
||||||
|
if (verbose_level >= 1)
|
||||||
|
{
|
||||||
|
std::cerr << "is_pure_manifold: " << (ret ? "YES" : "NO") << std::endl;
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
std::cerr << " * Number of wrong dimension simplices: "
|
||||||
|
<< num_wrong_dim_simplices << std::endl
|
||||||
|
<< " * Number of wrong number of cofaces: "
|
||||||
|
<< num_wrong_number_of_cofaces << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_num_wrong_dim_simplices)
|
||||||
|
*p_num_wrong_dim_simplices = num_wrong_dim_simplices;
|
||||||
|
if (p_num_wrong_number_of_cofaces)
|
||||||
|
*p_num_wrong_number_of_cofaces = num_wrong_number_of_cofaces;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CJTODO: ADD COMMENTS
|
||||||
|
bool is_pure_pseudomanifold(
|
||||||
|
int simplex_dim,
|
||||||
|
std::size_t num_vertices,
|
||||||
|
bool exit_at_the_first_problem = false,
|
||||||
|
int verbose_level = 0,
|
||||||
|
std::size_t *p_num_wrong_dim_simplices = NULL,
|
||||||
|
std::size_t *p_num_wrong_number_of_cofaces = NULL,
|
||||||
|
std::size_t *p_num_unconnected_stars = NULL,
|
||||||
|
Simplex_range *p_wrong_dim_simplices = NULL,
|
||||||
|
Simplex_range *p_wrong_number_of_cofaces_simplices = NULL,
|
||||||
|
Simplex_range *p_unconnected_stars_simplices = NULL)
|
||||||
|
{
|
||||||
|
// If simplex_dim == 1, we do not need to check if stars are connected
|
||||||
|
if (simplex_dim == 1)
|
||||||
|
{
|
||||||
|
if (p_num_unconnected_stars)
|
||||||
|
*p_num_unconnected_stars = 0;
|
||||||
|
return is_pure_pseudomanifold__do_not_check_if_stars_are_connected(
|
||||||
|
simplex_dim,
|
||||||
|
exit_at_the_first_problem,
|
||||||
|
verbose_level,
|
||||||
|
p_num_wrong_dim_simplices,
|
||||||
|
p_num_wrong_number_of_cofaces);
|
||||||
|
}
|
||||||
|
// Associates each vertex (= the index in the vector)
|
||||||
|
// to its star (list of simplices)
|
||||||
|
typedef std::vector<std::vector<Complex::const_iterator> > Stars;
|
||||||
|
std::size_t num_wrong_dim_simplices = 0;
|
||||||
|
std::size_t num_wrong_number_of_cofaces = 0;
|
||||||
|
std::size_t num_unconnected_stars = 0;
|
||||||
|
|
||||||
|
// Fills a Stars data structure
|
||||||
|
Stars stars;
|
||||||
|
stars.resize(num_vertices);
|
||||||
|
for (Complex::const_iterator it_simplex = m_complex.begin(),
|
||||||
|
it_simplex_end = m_complex.end() ;
|
||||||
|
it_simplex != it_simplex_end ;
|
||||||
|
++it_simplex)
|
||||||
|
{
|
||||||
|
if (it_simplex->size() != simplex_dim + 1)
|
||||||
|
{
|
||||||
|
if (verbose_level >= 2)
|
||||||
|
std::cerr << "Found a simplex with dim = "
|
||||||
|
<< it_simplex->size() - 1 << std::endl;
|
||||||
|
++num_wrong_dim_simplices;
|
||||||
|
if (p_wrong_dim_simplices)
|
||||||
|
p_wrong_dim_simplices->insert(*it_simplex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (Simplex::const_iterator it_point_idx = it_simplex->begin() ;
|
||||||
|
it_point_idx != it_simplex->end() ;
|
||||||
|
++it_point_idx)
|
||||||
|
{
|
||||||
|
stars[*it_point_idx].push_back(it_simplex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, for each star, with have a vector of its d-simplices
|
||||||
|
// i.e. one index for each d-simplex
|
||||||
|
// Boost Graph only deals with indexes, so we also need indexes for the
|
||||||
|
// (d-1)-simplices
|
||||||
|
std::size_t center_vertex_index = 0;
|
||||||
|
for (Stars::const_iterator it_star = stars.begin() ;
|
||||||
|
it_star != stars.end() ;
|
||||||
|
++it_star, ++center_vertex_index)
|
||||||
|
{
|
||||||
|
typedef std::map<Simplex, std::vector<std::size_t> >
|
||||||
|
Dm1_faces_to_adj_D_faces;
|
||||||
|
Dm1_faces_to_adj_D_faces dm1_faces_to_adj_d_faces;
|
||||||
|
|
||||||
|
for (int i_dsimpl = 0 ; i_dsimpl < it_star->size() ; ++i_dsimpl)
|
||||||
|
{
|
||||||
|
Simplex dm1_simpl_of_link = *((*it_star)[i_dsimpl]);
|
||||||
|
dm1_simpl_of_link.erase(center_vertex_index);
|
||||||
|
// Copy it to a vector so that we can use operator[] on it
|
||||||
|
std::vector<std::size_t> dm1_simpl_of_link_vec(
|
||||||
|
dm1_simpl_of_link.begin(), dm1_simpl_of_link.end());
|
||||||
|
|
||||||
|
CGAL::Combination_enumerator<int> dm2_simplices(
|
||||||
|
simplex_dim - 1, 0, simplex_dim);
|
||||||
|
for ( ; !dm2_simplices.finished() ; ++dm2_simplices)
|
||||||
|
{
|
||||||
|
Simplex dm2_simpl;
|
||||||
|
for (int j = 0 ; j < simplex_dim - 1 ; ++j)
|
||||||
|
dm2_simpl.insert(dm1_simpl_of_link_vec[dm2_simplices[j]]);
|
||||||
|
dm1_faces_to_adj_d_faces[dm2_simpl].push_back(i_dsimpl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Adj_graph adj_graph;
|
||||||
|
std::vector<Graph_vertex> d_faces_descriptors;
|
||||||
|
d_faces_descriptors.resize(it_star->size());
|
||||||
|
for (int j = 0 ; j < it_star->size() ; ++j)
|
||||||
|
d_faces_descriptors[j] = boost::add_vertex(adj_graph);
|
||||||
|
|
||||||
|
Dm1_faces_to_adj_D_faces::const_iterator dm1_to_d_it =
|
||||||
|
dm1_faces_to_adj_d_faces.begin();
|
||||||
|
Dm1_faces_to_adj_D_faces::const_iterator dm1_to_d_it_end =
|
||||||
|
dm1_faces_to_adj_d_faces.end();
|
||||||
|
for (std::size_t i_km1_face = 0 ;
|
||||||
|
dm1_to_d_it != dm1_to_d_it_end ;
|
||||||
|
++dm1_to_d_it, ++i_km1_face)
|
||||||
|
{
|
||||||
|
Graph_vertex km1_gv = boost::add_vertex(adj_graph);
|
||||||
|
|
||||||
|
for (std::vector<std::size_t>::const_iterator kface_it =
|
||||||
|
dm1_to_d_it->second.begin() ;
|
||||||
|
kface_it != dm1_to_d_it->second.end() ;
|
||||||
|
++kface_it)
|
||||||
|
{
|
||||||
|
boost::add_edge(km1_gv, *kface_it, adj_graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dm1_to_d_it->second.size() != 2)
|
||||||
|
{
|
||||||
|
++num_wrong_number_of_cofaces;
|
||||||
|
if (p_wrong_number_of_cofaces_simplices)
|
||||||
|
{
|
||||||
|
for (auto idx : dm1_to_d_it->second)
|
||||||
|
p_wrong_number_of_cofaces_simplices->insert(*((*it_star)[idx]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// What is left is to check the connexity
|
||||||
|
std::vector<int> components(boost::num_vertices(adj_graph));
|
||||||
|
bool is_connected =
|
||||||
|
(boost::connected_components(adj_graph, &components[0]) == 1);
|
||||||
|
|
||||||
|
if (!is_connected)
|
||||||
|
{
|
||||||
|
if (verbose_level >= 2)
|
||||||
|
std::cerr << "Error: star #" << center_vertex_index
|
||||||
|
<< " is not connected" << std::endl;
|
||||||
|
++num_unconnected_stars;
|
||||||
|
if (p_unconnected_stars_simplices)
|
||||||
|
{
|
||||||
|
for (std::vector<Complex::const_iterator>::const_iterator
|
||||||
|
it_simpl = it_star->begin(),
|
||||||
|
it_simpl_end = it_star->end();
|
||||||
|
it_simpl != it_simpl_end ;
|
||||||
|
++it_simpl)
|
||||||
|
{
|
||||||
|
p_unconnected_stars_simplices->insert(**it_simpl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each one has been counted several times ("simplex_dim" times)
|
||||||
|
num_wrong_number_of_cofaces /= simplex_dim;
|
||||||
|
|
||||||
|
bool ret =
|
||||||
|
num_wrong_dim_simplices == 0
|
||||||
|
&& num_wrong_number_of_cofaces == 0
|
||||||
|
&& num_unconnected_stars == 0;
|
||||||
|
|
||||||
|
if (verbose_level >= 1)
|
||||||
|
{
|
||||||
|
std::cerr << "is_pure_pseudo_manifold: "
|
||||||
|
<< (ret ? "YES" : "NO") << std::endl;
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
std::cerr << " * Number of wrong dimension simplices: "
|
||||||
|
<< num_wrong_dim_simplices << std::endl
|
||||||
|
<< " * Number of wrong number of cofaces: "
|
||||||
|
<< num_wrong_number_of_cofaces << std::endl
|
||||||
|
<< " * Number of not-connected stars: "
|
||||||
|
<< num_unconnected_stars << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_num_wrong_dim_simplices)
|
||||||
|
*p_num_wrong_dim_simplices = num_wrong_dim_simplices;
|
||||||
|
if (p_num_wrong_number_of_cofaces)
|
||||||
|
*p_num_wrong_number_of_cofaces = num_wrong_number_of_cofaces;
|
||||||
|
if (p_num_unconnected_stars)
|
||||||
|
*p_num_unconnected_stars = num_unconnected_stars;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef Simplex_range Complex;
|
||||||
|
|
||||||
|
// graph is an adjacency list
|
||||||
|
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS> Adj_graph;
|
||||||
|
// map that gives to a certain simplex its node in graph and its dimension
|
||||||
|
typedef boost::graph_traits<Adj_graph>::vertex_descriptor Graph_vertex;
|
||||||
|
typedef boost::graph_traits<Adj_graph>::edge_descriptor Graph_edge;
|
||||||
|
|
||||||
|
Complex m_complex;
|
||||||
|
|
||||||
|
}; // /class Simplicial_complex
|
||||||
|
|
||||||
|
} // namespace Tangential_complex_
|
||||||
|
} //namespace CGAL
|
||||||
|
|
||||||
|
#endif // SIMPLICIAL_COMPLEX_H
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright (c) 2014 INRIA Sophia-Antipolis (France)
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL: $
|
||||||
|
// $Id: $
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Clement Jamin
|
||||||
|
|
||||||
|
#ifndef CGAL_TC_CONFIG_H
|
||||||
|
#define CGAL_TC_CONFIG_H
|
||||||
|
|
||||||
|
#include <CGAL/config.h>
|
||||||
|
|
||||||
|
// Without TBB_USE_THREADING_TOOL Intel Inspector XE will report false
|
||||||
|
// positives in Intel TBB
|
||||||
|
// (http://software.intel.com/en-us/articles/compiler-settings-for-threading-error-analysis-in-intel-inspector-xe/)
|
||||||
|
#ifdef _DEBUG
|
||||||
|
# define TBB_USE_THREADING_TOOL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//=========================== Alpha-TC or not? ================================
|
||||||
|
|
||||||
|
#define CGAL_ALPHA_TC
|
||||||
|
//#define CGAL_USE_A_FIXED_ALPHA
|
||||||
|
const double CGAL_TC_ALPHA_VALUE = 0.3;
|
||||||
|
|
||||||
|
//========================= Debugging & profiling =============================
|
||||||
|
#define CGAL_TC_PROFILING
|
||||||
|
#define CGAL_TC_VERBOSE
|
||||||
|
#define CGAL_TC_VERY_VERBOSE
|
||||||
|
#define CGAL_TC_PERFORM_EXTRA_CHECKS
|
||||||
|
//#define CGAL_TC_SHOW_DETAILED_STATS_FOR_INCONSISTENCIES
|
||||||
|
//#define USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||||
|
|
||||||
|
// Solving inconsistencies: only perturb the vertex, the simplex or more?
|
||||||
|
//#define CGAL_TC_PERTURB_THE_CENTER_VERTEX_ONLY
|
||||||
|
//#define CGAL_TC_PERTURB_THE_SIMPLEX_ONLY
|
||||||
|
//#define CGAL_TC_PERTURB_THE_1_STAR
|
||||||
|
#define CGAL_TC_PERTURB_N_CLOSEST_POINTS // perturb the CGAL_TC_NUMBER_OF_PERTURBED_POINTS closest points
|
||||||
|
// Otherwise, perturb one random point of the simplex
|
||||||
|
|
||||||
|
// Only used if CGAL_TC_PERTURB_N_CLOSEST_POINTS is defined
|
||||||
|
#define CGAL_TC_NUMBER_OF_PERTURBED_POINTS(intr_dim) (1)
|
||||||
|
//#define CGAL_TC_NUMBER_OF_PERTURBED_POINTS(intr_dim) (intr_dim + 2)
|
||||||
|
|
||||||
|
|
||||||
|
//========================= Strategy ==========================================
|
||||||
|
#define CGAL_TC_NANOFLANN_IS_AVAILABLE
|
||||||
|
//#define CGAL_TC_ANN_IS_AVAILABLE
|
||||||
|
//#define CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
#define CGAL_TC_GLOBAL_REFRESH
|
||||||
|
//#define CGAL_TC_ON_DEMAND_REFRESH // CJTODO: not implemented yet
|
||||||
|
// The idea is to perform a global refresh + some local refreshes, just
|
||||||
|
// for local tri where there are some inconsistencies
|
||||||
|
// But be careful: refreshing the TC may invalidate cells, so the
|
||||||
|
// incident cells have to be recomputed again
|
||||||
|
#define CGAL_TC_PERTURB_POSITION
|
||||||
|
# define CGAL_TC_PERTURB_POSITION_TANGENTIAL // default
|
||||||
|
//# define CGAL_TC_PERTURB_POSITION_GLOBAL
|
||||||
|
//#define CGAL_TC_PERTURB_WEIGHT
|
||||||
|
//#define CGAL_TC_PERTURB_TANGENT_SPACE
|
||||||
|
|
||||||
|
//========================= Parameters ========================================
|
||||||
|
|
||||||
|
// PCA will use BASE_VALUE_FOR_PCA^intrinsic_dim points
|
||||||
|
const std::size_t BASE_VALUE_FOR_PCA = 5;
|
||||||
|
|
||||||
|
#endif // CGAL_TC_CONFIG_H
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,410 @@
|
||||||
|
// Copyright (c) 2014 INRIA Sophia-Antipolis (France)
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL: $
|
||||||
|
// $Id: $
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Clement Jamin
|
||||||
|
|
||||||
|
#ifndef CGAL_TC_UTILITIES_H
|
||||||
|
#define CGAL_TC_UTILITIES_H
|
||||||
|
|
||||||
|
#include <CGAL/basic.h>
|
||||||
|
#include <CGAL/Dimension.h>
|
||||||
|
#include <CGAL/Combination_enumerator.h>
|
||||||
|
#include <CGAL/QP_models.h>
|
||||||
|
#include <CGAL/QP_functions.h>
|
||||||
|
|
||||||
|
#include <Eigen/Core>
|
||||||
|
#include <Eigen/Eigen>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <atomic> // CJTODO: this is C++11 => use boost.Atomic (but it's too recent)
|
||||||
|
// or tbb::atomic (works for doubles, but not officially)
|
||||||
|
|
||||||
|
// choose exact integral type for QP solver
|
||||||
|
// (Gmpzf is not thread-safe)
|
||||||
|
#include <CGAL/MP_Float.h>
|
||||||
|
typedef CGAL::MP_Float ET;
|
||||||
|
//#define CGAL_QP_NO_ASSERTIONS // CJTODO: NECESSARY? http://doc.cgal.org/latest/QP_solver/group__PkgQPSolverFunctions.html#ga1fefbd0436aca0e281f88e8e6cd8eb74
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace Tangential_complex_ {
|
||||||
|
|
||||||
|
// Provides copy constructors to std::atomic so that
|
||||||
|
// it can be used in a vector
|
||||||
|
template <typename T>
|
||||||
|
struct Atomic_wrapper
|
||||||
|
: public std::atomic<T>
|
||||||
|
{
|
||||||
|
typedef std::atomic<T> Base;
|
||||||
|
|
||||||
|
Atomic_wrapper() {}
|
||||||
|
Atomic_wrapper(const T &t) : Base(t) {}
|
||||||
|
Atomic_wrapper(const std::atomic<T> &a) : Base(a.load()) {}
|
||||||
|
Atomic_wrapper(const Atomic_wrapper &other) : Base(other.load())
|
||||||
|
{}
|
||||||
|
|
||||||
|
Atomic_wrapper &operator=(const T &other)
|
||||||
|
{
|
||||||
|
Base::store(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Atomic_wrapper &operator=(const std::atomic<T> &other)
|
||||||
|
{
|
||||||
|
Base::store(other.load());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Atomic_wrapper &operator=(const Atomic_wrapper &other)
|
||||||
|
{
|
||||||
|
Base::store(other.load());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*template <typename T>
|
||||||
|
struct Atomic_wrapper
|
||||||
|
{
|
||||||
|
std::atomic<T> _a;
|
||||||
|
|
||||||
|
Atomic_wrapper()
|
||||||
|
:_a()
|
||||||
|
{}
|
||||||
|
|
||||||
|
Atomic_wrapper(const std::atomic<T> &other)
|
||||||
|
:_a(other.load())
|
||||||
|
{}
|
||||||
|
|
||||||
|
Atomic_wrapper(const Atomic_wrapper &other)
|
||||||
|
:_a(other._a.load())
|
||||||
|
{}
|
||||||
|
|
||||||
|
Atomic_wrapper(const T &other)
|
||||||
|
:_a(other)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Atomic_wrapper &operator=(const std::atomic<T> &other)
|
||||||
|
{
|
||||||
|
_a.store(other._a.load());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Atomic_wrapper &operator=(const Atomic_wrapper &other)
|
||||||
|
{
|
||||||
|
_a.store(other._a.load());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Atomic_wrapper &operator=(const T &other)
|
||||||
|
{
|
||||||
|
_a.store(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T() const
|
||||||
|
{
|
||||||
|
return _a.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator std::atomic<T>() const
|
||||||
|
{
|
||||||
|
return _a;
|
||||||
|
}
|
||||||
|
};*/
|
||||||
|
|
||||||
|
// Modifies v in-place
|
||||||
|
template <typename K>
|
||||||
|
typename K::Vector_d& normalize_vector(typename K::Vector_d& v,
|
||||||
|
K const& k)
|
||||||
|
{
|
||||||
|
v = k.scaled_vector_d_object()(
|
||||||
|
v, typename K::FT(1)/CGAL::sqrt(k.squared_length_d_object()(v)));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Kernel>
|
||||||
|
struct Basis
|
||||||
|
{
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
typedef typename Kernel::Vector_d Vector;
|
||||||
|
typedef typename std::vector<Vector>::const_iterator const_iterator;
|
||||||
|
|
||||||
|
std::size_t m_origin;
|
||||||
|
std::vector<Vector> m_vectors;
|
||||||
|
|
||||||
|
std::size_t origin() const { return m_origin; }
|
||||||
|
void set_origin(std::size_t o) { m_origin = o; }
|
||||||
|
const_iterator begin() const { return m_vectors.begin(); }
|
||||||
|
const_iterator end() const { return m_vectors.end(); }
|
||||||
|
std::size_t size() const { return m_vectors.size(); }
|
||||||
|
|
||||||
|
Vector& operator[](const std::size_t i)
|
||||||
|
{
|
||||||
|
return m_vectors[i];
|
||||||
|
}
|
||||||
|
const Vector& operator[](const std::size_t i) const
|
||||||
|
{
|
||||||
|
return m_vectors[i];
|
||||||
|
}
|
||||||
|
void push_back(const Vector& v)
|
||||||
|
{
|
||||||
|
m_vectors.push_back(v);
|
||||||
|
}
|
||||||
|
void reserve(const std::size_t s)
|
||||||
|
{
|
||||||
|
m_vectors.reserve(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
Basis() { }
|
||||||
|
Basis(std::size_t origin) : m_origin(origin) { }
|
||||||
|
Basis(std::size_t origin, const std::vector<Vector>& vectors)
|
||||||
|
: m_origin(origin), m_vectors(vectors)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#ifdef CGAL_ALPHA_TC
|
||||||
|
// Thickening vectors...
|
||||||
|
|
||||||
|
struct Thickening_vector
|
||||||
|
{
|
||||||
|
Thickening_vector()
|
||||||
|
: alpha_minus(FT(0)), alpha_plus(FT(0)) {}
|
||||||
|
Thickening_vector(Vector const& v, FT am, FT ap)
|
||||||
|
: vec(v), alpha_minus(am), alpha_plus(ap) {}
|
||||||
|
|
||||||
|
Vector vec;
|
||||||
|
FT alpha_minus;
|
||||||
|
FT alpha_plus;
|
||||||
|
};
|
||||||
|
typedef std::vector<Thickening_vector> Thickening_vectors;
|
||||||
|
|
||||||
|
Thickening_vectors m_thickening_vectors;
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t num_thickening_vectors() const
|
||||||
|
{
|
||||||
|
return m_thickening_vectors.size();
|
||||||
|
}
|
||||||
|
Thickening_vectors const& thickening_vectors() const
|
||||||
|
{
|
||||||
|
return m_thickening_vectors;
|
||||||
|
}
|
||||||
|
void add_thickening_vector(
|
||||||
|
Vector const& vec, FT alpha_minus = FT(0), FT alpha_plus = FT(0))
|
||||||
|
{
|
||||||
|
m_thickening_vectors.push_back(
|
||||||
|
Thickening_vector(vec, alpha_minus, alpha_plus));
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_alpha_values_of_thickening_vectors(
|
||||||
|
Vector const& vec, Kernel const& k)
|
||||||
|
{
|
||||||
|
typename Kernel::Scalar_product_d k_scalar_pdct =
|
||||||
|
k.scalar_product_d_object();
|
||||||
|
|
||||||
|
for (Thickening_vectors::iterator it_v = m_thickening_vectors.begin(),
|
||||||
|
it_v_end = m_thickening_vectors.end() ;
|
||||||
|
it_v != it_v_end ; ++it_v)
|
||||||
|
{
|
||||||
|
const FT MARGIN_RATIO = 1.001; // CJTODO TEMP
|
||||||
|
FT alpha_i = k_scalar_pdct(it_v->vec, vec);
|
||||||
|
if (alpha_i * MARGIN_RATIO > it_v->alpha_plus)
|
||||||
|
{
|
||||||
|
#ifdef CGAL_TC_VERY_VERBOSE
|
||||||
|
std::cerr << "OLD alpha+ = " << it_v->alpha_plus << std::endl;
|
||||||
|
#endif
|
||||||
|
it_v->alpha_plus = alpha_i * MARGIN_RATIO;
|
||||||
|
#ifdef CGAL_TC_VERY_VERBOSE
|
||||||
|
std::cerr << "NEW alpha+ = " << it_v->alpha_plus << std::endl;
|
||||||
|
std::cerr << "NOT MODIFIED alpha- = " << it_v->alpha_minus << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (alpha_i * MARGIN_RATIO < it_v->alpha_minus)
|
||||||
|
{
|
||||||
|
#ifdef CGAL_TC_VERY_VERBOSE
|
||||||
|
std::cerr << "OLD alpha- = " << it_v->alpha_minus << std::endl;
|
||||||
|
#endif
|
||||||
|
it_v->alpha_minus = alpha_i * MARGIN_RATIO;
|
||||||
|
#ifdef CGAL_TC_VERY_VERBOSE
|
||||||
|
std::cerr << "NEW alpha- = " << it_v->alpha_minus << std::endl;
|
||||||
|
std::cerr << "NOT MODIFIED alpha+ = " << it_v->alpha_plus << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FT alpha_minus(std::size_t i) const
|
||||||
|
{
|
||||||
|
return m_thickening_vectors[i].alpha_minus;
|
||||||
|
}
|
||||||
|
FT alpha_plus(std::size_t i) const
|
||||||
|
{
|
||||||
|
return m_thickening_vectors[i].alpha_plus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns 0 if no thickening vectors
|
||||||
|
FT max_absolute_alpha() const
|
||||||
|
{
|
||||||
|
FT max = FT(0);
|
||||||
|
|
||||||
|
for (Thickening_vectors::const_iterator
|
||||||
|
it_v = m_thickening_vectors.begin(),
|
||||||
|
it_v_end = m_thickening_vectors.end() ;
|
||||||
|
it_v != it_v_end ;
|
||||||
|
++it_v)
|
||||||
|
{
|
||||||
|
if (it_v->alpha_plus > max)
|
||||||
|
max = it_v->alpha_plus;
|
||||||
|
if (-it_v->alpha_minus > max)
|
||||||
|
max = -it_v->alpha_minus;
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dimension() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_vectors.size() + m_thickening_vectors.size());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int dimension() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_vectors.size());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// Using Gram-Schmidt
|
||||||
|
// * If the resulting vector after G-S algorithm is below "sqlen_threshold",
|
||||||
|
// the vector considered linearly dependend to the existing vectors
|
||||||
|
// and is not added to the basis
|
||||||
|
// * Returns true if the vector was added to the basis
|
||||||
|
template <typename K>
|
||||||
|
bool add_vector_to_orthonormal_basis(
|
||||||
|
Basis<K> & basis, typename K::Vector_d const& v, K const& k,
|
||||||
|
typename K::FT sqlen_threshold = typename K::FT(1e-13)
|
||||||
|
#ifdef CGAL_ALPHA_TC
|
||||||
|
, bool add_to_thickening_vectors = false
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typedef Basis<K> Basis;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
typedef typename K::Vector_d Vector;
|
||||||
|
|
||||||
|
// Kernel functors
|
||||||
|
typename K::Scaled_vector_d scaled_vec = k.scaled_vector_d_object();
|
||||||
|
typename K::Scalar_product_d scalar_pdct = k.scalar_product_d_object();
|
||||||
|
typename K::Difference_of_vectors_d diff_vec = k.difference_of_vectors_d_object();
|
||||||
|
|
||||||
|
Vector u = v;
|
||||||
|
for (int j = 0 ; j < basis.size() ; ++j)
|
||||||
|
{
|
||||||
|
Vector const& ej = basis[j];
|
||||||
|
Vector u_proj = scaled_vec(ej, scalar_pdct(u, ej) / scalar_pdct(ej, ej));
|
||||||
|
u = diff_vec(u, u_proj);
|
||||||
|
}
|
||||||
|
for (int j = 0 ; j < basis.num_thickening_vectors() ; ++j)
|
||||||
|
{
|
||||||
|
Vector const& ej = basis.thickening_vectors()[j].vec;
|
||||||
|
Vector u_proj = scaled_vec(ej, scalar_pdct(u, ej) / scalar_pdct(ej, ej));
|
||||||
|
u = diff_vec(u, u_proj);
|
||||||
|
}
|
||||||
|
|
||||||
|
FT sqlen_new_v = k.squared_length_d_object()(u);
|
||||||
|
bool add_it = (sqlen_new_v > sqlen_threshold);
|
||||||
|
if (add_it)
|
||||||
|
{
|
||||||
|
Vector new_v = scaled_vec(u, FT(1)/CGAL::sqrt(sqlen_new_v));
|
||||||
|
|
||||||
|
// If new_v is small, run the Gram-Schmidt once more to
|
||||||
|
// re-orthogonalize it
|
||||||
|
if (sqlen_new_v < 0.01)
|
||||||
|
{
|
||||||
|
for (int j = 0 ; j < basis.size() ; ++j)
|
||||||
|
{
|
||||||
|
Vector const& ej = basis[j];
|
||||||
|
Vector new_v_proj = scaled_vec(
|
||||||
|
ej, scalar_pdct(new_v, ej) / scalar_pdct(ej, ej));
|
||||||
|
new_v = diff_vec(new_v, new_v_proj);
|
||||||
|
}
|
||||||
|
for (int j = 0 ; j < basis.num_thickening_vectors() ; ++j)
|
||||||
|
{
|
||||||
|
Vector const& ej = basis.thickening_vectors()[j].vec;
|
||||||
|
Vector new_v_proj = scaled_vec(
|
||||||
|
ej, scalar_pdct(new_v, ej) / scalar_pdct(ej, ej));
|
||||||
|
new_v = diff_vec(new_v, new_v_proj);
|
||||||
|
}
|
||||||
|
sqlen_new_v = k.squared_length_d_object()(new_v);
|
||||||
|
new_v = scaled_vec(new_v, FT(1)/CGAL::sqrt(sqlen_new_v));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CGAL_ALPHA_TC
|
||||||
|
if (add_to_thickening_vectors)
|
||||||
|
basis.add_thickening_vector(new_v);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
basis.push_back(new_v);
|
||||||
|
}
|
||||||
|
return add_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K>
|
||||||
|
Basis<K> compute_gram_schmidt_basis(Basis<K> const& input_basis, K const& k)
|
||||||
|
{
|
||||||
|
typedef Basis<K> Basis;
|
||||||
|
|
||||||
|
Basis output_basis(input_basis.origin());
|
||||||
|
|
||||||
|
// Add vector one by one
|
||||||
|
typename Basis::const_iterator inb_it = input_basis.begin();
|
||||||
|
typename Basis::const_iterator inb_it_end = input_basis.end();
|
||||||
|
for (int i = 0 ; inb_it != inb_it_end ; ++inb_it, ++i)
|
||||||
|
add_vector_to_orthonormal_basis(output_basis, *inb_it, k);
|
||||||
|
|
||||||
|
return output_basis;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CJTODO: use CGAL::Combination_enumerator<int> (cf. Tangential_complex.h)
|
||||||
|
// Compute all the k-combinations of elements
|
||||||
|
// Output_iterator::value_type must be std::set<std::size_t> >
|
||||||
|
template <typename Elements_container, typename Output_iterator>
|
||||||
|
void combinations(const Elements_container elements, int k,
|
||||||
|
Output_iterator combinations)
|
||||||
|
{
|
||||||
|
std::size_t n = elements.size();
|
||||||
|
std::vector<bool> booleans(n, false);
|
||||||
|
std::fill(booleans.begin() + n - k, booleans.end(), true);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
std::set<std::size_t> combination;
|
||||||
|
typename Elements_container::const_iterator it_elt = elements.begin();
|
||||||
|
for (std::size_t i = 0 ; i < n ; ++i, ++it_elt)
|
||||||
|
{
|
||||||
|
if (booleans[i])
|
||||||
|
combination.insert(*it_elt);
|
||||||
|
}
|
||||||
|
*combinations++ = combination;
|
||||||
|
|
||||||
|
} while (std::next_permutation(booleans.begin(), booleans.end()));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Tangential_complex_
|
||||||
|
} //namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_TC_UTILITIES_H
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
INRIA Sophia-Antipolis (France)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
Tangential complex
|
||||||
|
|
||||||
|
This CGAL component provides an implementation of the tangential complex.
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
GPL (v3 or later)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Clément Jamin <clement.jamin.pro@gmail.com>
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
# Created by the script cgal_create_cmake_script
|
||||||
|
# This is the CMake script for compiling a CGAL application.
|
||||||
|
|
||||||
|
|
||||||
|
project( Tangential_complex_test )
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 2.6.2)
|
||||||
|
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6)
|
||||||
|
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3)
|
||||||
|
cmake_policy(VERSION 2.8.4)
|
||||||
|
else()
|
||||||
|
cmake_policy(VERSION 2.6)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Creates a new CMake option, turned ON by default
|
||||||
|
option(ACTIVATE_MSVC_PRECOMPILED_HEADERS
|
||||||
|
"Activate precompiled headers in MSVC"
|
||||||
|
OFF)
|
||||||
|
|
||||||
|
# Macro to add precompiled headers for MSVC
|
||||||
|
# This function does two things:
|
||||||
|
# 1. Enable precompiled headers on each file which is listed in "SourcesVar".
|
||||||
|
# 2. Add the content of "PrecompiledSource" (e.g. "StdAfx.cpp") to "SourcesVar".
|
||||||
|
MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
|
||||||
|
IF(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS)
|
||||||
|
GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
|
||||||
|
SET(Sources ${${SourcesVar}})
|
||||||
|
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
|
||||||
|
PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\"")
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(${Sources}
|
||||||
|
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeaders}\" /FI\"${PrecompiledHeader}\"")
|
||||||
|
# Add precompiled header to SourcesVar
|
||||||
|
LIST(APPEND ${SourcesVar} ${PrecompiledSource})
|
||||||
|
ENDIF(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS)
|
||||||
|
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
|
||||||
|
|
||||||
|
# The compiler might need more memory because of precompiled headers
|
||||||
|
if(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS AND NOT(MSVC_VERSION LESS 1310))
|
||||||
|
set(CGAL_C_FLAGS "${CGAL_C_FLAGS} /Zm1000")
|
||||||
|
set(CGAL_CXX_FLAGS "${CGAL_CXX_FLAGS} /Zm1000")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(CGAL QUIET COMPONENTS Core )
|
||||||
|
|
||||||
|
if ( CGAL_FOUND )
|
||||||
|
include( ${CGAL_USE_FILE} )
|
||||||
|
|
||||||
|
find_package( TBB QUIET )
|
||||||
|
|
||||||
|
if( TBB_FOUND )
|
||||||
|
include(${TBB_USE_FILE})
|
||||||
|
list(APPEND CGAL_3RD_PARTY_LIBRARIES ${TBB_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
include( CGAL_CreateSingleSourceCGALProgram )
|
||||||
|
|
||||||
|
find_package(Eigen3 3.1.0)
|
||||||
|
if (EIGEN3_FOUND)
|
||||||
|
include( ${EIGEN3_USE_FILE} )
|
||||||
|
include_directories (BEFORE "../../include")
|
||||||
|
include_directories (BEFORE "include")
|
||||||
|
include_directories(../../../Anisotropic_mesh_TC/include)
|
||||||
|
|
||||||
|
set (SOURCE_FILES "test_tangential_complex.cpp")
|
||||||
|
ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" SOURCE_FILES)
|
||||||
|
create_single_source_cgal_program( ${SOURCE_FILES} )
|
||||||
|
|
||||||
|
create_single_source_cgal_program( "aniso_TC.cpp" )
|
||||||
|
create_single_source_cgal_program( "test_utilities.cpp" )
|
||||||
|
|
||||||
|
else()
|
||||||
|
message(STATUS "NOTICE: Some of the executables in this directory need Eigen 3.1 (or greater) and will not be compiled.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
else()
|
||||||
|
message(STATUS "This program requires the CGAL library, and will not be compiled.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
// Build the precompiled headers.
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef STDAFX_H
|
||||||
|
#define STDAFX_H
|
||||||
|
|
||||||
|
// CGAL
|
||||||
|
#include <CGAL/Tangential_complex/config.h>
|
||||||
|
#include <CGAL/Epick_d.h>
|
||||||
|
#include <CGAL/Regular_triangulation_euclidean_traits.h>
|
||||||
|
#include <CGAL/Regular_triangulation.h>
|
||||||
|
#include <CGAL/Delaunay_triangulation.h>
|
||||||
|
#include <CGAL/Tangential_complex/utilities.h>
|
||||||
|
#include <CGAL/Tangential_complex/Point_cloud.h>
|
||||||
|
#include <CGAL/Combination_enumerator.h>
|
||||||
|
|
||||||
|
#endif //STDAFX_H
|
||||||
|
|
@ -0,0 +1,297 @@
|
||||||
|
#include <CGAL/assertions_behaviour.h>
|
||||||
|
#include <CGAL/Epick_d.h>
|
||||||
|
#include <CGAL/Tangential_complex.h>
|
||||||
|
#include <CGAL/Random.h>
|
||||||
|
|
||||||
|
#include "../../test/Tangential_complex/testing_utilities.h"
|
||||||
|
|
||||||
|
#include <CGAL/Metric_field.h> // Anisotropic metrics
|
||||||
|
#include <Metric_field/Euclidean_metric_field.h>
|
||||||
|
#include <Metric_field/Custom_metric_field.h>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
const int k = 2; // intrinsic
|
||||||
|
const int d = 5; // ambiant
|
||||||
|
|
||||||
|
typedef CGAL::Epick_d< CGAL::Dimension_tag<k> > Kk;
|
||||||
|
typedef CGAL::Epick_d< CGAL::Dimension_tag<d> > Kd;
|
||||||
|
typedef Kk::FT FT;
|
||||||
|
typedef Kk::Point_d Point_k;
|
||||||
|
typedef Kd::Point_d Point_d;
|
||||||
|
typedef Kd::Weighted_point_d Weighted_point_d;
|
||||||
|
typedef Kd::Vector_d Vector_d;
|
||||||
|
typedef CGAL::Tangential_complex<Kd,
|
||||||
|
CGAL::Dimension_tag<k>,
|
||||||
|
CGAL::Parallel_tag> TC;
|
||||||
|
|
||||||
|
typedef CGAL::Tangential_complex_::Basis<Kd> Basis;
|
||||||
|
typedef CGAL::Anisotropic_mesh_TC::Metric_base<Kk> Metric;
|
||||||
|
typedef CGAL::Anisotropic_mesh_TC::Metric_field<Kk> Metric_field;
|
||||||
|
|
||||||
|
typedef typename Metric::E_Matrix E_Matrix_k;
|
||||||
|
typedef typename Metric::E_Vector E_Vector_k;
|
||||||
|
typedef Eigen::Matrix<FT, d, 1> E_Vector_d;
|
||||||
|
typedef Eigen::Matrix<FT, d, k> E_Matrix_dk;
|
||||||
|
|
||||||
|
typedef CGAL::Anisotropic_mesh_TC::Euclidean_metric_field<Kk> Euclidean_mf;
|
||||||
|
typedef CGAL::Anisotropic_mesh_TC::Custom_metric_field<Kk> Custom_mf;
|
||||||
|
|
||||||
|
void read_points(std::vector<Point_k>& points,
|
||||||
|
const Kk kerk = Kk())
|
||||||
|
{
|
||||||
|
std::ifstream in("../../../../Anisotropic_mesh_2/examples/Anisotropic_mesh_2/bambimboum.mesh");
|
||||||
|
// std::ifstream in("aniso_regular.mesh");
|
||||||
|
std::string word;
|
||||||
|
int useless, nv, dd;
|
||||||
|
FT x;
|
||||||
|
|
||||||
|
in >> word >> useless; //MeshVersionFormatted i
|
||||||
|
in >> word >> dd; //Dimension d
|
||||||
|
in >> word >> nv;
|
||||||
|
|
||||||
|
assert(dd == Kk::Dimension::value);
|
||||||
|
|
||||||
|
for(int i=0; i<nv; ++i)
|
||||||
|
{
|
||||||
|
std::vector<FT> ids;
|
||||||
|
for(int j=0; j<k; ++j)
|
||||||
|
{
|
||||||
|
in >> x;
|
||||||
|
ids.push_back(x);
|
||||||
|
}
|
||||||
|
in >> useless;
|
||||||
|
points.push_back(kerk.construct_point_d_object()(ids.begin(), ids.begin() + k));
|
||||||
|
|
||||||
|
if(points.size() == 200)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << points.size() << " points" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the corresponding point on the paraboloid (these points will be the
|
||||||
|
// points at which we compute tangent planes)
|
||||||
|
Point_d to_Q(const Point_k& p)
|
||||||
|
{
|
||||||
|
typename Kk::Compute_coordinate_d k_coord = Kk().compute_coordinate_d_object();
|
||||||
|
|
||||||
|
E_Vector_d p_on_Q;
|
||||||
|
for(int i=0; i<k; ++i)
|
||||||
|
p_on_Q(i) = k_coord(p, i);
|
||||||
|
|
||||||
|
int ind = k;
|
||||||
|
for(int i=0; i<k; ++i)
|
||||||
|
for(int j=i; j<k; ++j)
|
||||||
|
p_on_Q(ind++) = k_coord(p,i) * k_coord(p,j);
|
||||||
|
|
||||||
|
return Kd().construct_point_d_object()(d, p_on_Q.data(), p_on_Q.data() + d);
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the corresponding point on the metric manifold (these points will be
|
||||||
|
// the seeds of the global power diagram)
|
||||||
|
Weighted_point_d to_S(const Point_k& p,
|
||||||
|
const Metric& met,
|
||||||
|
const Kd kerd = Kd())
|
||||||
|
{
|
||||||
|
const E_Matrix_k m = met.get_mat();
|
||||||
|
E_Vector_k e_p, p_bar;
|
||||||
|
|
||||||
|
typename Kk::Compute_coordinate_d k_coord = Kk().compute_coordinate_d_object();
|
||||||
|
for(int i=0; i<k; ++i)
|
||||||
|
e_p(i) = k_coord(p, i);
|
||||||
|
|
||||||
|
p_bar = m * e_p;
|
||||||
|
|
||||||
|
E_Vector_d p_on_S;
|
||||||
|
for(int i=0; i<k; ++i)
|
||||||
|
p_on_S(i) = p_bar(i);
|
||||||
|
|
||||||
|
int ind = k;
|
||||||
|
for(int i=0; i<k; ++i)
|
||||||
|
{
|
||||||
|
for(int j=i; j<k; ++j)
|
||||||
|
{
|
||||||
|
if(j==i)
|
||||||
|
p_on_S(ind++) = -0.5*m(i,i);
|
||||||
|
else
|
||||||
|
p_on_S(ind++) = -m(i,j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FT n = p_on_S.norm();
|
||||||
|
FT w = n * n - e_p.transpose() * p_bar;
|
||||||
|
|
||||||
|
return kerd.construct_weighted_point_d_object()
|
||||||
|
(kerd.construct_point_d_object()(d, p_on_S.data(),p_on_S.data()+d), w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void compute_points_in_ambiant_space(std::vector<Point_k> const & points_k,
|
||||||
|
Metric_field const * const mf,
|
||||||
|
std::vector<Point_d>& points_d,
|
||||||
|
std::vector<FT>& weights,
|
||||||
|
Kd const kerd = Kd())
|
||||||
|
{
|
||||||
|
typename Kd::Point_drop_weight_d k_drop_w = kerd.point_drop_weight_d_object();
|
||||||
|
typename Kd::Point_weight_d k_point_weight = kerd.point_weight_d_object();
|
||||||
|
|
||||||
|
for(std::size_t i=0; i<points_k.size(); ++i)
|
||||||
|
{
|
||||||
|
Point_k const & p = points_k[i];
|
||||||
|
Metric met = mf->compute_metric(p);
|
||||||
|
Weighted_point_d wp = to_S(p, met, kerd);
|
||||||
|
points_d.push_back(k_drop_w(wp));
|
||||||
|
weights.push_back(k_point_weight(wp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compute_and_set_tangent_planes(TC& tc,
|
||||||
|
const std::vector<Point_k>& points_k,
|
||||||
|
Kd const kerd = Kd())
|
||||||
|
{
|
||||||
|
typedef TC::TS_container TS_container;
|
||||||
|
typedef TC::OS_container OS_container;
|
||||||
|
|
||||||
|
typename Kd::Compute_coordinate_d coord = kerd.compute_coordinate_d_object();
|
||||||
|
typename Kd::Construct_vector_d constr_vec = kerd.construct_vector_d_object();
|
||||||
|
TS_container tsc;
|
||||||
|
OS_container osc;
|
||||||
|
std::size_t n = tc.number_of_vertices();
|
||||||
|
CGAL_assertion(n == points_k.size());
|
||||||
|
|
||||||
|
for(std::size_t c=0; c<n; ++c)
|
||||||
|
{
|
||||||
|
// origin of the basis is the point moved the paraboloid
|
||||||
|
Point_d origin = to_Q(points_k[c]);
|
||||||
|
|
||||||
|
// compute the tsc; the vectors are given by the partial derivatives
|
||||||
|
// of the parametrization of the paraboloid
|
||||||
|
Basis ts(origin);
|
||||||
|
|
||||||
|
// filling all the vectors at the same time through a (d,k)-matrix
|
||||||
|
E_Matrix_dk ts_m = E_Matrix_dk::Zero();
|
||||||
|
// 'first' part: x y z etc. derivates
|
||||||
|
for(int i=0; i<k; ++i)
|
||||||
|
for(int j=0; j<k; ++j)
|
||||||
|
ts_m(i,j) = (i==j);
|
||||||
|
|
||||||
|
// 'second' part: x² xy xz y² yz z² etc. derivatives
|
||||||
|
int pos = k;
|
||||||
|
for(int i=0; i<k; ++i)
|
||||||
|
{
|
||||||
|
for(int j=i; j<k; ++j)
|
||||||
|
{
|
||||||
|
if(i == j)
|
||||||
|
ts_m(pos, i) = 2*coord(origin, i);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ts_m(pos, i) = coord(origin, j);
|
||||||
|
ts_m(pos, j) = coord(origin, i);
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<k; ++i)
|
||||||
|
{
|
||||||
|
Vector_d v = constr_vec(d, ts_m.col(i).data(), ts_m.col(i).data() + d);
|
||||||
|
ts.push_back(v);
|
||||||
|
}
|
||||||
|
tsc.push_back(CGAL::Tangential_complex_::compute_gram_schmidt_basis(ts, kerd));
|
||||||
|
|
||||||
|
#ifdef CGAL_FIXED_ALPHA_TC
|
||||||
|
// compute the osc
|
||||||
|
Basis os(origin);
|
||||||
|
|
||||||
|
// todo
|
||||||
|
osc.push_back(CGAL::Tangential_complex_::compute_gram_schmidt_basis(os, kerd));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
tc.set_tangent_planes(tsc
|
||||||
|
#ifdef CGAL_FIXED_ALPHA_TC
|
||||||
|
, osc
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// translate the connectivity of the stars back to the original points
|
||||||
|
void export_complex_in_origin_space(const TC& tc,
|
||||||
|
const TC::Simplicial_complex& complex,
|
||||||
|
const std::vector<Point_k>& points_k)
|
||||||
|
{
|
||||||
|
std::ofstream out("aniso.off");
|
||||||
|
std::stringstream output;
|
||||||
|
std::size_t num_simplices;
|
||||||
|
|
||||||
|
typename Kk::Compute_coordinate_d k_coord = Kk().compute_coordinate_d_object();
|
||||||
|
|
||||||
|
|
||||||
|
for(std::size_t i=0; i<points_k.size(); ++i)
|
||||||
|
{
|
||||||
|
const Point_k& p = points_k[i];
|
||||||
|
output << k_coord(p, 0) << " " << k_coord(p, 1) << " 0" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
tc.export_simplices_to_off(complex, output, num_simplices);
|
||||||
|
|
||||||
|
out << "OFF" << std::endl;
|
||||||
|
out << points_k.size() << " " << num_simplices << " 0" << std::endl;
|
||||||
|
out << output.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void make_tc(std::vector<Point_k>& points_k,
|
||||||
|
Metric_field const * const mf)
|
||||||
|
{
|
||||||
|
Kd ker_d;
|
||||||
|
|
||||||
|
std::vector<Point_d> points_d;
|
||||||
|
std::vector<FT> weights;
|
||||||
|
compute_points_in_ambiant_space(points_k, mf, points_d, weights, ker_d);
|
||||||
|
|
||||||
|
TC tc(points_d.begin(), points_d.end(), 0./*sparsity*/, k /*intr dim*/, ker_d);
|
||||||
|
tc.set_weights(weights);
|
||||||
|
compute_and_set_tangent_planes(tc, points_k, ker_d);
|
||||||
|
|
||||||
|
tc.compute_tangential_complex();
|
||||||
|
|
||||||
|
TC::Simplicial_complex complex;
|
||||||
|
int max_dim = tc.export_TC(complex, false);
|
||||||
|
complex.display_stats();
|
||||||
|
{
|
||||||
|
std::ofstream off_stream("aniso_alpha_complex.off");
|
||||||
|
tc.export_to_off(complex, off_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collapse
|
||||||
|
complex.collapse(max_dim);
|
||||||
|
{
|
||||||
|
std::ofstream off_stream("aniso_after_collapse.off");
|
||||||
|
tc.export_to_off(complex, off_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t num_wrong_dim_simplices, num_wrong_number_of_cofaces;
|
||||||
|
bool pure_manifold = complex.is_pure_manifold(k, false, 1,
|
||||||
|
&num_wrong_dim_simplices,
|
||||||
|
&num_wrong_number_of_cofaces);
|
||||||
|
complex.display_stats();
|
||||||
|
|
||||||
|
export_complex_in_origin_space(tc, complex, points_k);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
CGAL::default_random = CGAL::Random();
|
||||||
|
std::vector<Point_k> points_k;
|
||||||
|
|
||||||
|
//Custom_mf* mf = new Custom_mf();
|
||||||
|
Euclidean_mf* mf = new Euclidean_mf();
|
||||||
|
|
||||||
|
read_points(points_k);
|
||||||
|
make_tc(points_k, mf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
//#undef CGAL_LINKED_WITH_TBB // CJTODO TEMP
|
||||||
|
|
||||||
|
// Without TBB_USE_THREADING_TOOL Intel Inspector XE will report false positives in Intel TBB
|
||||||
|
// (http://software.intel.com/en-us/articles/compiler-settings-for-threading-error-analysis-in-intel-inspector-xe/)
|
||||||
|
#ifdef _DEBUG
|
||||||
|
# define TBB_USE_THREADING_TOOL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <CGAL/assertions_behaviour.h>
|
||||||
|
#include <CGAL/Epick_d.h>
|
||||||
|
#include <CGAL/Tangential_complex.h>
|
||||||
|
#include <CGAL/Random.h>
|
||||||
|
#include <CGAL/Mesh_3/Profiling_tools.h>
|
||||||
|
|
||||||
|
#include "testing_utilities.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
# include <tbb/task_scheduler_init.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//=============== Constants =================
|
||||||
|
const double INPUT_SPARSITY = 0.05;
|
||||||
|
#ifdef _DEBUG
|
||||||
|
const int NUM_POINTS = 50;
|
||||||
|
#else
|
||||||
|
const int NUM_POINTS = 30000;
|
||||||
|
#endif
|
||||||
|
//===========================================
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#if defined(CHECK_MEMORY_LEAKS_ON_MSVC) && defined(_MSC_VER)
|
||||||
|
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
|
||||||
|
#endif
|
||||||
|
CGAL::set_error_behaviour(CGAL::ABORT);
|
||||||
|
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
# ifdef _DEBUG
|
||||||
|
tbb::task_scheduler_init init(1);
|
||||||
|
# else
|
||||||
|
tbb::task_scheduler_init init(10);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const int INTRINSIC_DIMENSION = 3;
|
||||||
|
const int AMBIENT_DIMENSION = 9;
|
||||||
|
|
||||||
|
typedef CGAL::Epick_d<CGAL::Dimension_tag<AMBIENT_DIMENSION> > Kernel;
|
||||||
|
typedef Kernel::FT FT;
|
||||||
|
typedef Kernel::Point_d Point;
|
||||||
|
typedef CGAL::Tangential_complex<
|
||||||
|
Kernel, CGAL::Dimension_tag<INTRINSIC_DIMENSION>,
|
||||||
|
CGAL::Parallel_tag> TC;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
bool stop = false;
|
||||||
|
//for ( ; !stop ; ++i)
|
||||||
|
{
|
||||||
|
Kernel k;
|
||||||
|
Wall_clock_timer t;
|
||||||
|
CGAL::default_random = CGAL::Random(i);
|
||||||
|
std::cerr << "Random seed = " << i << std::endl;
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_PROFILING
|
||||||
|
Wall_clock_timer t_gen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*std::vector<Point> points =
|
||||||
|
//generate_points_on_circle_2<Kernel>(NUM_POINTS, 3.);
|
||||||
|
//generate_points_on_moment_curve<Kernel>(NUM_POINTS, AMBIENT_DIMENSION, 0., 1.);
|
||||||
|
//generate_points_on_plane<Kernel>(NUM_POINTS);
|
||||||
|
//generate_points_on_sphere_3<Kernel>(NUM_POINTS, 3.0);
|
||||||
|
//generate_points_on_sphere_d<Kernel>(NUM_POINTS, AMBIENT_DIMENSION, 3.0);
|
||||||
|
//generate_points_on_klein_bottle_3D<Kernel>(NUM_POINTS, 4., 3.);
|
||||||
|
generate_points_on_klein_bottle_4D<Kernel>(NUM_POINTS, 4., 3.);
|
||||||
|
//generate_points_on_klein_bottle_variant_5D<Kernel>(NUM_POINTS, 4., 3.);*/
|
||||||
|
|
||||||
|
// LOAD FROM A FILE
|
||||||
|
std::vector<Point> points;
|
||||||
|
load_points_from_file<Point>(
|
||||||
|
"data/SO3_10000.txt", std::back_inserter(points));
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_PROFILING
|
||||||
|
std::cerr << "Point set generated in " << t_gen.elapsed()
|
||||||
|
<< " seconds." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::size_t num_points_before = points.size();
|
||||||
|
points = sparsify_point_set(
|
||||||
|
k, points, FT(INPUT_SPARSITY)*FT(INPUT_SPARSITY));
|
||||||
|
std::cerr << "Number of points before/after sparsification: "
|
||||||
|
<< num_points_before << " / " << points.size() << std::endl;
|
||||||
|
|
||||||
|
TC tc(points.begin(), points.end(), INPUT_SPARSITY, INTRINSIC_DIMENSION, k);
|
||||||
|
double init_time = t.elapsed(); t.reset();
|
||||||
|
|
||||||
|
tc.compute_tangential_complex();
|
||||||
|
double computation_time = t.elapsed(); t.reset();
|
||||||
|
|
||||||
|
if (ambient_dim <= 4)
|
||||||
|
tc.check_if_all_simplices_are_in_the_ambient_delaunay();
|
||||||
|
|
||||||
|
double export_before_time = -1.;
|
||||||
|
if (INTRINSIC_DIMENSION <= 3)
|
||||||
|
{
|
||||||
|
t.reset();
|
||||||
|
std::stringstream output_filename;
|
||||||
|
output_filename << "output/test_tc_" << INTRINSIC_DIMENSION
|
||||||
|
<< "_in_R" << AMBIENT_DIMENSION << "_BEFORE_FIX.off";
|
||||||
|
std::ofstream off_stream(output_filename.str().c_str());
|
||||||
|
tc.export_to_off(off_stream, true);
|
||||||
|
export_before_time = t.elapsed(); t.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
t.reset();
|
||||||
|
unsigned int num_fix_steps;
|
||||||
|
std::size_t initial_num_inconsistent_local_tr;
|
||||||
|
std::size_t best_num_inconsistent_local_tr;
|
||||||
|
std::size_t final_num_inconsistent_local_tr;
|
||||||
|
CGAL::Fix_inconsistencies_status fix_ret =
|
||||||
|
tc.fix_inconsistencies_using_perturbation(
|
||||||
|
num_fix_steps, initial_num_inconsistent_local_tr,
|
||||||
|
best_num_inconsistent_local_tr, final_num_inconsistent_local_tr, 1000.);
|
||||||
|
double fix_time = t.elapsed(); t.reset();
|
||||||
|
|
||||||
|
double export_after_time = -1.;
|
||||||
|
if (INTRINSIC_DIMENSION <= 3)
|
||||||
|
{
|
||||||
|
t.reset();
|
||||||
|
std::stringstream output_filename;
|
||||||
|
output_filename << "output/test_tc_" << INTRINSIC_DIMENSION
|
||||||
|
<< "_in_R" << AMBIENT_DIMENSION << "_AFTER_FIX.off";
|
||||||
|
std::ofstream off_stream(output_filename.str().c_str());
|
||||||
|
tc.export_to_off(off_stream, true);
|
||||||
|
export_after_time = t.elapsed(); t.reset();
|
||||||
|
}
|
||||||
|
/*else
|
||||||
|
tc.number_of_inconsistent_simplices();*/
|
||||||
|
|
||||||
|
|
||||||
|
std::cerr << std::endl
|
||||||
|
<< "================================================" << std::endl
|
||||||
|
<< "Number of vertices: " << tc.number_of_vertices() << std::endl
|
||||||
|
<< "Computation times (seconds): " << std::endl
|
||||||
|
<< " * Tangential complex: " << init_time + computation_time
|
||||||
|
<< std::endl
|
||||||
|
<< " - Init + kd-tree = " << init_time << std::endl
|
||||||
|
<< " - TC computation = " << computation_time << std::endl
|
||||||
|
<< " * Export to OFF (before fix): " << export_before_time << std::endl
|
||||||
|
<< " * Fix inconsistencies: " << fix_time
|
||||||
|
<< " (" << num_fix_steps << " steps) ==> "
|
||||||
|
<< (fix_ret == CGAL::TC_FIXED ? "FIXED" : "NOT fixed") << std::endl
|
||||||
|
<< " * Export to OFF (after fix): " << export_after_time << std::endl
|
||||||
|
<< "================================================" << std::endl
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
|
||||||
|
// Without TBB_USE_THREADING_TOOL Intel Inspector XE will report false positives in Intel TBB
|
||||||
|
// (http://software.intel.com/en-us/articles/compiler-settings-for-threading-error-analysis-in-intel-inspector-xe/)
|
||||||
|
#ifdef _DEBUG
|
||||||
|
# define TBB_USE_THREADING_TOOL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <CGAL/Epick_d.h>
|
||||||
|
#include <CGAL/Tangential_complex/utilities.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace CGAL::Tangential_complex_;
|
||||||
|
|
||||||
|
void test_does_voronoi_face_and_alpha_tangent_subspace_intersect()
|
||||||
|
{
|
||||||
|
typedef CGAL::Epick_d<CGAL::Dimension_tag<2> > K;
|
||||||
|
typedef K::Point_d Pt;
|
||||||
|
typedef K::Vector_d Vec;
|
||||||
|
std::vector<std::size_t> P;
|
||||||
|
std::vector<std::size_t> Q;
|
||||||
|
std::vector<Vec> osb;
|
||||||
|
|
||||||
|
K k;
|
||||||
|
|
||||||
|
std::vector<Pt> points;
|
||||||
|
points.push_back(Pt(0.02, -0.03));
|
||||||
|
points.push_back(Pt(0.005, 2.3));
|
||||||
|
points.push_back(Pt(4.5, 1.12));
|
||||||
|
points.push_back(Pt(-3.5, 1.02));
|
||||||
|
|
||||||
|
P.push_back(0);
|
||||||
|
P.push_back(1);
|
||||||
|
|
||||||
|
Q.push_back(2);
|
||||||
|
Q.push_back(3);
|
||||||
|
|
||||||
|
osb.push_back(Vec(0.01, 0.995));
|
||||||
|
|
||||||
|
assert(does_voronoi_face_and_fixed_alpha_tangent_subspace_intersect(
|
||||||
|
points, 0, P, Q, osb, 0.0, k) == false);
|
||||||
|
|
||||||
|
assert(does_voronoi_face_and_fixed_alpha_tangent_subspace_intersect(
|
||||||
|
points, 0, P, Q, osb, 0.5, k) == false);
|
||||||
|
|
||||||
|
assert(does_voronoi_face_and_fixed_alpha_tangent_subspace_intersect(
|
||||||
|
points, 0, P, Q, osb, 1.0, k) == false);
|
||||||
|
|
||||||
|
assert(does_voronoi_face_and_fixed_alpha_tangent_subspace_intersect(
|
||||||
|
points, 0, P, Q, osb, 1.5, k) == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test_does_voronoi_face_and_alpha_tangent_subspace_intersect();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,870 @@
|
||||||
|
// Copyright (c) 2014 INRIA Sophia-Antipolis (France).
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Clement Jamin
|
||||||
|
//
|
||||||
|
//******************************************************************************
|
||||||
|
// File Description :
|
||||||
|
//
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
#ifndef CGAL_TC_TEST_TEST_UTILITIES_H
|
||||||
|
#define CGAL_TC_TEST_TEST_UTILITIES_H
|
||||||
|
|
||||||
|
#include <CGAL/Random.h>
|
||||||
|
#include <CGAL/point_generators_2.h>
|
||||||
|
#include <CGAL/point_generators_3.h>
|
||||||
|
#include <CGAL/point_generators_d.h>
|
||||||
|
#include <CGAL/function_objects.h>
|
||||||
|
#include <CGAL/Tangential_complex/Point_cloud.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
// Actually, this is very slow because the "m_points_ds->insert"
|
||||||
|
// cleans the tree, which is thus built at each query_ANN call
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
template <typename Kernel, typename Point_container>
|
||||||
|
class Point_sparsifier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
typedef typename Point_container::value_type Point;
|
||||||
|
typedef typename CGAL::Tangential_complex_::Point_cloud_data_structure<
|
||||||
|
Kernel, Point_container> Points_ds;
|
||||||
|
typedef typename Points_ds::KNS_range KNS_range;
|
||||||
|
|
||||||
|
// We can't instantiate m_points_ds right now since it requires that
|
||||||
|
// points is not empty (which be the case here)
|
||||||
|
Point_sparsifier(Point_container &points,
|
||||||
|
FT sparsity = FT(0.05*0.05))
|
||||||
|
: m_points(points), m_sparsity(sparsity), m_points_ds(NULL)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool try_to_insert_point(const Point &p)
|
||||||
|
{
|
||||||
|
if (m_points_ds == NULL)
|
||||||
|
{
|
||||||
|
m_points.push_back(p);
|
||||||
|
m_points_ds = new Points_ds(m_points);
|
||||||
|
m_points_ds->insert(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KNS_range kns_range = m_points_ds->query_ANN(p, 1, false);
|
||||||
|
if (kns_range.begin()->second >= m_sparsity)
|
||||||
|
{
|
||||||
|
m_points.push_back(p);
|
||||||
|
m_points_ds->insert(m_points.size() - 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Point_container & m_points;
|
||||||
|
Points_ds * m_points_ds;
|
||||||
|
FT m_sparsity;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// construct_point: dim 2
|
||||||
|
template <typename Kernel>
|
||||||
|
typename Kernel::Point_d construct_point(
|
||||||
|
const Kernel &k,
|
||||||
|
typename Kernel::FT x1, typename Kernel::FT x2)
|
||||||
|
{
|
||||||
|
typename Kernel::FT tab[2];
|
||||||
|
tab[0] = x1; tab[1] = x2;
|
||||||
|
return k.construct_point_d_object()(2, &tab[0], &tab[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct_point: dim 3
|
||||||
|
template <typename Kernel>
|
||||||
|
typename Kernel::Point_d construct_point(
|
||||||
|
const Kernel &k,
|
||||||
|
typename Kernel::FT x1, typename Kernel::FT x2, typename Kernel::FT x3)
|
||||||
|
{
|
||||||
|
typename Kernel::FT tab[3];
|
||||||
|
tab[0] = x1; tab[1] = x2; tab[2] = x3;
|
||||||
|
return k.construct_point_d_object()(3, &tab[0], &tab[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct_point: dim 4
|
||||||
|
template <typename Kernel>
|
||||||
|
typename Kernel::Point_d construct_point(
|
||||||
|
const Kernel &k,
|
||||||
|
typename Kernel::FT x1, typename Kernel::FT x2, typename Kernel::FT x3,
|
||||||
|
typename Kernel::FT x4)
|
||||||
|
{
|
||||||
|
typename Kernel::FT tab[4];
|
||||||
|
tab[0] = x1; tab[1] = x2; tab[2] = x3; tab[3] = x4;
|
||||||
|
return k.construct_point_d_object()(4, &tab[0], &tab[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct_point: dim 5
|
||||||
|
template <typename Kernel>
|
||||||
|
typename Kernel::Point_d construct_point(
|
||||||
|
const Kernel &k,
|
||||||
|
typename Kernel::FT x1, typename Kernel::FT x2, typename Kernel::FT x3,
|
||||||
|
typename Kernel::FT x4, typename Kernel::FT x5)
|
||||||
|
{
|
||||||
|
typename Kernel::FT tab[5];
|
||||||
|
tab[0] = x1; tab[1] = x2; tab[2] = x3; tab[3] = x4; tab[4] = x5;
|
||||||
|
return k.construct_point_d_object()(5, &tab[0], &tab[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// construct_point: dim 6
|
||||||
|
template <typename Kernel>
|
||||||
|
typename Kernel::Point_d construct_point(
|
||||||
|
const Kernel &k,
|
||||||
|
typename Kernel::FT x1, typename Kernel::FT x2, typename Kernel::FT x3,
|
||||||
|
typename Kernel::FT x4, typename Kernel::FT x5, typename Kernel::FT x6)
|
||||||
|
{
|
||||||
|
typename Kernel::FT tab[6];
|
||||||
|
tab[0] = x1; tab[1] = x2; tab[2] = x3; tab[3] = x4; tab[4] = x5; tab[5] = x6;
|
||||||
|
return k.construct_point_d_object()(6, &tab[0], &tab[6]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Kernel, typename Point_container>
|
||||||
|
std::vector<typename Point_container::value_type>
|
||||||
|
sparsify_point_set(
|
||||||
|
const Kernel &k, Point_container const& input_pts,
|
||||||
|
typename Kernel::FT min_squared_dist)
|
||||||
|
{
|
||||||
|
typedef typename CGAL::Tangential_complex_::Point_cloud_data_structure<
|
||||||
|
Kernel, Point_container> Points_ds;
|
||||||
|
typedef typename Points_ds::INS_iterator INS_iterator;
|
||||||
|
typedef typename Points_ds::INS_range INS_range;
|
||||||
|
|
||||||
|
typename Kernel::Squared_distance_d sqdist = k.squared_distance_d_object();
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_PROFILING
|
||||||
|
Wall_clock_timer t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Create the output container
|
||||||
|
std::vector<typename Point_container::value_type> output;
|
||||||
|
|
||||||
|
Points_ds points_ds(input_pts);
|
||||||
|
|
||||||
|
std::vector<bool> dropped_points(input_pts.size(), false);
|
||||||
|
|
||||||
|
// Parse the following points, and add them if they are not too close to
|
||||||
|
// the other points
|
||||||
|
std::size_t pt_idx = 0;
|
||||||
|
for (typename Point_container::const_iterator it_pt = input_pts.begin() ;
|
||||||
|
it_pt != input_pts.end();
|
||||||
|
++it_pt, ++pt_idx)
|
||||||
|
{
|
||||||
|
if (dropped_points[pt_idx])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
output.push_back(*it_pt);
|
||||||
|
|
||||||
|
INS_range ins_range = points_ds.query_incremental_ANN(*it_pt);
|
||||||
|
|
||||||
|
// Drop it if there is another point that:
|
||||||
|
// - is closer that min_squared_dist
|
||||||
|
// - and has a higher index
|
||||||
|
for (INS_iterator nn_it = ins_range.begin() ;
|
||||||
|
nn_it != ins_range.end() ;
|
||||||
|
++nn_it)
|
||||||
|
{
|
||||||
|
std::size_t neighbor_point_idx = nn_it->first;
|
||||||
|
typename Kernel::FT sq_dist = nn_it->second;
|
||||||
|
// The neighbor is too close, we drop the neighbor
|
||||||
|
if (sq_dist < min_squared_dist)
|
||||||
|
dropped_points[neighbor_point_idx] = true;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_PROFILING
|
||||||
|
std::cerr << "Point set sparsified in " << t.elapsed()
|
||||||
|
<< " seconds." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Point, typename OutputIterator>
|
||||||
|
bool load_points_from_file(
|
||||||
|
const std::string &filename, OutputIterator points,
|
||||||
|
std::size_t only_first_n_points = std::numeric_limits<std::size_t>::max())
|
||||||
|
{
|
||||||
|
std::ifstream in(filename);
|
||||||
|
if (!in.is_open())
|
||||||
|
{
|
||||||
|
std::cerr << "Could not open '" << filename << "'" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point p;
|
||||||
|
int dim_from_file;
|
||||||
|
in >> dim_from_file;
|
||||||
|
|
||||||
|
std::size_t i = 0;
|
||||||
|
while(i < only_first_n_points && in >> p)
|
||||||
|
{
|
||||||
|
*points++ = p;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_VERBOSE
|
||||||
|
std::cerr << "'" << filename << "' loaded." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Kernel>
|
||||||
|
std::vector<typename Kernel::Point_d> generate_points_on_plane(
|
||||||
|
std::size_t num_points, int intrinsic_dim, int ambient_dim)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
Kernel k;
|
||||||
|
CGAL::Random rng;
|
||||||
|
std::vector<Point> points;
|
||||||
|
points.reserve(num_points);
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
Point_sparsifier<Kernel, std::vector<Point> > sparsifier(points);
|
||||||
|
#endif
|
||||||
|
for (std::size_t i = 0 ; i < num_points ; )
|
||||||
|
{
|
||||||
|
std::vector<FT> pt(ambient_dim, FT(0));
|
||||||
|
for (int j = 0 ; j < intrinsic_dim ; ++j)
|
||||||
|
pt[j] = rng.get_double(-5., 5.);
|
||||||
|
/*for (int j = intrinsic_dim ; j < ambient_dim ; ++j)
|
||||||
|
pt[j] = rng.get_double(-0.01, 0.01);*/
|
||||||
|
|
||||||
|
Point p = k.construct_point_d_object()(ambient_dim, pt.begin(), pt.end());
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
if (sparsifier.try_to_insert_point(p))
|
||||||
|
++i;
|
||||||
|
#else
|
||||||
|
points.push_back(p);
|
||||||
|
++i;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Kernel>
|
||||||
|
std::vector<typename Kernel::Point_d> generate_points_on_moment_curve(
|
||||||
|
std::size_t num_points, int dim,
|
||||||
|
typename Kernel::FT min_x , typename Kernel::FT max_x)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
Kernel k;
|
||||||
|
CGAL::Random rng;
|
||||||
|
std::vector<Point> points;
|
||||||
|
points.reserve(num_points);
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
Point_sparsifier<Kernel, std::vector<Point> > sparsifier(points);
|
||||||
|
#endif
|
||||||
|
for (std::size_t i = 0 ; i < num_points ; )
|
||||||
|
{
|
||||||
|
FT x = rng.get_double(min_x, max_x);
|
||||||
|
std::vector<FT> coords;
|
||||||
|
coords.reserve(dim);
|
||||||
|
for (int p = 1 ; p <= dim ; ++p)
|
||||||
|
coords.push_back(std::pow(CGAL::to_double(x), p));
|
||||||
|
Point p = k.construct_point_d_object()(
|
||||||
|
dim, coords.begin(), coords.end());
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
if (sparsifier.try_to_insert_point(p))
|
||||||
|
++i;
|
||||||
|
#else
|
||||||
|
points.push_back(p);
|
||||||
|
++i;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// R = big radius, r = small radius
|
||||||
|
template <typename Kernel/*, typename TC_basis*/>
|
||||||
|
std::vector<typename Kernel::Point_d> generate_points_on_torus_3D(
|
||||||
|
std::size_t num_points, double R, double r, bool uniform = false
|
||||||
|
/*, std::vector<TC_basis> *p_tangent_planes = NULL*/)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
typedef typename Kernel::Vector_d Vector;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
Kernel k;
|
||||||
|
CGAL::Random rng;
|
||||||
|
|
||||||
|
//typename Kernel::Construct_vector_d cstr_vec = k.construct_vector_d_object();
|
||||||
|
|
||||||
|
// if uniform
|
||||||
|
std::size_t num_lines = (std::size_t)sqrt(num_points);
|
||||||
|
std::size_t num_cols = num_points/num_lines + 1;
|
||||||
|
|
||||||
|
std::vector<Point> points;
|
||||||
|
points.reserve(num_points);
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
Point_sparsifier<Kernel, std::vector<Point> > sparsifier(points);
|
||||||
|
#endif
|
||||||
|
for (std::size_t i = 0 ; i < num_points ; )
|
||||||
|
{
|
||||||
|
FT u, v;
|
||||||
|
if (uniform)
|
||||||
|
{
|
||||||
|
std::size_t k1 = i / num_lines;
|
||||||
|
std::size_t k2 = i % num_lines;
|
||||||
|
u = 6.2832 * k1 / num_lines;
|
||||||
|
v = 6.2832 * k2 / num_lines;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u = rng.get_double(0, 6.2832);
|
||||||
|
v = rng.get_double(0, 6.2832);
|
||||||
|
}
|
||||||
|
double tmp = cos(u/2)*sin(v) - sin(u/2)*sin(2.*v);
|
||||||
|
Point p = construct_point(k,
|
||||||
|
(R + r * std::cos(u)) * std::cos(v),
|
||||||
|
(R + r * std::cos(u)) * std::sin(v),
|
||||||
|
r * std::sin(u));
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
if (sparsifier.try_to_insert_point(p))
|
||||||
|
++i;
|
||||||
|
#else
|
||||||
|
points.push_back(p);
|
||||||
|
++i;
|
||||||
|
#endif
|
||||||
|
/*if (p_tangent_planes)
|
||||||
|
{
|
||||||
|
TC_basis tp(p);
|
||||||
|
tp.push_back(cstr_vec(
|
||||||
|
-r * std::cos(v) * std::sin(u),
|
||||||
|
-r * std::sin(v) * std::sin(u),
|
||||||
|
r * std::cos(u)));
|
||||||
|
tp.push_back(cstr_vec(
|
||||||
|
-(R + r * std::cos(u)) * std::sin(v),
|
||||||
|
(R + r * std::cos(u)) * std::cos(v),
|
||||||
|
0));
|
||||||
|
p_tangent_planes->push_back(
|
||||||
|
CGAL::Tangential_complex_::compute_gram_schmidt_basis(sp, k));
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Kernel, typename OutputIterator>
|
||||||
|
static void generate_uniform_points_on_torus_d(
|
||||||
|
const Kernel &k, int dim, std::size_t num_slices,
|
||||||
|
OutputIterator out,
|
||||||
|
double radius_noise_percentage = 0.,
|
||||||
|
std::vector<typename Kernel::FT> current_point = std::vector<typename Kernel::FT>())
|
||||||
|
{
|
||||||
|
static CGAL::Random rng;
|
||||||
|
if (current_point.size() == 2*dim)
|
||||||
|
{
|
||||||
|
*out++ = k.construct_point_d_object()(
|
||||||
|
static_cast<int>(current_point.size()),
|
||||||
|
current_point.begin(), current_point.end());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (std::size_t slice_idx = 0 ; slice_idx < num_slices ; ++slice_idx)
|
||||||
|
{
|
||||||
|
double radius_noise_ratio = 1.;
|
||||||
|
if (radius_noise_percentage > 0.)
|
||||||
|
{
|
||||||
|
radius_noise_ratio = rng.get_double(
|
||||||
|
(100. - radius_noise_percentage)/100.,
|
||||||
|
(100. + radius_noise_percentage)/100.);
|
||||||
|
}
|
||||||
|
std::vector<typename Kernel::FT> cp2 = current_point;
|
||||||
|
FT alpha = 6.2832 * slice_idx / num_slices;
|
||||||
|
cp2.push_back(radius_noise_ratio*std::cos(alpha));
|
||||||
|
cp2.push_back(radius_noise_ratio*std::sin(alpha));
|
||||||
|
generate_uniform_points_on_torus_d(
|
||||||
|
k, dim, num_slices, out, radius_noise_percentage, cp2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Kernel>
|
||||||
|
std::vector<typename Kernel::Point_d> generate_points_on_torus_d(
|
||||||
|
std::size_t num_points, int dim, bool uniform = false,
|
||||||
|
double radius_noise_percentage = 0.)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
Kernel k;
|
||||||
|
static CGAL::Random rng;
|
||||||
|
|
||||||
|
std::vector<Point> points;
|
||||||
|
points.reserve(num_points);
|
||||||
|
if (uniform)
|
||||||
|
{
|
||||||
|
std::size_t num_slices = (std::size_t)std::pow(num_points, 1./dim);
|
||||||
|
generate_uniform_points_on_torus_d(
|
||||||
|
k, dim, num_slices, std::back_inserter(points), radius_noise_percentage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
Point_sparsifier<Kernel, std::vector<Point> > sparsifier(points);
|
||||||
|
#endif
|
||||||
|
for (std::size_t i = 0 ; i < num_points ; )
|
||||||
|
{
|
||||||
|
double radius_noise_ratio = 1.;
|
||||||
|
if (radius_noise_percentage > 0.)
|
||||||
|
{
|
||||||
|
radius_noise_ratio = rng.get_double(
|
||||||
|
(100. - radius_noise_percentage)/100.,
|
||||||
|
(100. + radius_noise_percentage)/100.);
|
||||||
|
}
|
||||||
|
std::vector<typename Kernel::FT> pt;
|
||||||
|
pt.reserve(dim*2);
|
||||||
|
for (int curdim = 0 ; curdim < dim ; ++curdim)
|
||||||
|
{
|
||||||
|
FT alpha = rng.get_double(0, 6.2832);
|
||||||
|
pt.push_back(radius_noise_ratio*std::cos(alpha));
|
||||||
|
pt.push_back(radius_noise_ratio*std::sin(alpha));
|
||||||
|
}
|
||||||
|
|
||||||
|
Point p = k.construct_point_d_object()(pt.begin(), pt.end());
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
if (sparsifier.try_to_insert_point(p))
|
||||||
|
++i;
|
||||||
|
#else
|
||||||
|
points.push_back(p);
|
||||||
|
++i;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Kernel>
|
||||||
|
std::vector<typename Kernel::Point_d> generate_points_on_sphere_d(
|
||||||
|
std::size_t num_points, int dim, double radius,
|
||||||
|
double radius_noise_percentage = 0.)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
Kernel k;
|
||||||
|
CGAL::Random rng;
|
||||||
|
CGAL::Random_points_on_sphere_d<Point> generator(dim, radius);
|
||||||
|
std::vector<Point> points;
|
||||||
|
points.reserve(num_points);
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
Point_sparsifier<Kernel, std::vector<Point> > sparsifier(points);
|
||||||
|
#endif
|
||||||
|
for (std::size_t i = 0 ; i < num_points ; )
|
||||||
|
{
|
||||||
|
Point p = *generator++;
|
||||||
|
if (radius_noise_percentage > 0.)
|
||||||
|
{
|
||||||
|
double radius_noise_ratio = rng.get_double(
|
||||||
|
(100. - radius_noise_percentage)/100.,
|
||||||
|
(100. + radius_noise_percentage)/100.);
|
||||||
|
|
||||||
|
typename Kernel::Point_to_vector_d k_pt_to_vec =
|
||||||
|
k.point_to_vector_d_object();
|
||||||
|
typename Kernel::Vector_to_point_d k_vec_to_pt =
|
||||||
|
k.vector_to_point_d_object();
|
||||||
|
typename Kernel::Scaled_vector_d k_scaled_vec =
|
||||||
|
k.scaled_vector_d_object();
|
||||||
|
p = k_vec_to_pt(k_scaled_vec(k_pt_to_vec(p), radius_noise_ratio));
|
||||||
|
}
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
if (sparsifier.try_to_insert_point(p))
|
||||||
|
++i;
|
||||||
|
#else
|
||||||
|
points.push_back(p);
|
||||||
|
++i;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Kernel>
|
||||||
|
std::vector<typename Kernel::Point_d> generate_points_on_two_spheres_d(
|
||||||
|
std::size_t num_points, int dim, double radius,
|
||||||
|
double distance_between_centers, double radius_noise_percentage = 0.)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
typedef typename Kernel::Vector_d Vector;
|
||||||
|
Kernel k;
|
||||||
|
CGAL::Random rng;
|
||||||
|
CGAL::Random_points_on_sphere_d<Point> generator(dim, radius);
|
||||||
|
std::vector<Point> points;
|
||||||
|
points.reserve(num_points);
|
||||||
|
|
||||||
|
std::vector<FT> t(dim, FT(0));
|
||||||
|
t[0] = distance_between_centers;
|
||||||
|
Vector c1_to_c2(t.begin(), t.end());
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
Point_sparsifier<Kernel, std::vector<Point> > sparsifier(points);
|
||||||
|
#endif
|
||||||
|
for (std::size_t i = 0 ; i < num_points ; )
|
||||||
|
{
|
||||||
|
Point p = *generator++;
|
||||||
|
if (radius_noise_percentage > 0.)
|
||||||
|
{
|
||||||
|
double radius_noise_ratio = rng.get_double(
|
||||||
|
(100. - radius_noise_percentage)/100.,
|
||||||
|
(100. + radius_noise_percentage)/100.);
|
||||||
|
|
||||||
|
typename Kernel::Point_to_vector_d k_pt_to_vec =
|
||||||
|
k.point_to_vector_d_object();
|
||||||
|
typename Kernel::Vector_to_point_d k_vec_to_pt =
|
||||||
|
k.vector_to_point_d_object();
|
||||||
|
typename Kernel::Scaled_vector_d k_scaled_vec =
|
||||||
|
k.scaled_vector_d_object();
|
||||||
|
p = k_vec_to_pt(k_scaled_vec(k_pt_to_vec(p), radius_noise_ratio));
|
||||||
|
}
|
||||||
|
|
||||||
|
typename Kernel::Translated_point_d k_transl =
|
||||||
|
k.translated_point_d_object();
|
||||||
|
Point p2 = k_transl(p, c1_to_c2);
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
if (sparsifier.try_to_insert_point(p))
|
||||||
|
++i;
|
||||||
|
if (sparsifier.try_to_insert_point(p2))
|
||||||
|
++i;
|
||||||
|
#else
|
||||||
|
points.push_back(p);
|
||||||
|
points.push_back(p2);
|
||||||
|
i += 2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Product of a 3-sphere and a circle => d = 3 / D = 5
|
||||||
|
template <typename Kernel>
|
||||||
|
std::vector<typename Kernel::Point_d> generate_points_on_3sphere_and_circle(
|
||||||
|
std::size_t num_points, double sphere_radius)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
typedef typename Kernel::Vector_d Vector;
|
||||||
|
Kernel k;
|
||||||
|
CGAL::Random rng;
|
||||||
|
CGAL::Random_points_on_sphere_d<Point> generator(3, sphere_radius);
|
||||||
|
std::vector<Point> points;
|
||||||
|
points.reserve(num_points);
|
||||||
|
|
||||||
|
typename Kernel::Translated_point_d k_transl =
|
||||||
|
k.translated_point_d_object();
|
||||||
|
typename Kernel::Compute_coordinate_d k_coord =
|
||||||
|
k.compute_coordinate_d_object();
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
Point_sparsifier<Kernel, std::vector<Point> > sparsifier(points);
|
||||||
|
#endif
|
||||||
|
for (std::size_t i = 0 ; i < num_points ; )
|
||||||
|
{
|
||||||
|
Point p_sphere = *generator++; // First 3 coords
|
||||||
|
|
||||||
|
FT alpha = rng.get_double(0, 6.2832);
|
||||||
|
std::vector<FT> pt(5);
|
||||||
|
pt[0] = k_coord(p_sphere, 0);
|
||||||
|
pt[1] = k_coord(p_sphere, 1);
|
||||||
|
pt[2] = k_coord(p_sphere, 2);
|
||||||
|
pt[3] = std::cos(alpha);
|
||||||
|
pt[4] = std::sin(alpha);
|
||||||
|
Point p(pt.begin(), pt.end());
|
||||||
|
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
if (sparsifier.try_to_insert_point(p))
|
||||||
|
++i;
|
||||||
|
if (sparsifier.try_to_insert_point(p2))
|
||||||
|
++i;
|
||||||
|
#else
|
||||||
|
points.push_back(p);
|
||||||
|
++i;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a = big radius, b = small radius
|
||||||
|
template <typename Kernel>
|
||||||
|
std::vector<typename Kernel::Point_d> generate_points_on_klein_bottle_3D(
|
||||||
|
std::size_t num_points, double a, double b, bool uniform = false)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
Kernel k;
|
||||||
|
CGAL::Random rng;
|
||||||
|
|
||||||
|
// if uniform
|
||||||
|
std::size_t num_lines = (std::size_t)sqrt(num_points);
|
||||||
|
std::size_t num_cols = num_points/num_lines + 1;
|
||||||
|
|
||||||
|
std::vector<Point> points;
|
||||||
|
points.reserve(num_points);
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
Point_sparsifier<Kernel, std::vector<Point> > sparsifier(points);
|
||||||
|
#endif
|
||||||
|
for (std::size_t i = 0 ; i < num_points ; )
|
||||||
|
{
|
||||||
|
FT u, v;
|
||||||
|
if (uniform)
|
||||||
|
{
|
||||||
|
std::size_t k1 = i / num_lines;
|
||||||
|
std::size_t k2 = i % num_lines;
|
||||||
|
u = 6.2832 * k1 / num_lines;
|
||||||
|
v = 6.2832 * k2 / num_lines;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u = rng.get_double(0, 6.2832);
|
||||||
|
v = rng.get_double(0, 6.2832);
|
||||||
|
}
|
||||||
|
double tmp = cos(u/2)*sin(v) - sin(u/2)*sin(2.*v);
|
||||||
|
Point p = construct_point(k,
|
||||||
|
(a + b*tmp)*cos(u),
|
||||||
|
(a + b*tmp)*sin(u),
|
||||||
|
b*(sin(u/2)*sin(v) + cos(u/2)*sin(2.*v)));
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
if (sparsifier.try_to_insert_point(p))
|
||||||
|
++i;
|
||||||
|
#else
|
||||||
|
points.push_back(p);
|
||||||
|
++i;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a = big radius, b = small radius
|
||||||
|
template <typename Kernel>
|
||||||
|
std::vector<typename Kernel::Point_d> generate_points_on_klein_bottle_4D(
|
||||||
|
std::size_t num_points, double a, double b, double noise = 0., bool uniform = false)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
Kernel k;
|
||||||
|
CGAL::Random rng;
|
||||||
|
|
||||||
|
// if uniform
|
||||||
|
std::size_t num_lines = (std::size_t)sqrt(num_points);
|
||||||
|
std::size_t num_cols = num_points/num_lines + 1;
|
||||||
|
|
||||||
|
std::vector<Point> points;
|
||||||
|
points.reserve(num_points);
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
Point_sparsifier<Kernel, std::vector<Point> > sparsifier(points);
|
||||||
|
#endif
|
||||||
|
for (std::size_t i = 0 ; i < num_points ; )
|
||||||
|
{
|
||||||
|
FT u, v;
|
||||||
|
if (uniform)
|
||||||
|
{
|
||||||
|
std::size_t k1 = i / num_lines;
|
||||||
|
std::size_t k2 = i % num_lines;
|
||||||
|
u = 6.2832 * k1 / num_lines;
|
||||||
|
v = 6.2832 * k2 / num_lines;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u = rng.get_double(0, 6.2832);
|
||||||
|
v = rng.get_double(0, 6.2832);
|
||||||
|
}
|
||||||
|
Point p = construct_point(k,
|
||||||
|
(a + b*cos(v))*cos(u) + (noise == 0. ? 0. : rng.get_double(0, noise)),
|
||||||
|
(a + b*cos(v))*sin(u) + (noise == 0. ? 0. : rng.get_double(0, noise)),
|
||||||
|
b*sin(v)*cos(u/2) + (noise == 0. ? 0. : rng.get_double(0, noise)),
|
||||||
|
b*sin(v)*sin(u/2) + (noise == 0. ? 0. : rng.get_double(0, noise)));
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
if (sparsifier.try_to_insert_point(p))
|
||||||
|
++i;
|
||||||
|
#else
|
||||||
|
points.push_back(p);
|
||||||
|
++i;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// a = big radius, b = small radius
|
||||||
|
template <typename Kernel>
|
||||||
|
std::vector<typename Kernel::Point_d>
|
||||||
|
generate_points_on_klein_bottle_variant_5D(
|
||||||
|
std::size_t num_points, double a, double b, bool uniform = false)
|
||||||
|
{
|
||||||
|
typedef typename Kernel::Point_d Point;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
Kernel k;
|
||||||
|
CGAL::Random rng;
|
||||||
|
|
||||||
|
// if uniform
|
||||||
|
std::size_t num_lines = (std::size_t)sqrt(num_points);
|
||||||
|
std::size_t num_cols = num_points/num_lines + 1;
|
||||||
|
|
||||||
|
std::vector<Point> points;
|
||||||
|
points.reserve(num_points);
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
Point_sparsifier<Kernel, std::vector<Point> > sparsifier(points);
|
||||||
|
#endif
|
||||||
|
for (std::size_t i = 0 ; i < num_points ; )
|
||||||
|
{
|
||||||
|
FT u, v;
|
||||||
|
if (uniform)
|
||||||
|
{
|
||||||
|
std::size_t k1 = i / num_lines;
|
||||||
|
std::size_t k2 = i % num_lines;
|
||||||
|
u = 6.2832 * k1 / num_lines;
|
||||||
|
v = 6.2832 * k2 / num_lines;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u = rng.get_double(0, 6.2832);
|
||||||
|
v = rng.get_double(0, 6.2832);
|
||||||
|
}
|
||||||
|
FT x1 = (a + b*cos(v))*cos(u);
|
||||||
|
FT x2 = (a + b*cos(v))*sin(u);
|
||||||
|
FT x3 = b*sin(v)*cos(u/2);
|
||||||
|
FT x4 = b*sin(v)*sin(u/2);
|
||||||
|
FT x5 = x1 + x2 + x3 + x4;
|
||||||
|
|
||||||
|
Point p = construct_point(k, x1, x2, x3, x4, x5);
|
||||||
|
#ifdef CGAL_TC_USE_SLOW_BUT_ACCURATE_SPARSIFIER
|
||||||
|
if (sparsifier.try_to_insert_point(p))
|
||||||
|
++i;
|
||||||
|
#else
|
||||||
|
points.push_back(p);
|
||||||
|
++i;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Kernel>
|
||||||
|
void benchmark_spatial_search(
|
||||||
|
const std::vector<typename Kernel::Point_d> &points, const Kernel &k,
|
||||||
|
std::ostream & csv_file)
|
||||||
|
{
|
||||||
|
std::cout <<
|
||||||
|
"****************************************\n"
|
||||||
|
"***** Benchmarking spatial search ******\n"
|
||||||
|
"****************************************\n\n";
|
||||||
|
|
||||||
|
const std::size_t NUM_QUERIES = 100000;
|
||||||
|
const std::size_t NUM_NEIGHBORS = 50;
|
||||||
|
|
||||||
|
typedef Kernel::FT FT;
|
||||||
|
typedef Kernel::Point_d Point;
|
||||||
|
typedef std::vector<Point> Points;
|
||||||
|
|
||||||
|
CGAL::Random random_generator;
|
||||||
|
Wall_clock_timer t;
|
||||||
|
|
||||||
|
//****************************** CGAL ***************************************
|
||||||
|
{
|
||||||
|
std::cout << "\n=== CGAL ===\n";
|
||||||
|
|
||||||
|
typedef CGAL::Tangential_complex_::Point_cloud_data_structure<Kernel, Points>
|
||||||
|
Points_ds;
|
||||||
|
typedef Points_ds::KNS_range KNS_range;
|
||||||
|
typedef Points_ds::KNS_iterator KNS_iterator;
|
||||||
|
typedef Points_ds::INS_range INS_range;
|
||||||
|
typedef Points_ds::INS_iterator INS_iterator;
|
||||||
|
|
||||||
|
t.reset();
|
||||||
|
Points_ds points_ds(points);
|
||||||
|
double init_time = t.elapsed();
|
||||||
|
std::cout << "Init: " << init_time << std::endl;
|
||||||
|
t.reset();
|
||||||
|
|
||||||
|
for (std::size_t i = 0 ; i < NUM_QUERIES ; ++i)
|
||||||
|
{
|
||||||
|
std::size_t pt_idx = random_generator.get_int(0, points.size() - 1);
|
||||||
|
KNS_range kns_range = points_ds.query_ANN(
|
||||||
|
points[pt_idx], NUM_NEIGHBORS, true);
|
||||||
|
}
|
||||||
|
double queries_time = t.elapsed();
|
||||||
|
std::cout << NUM_QUERIES << " queries among "
|
||||||
|
<< points.size() << " points: " << queries_time << std::endl;
|
||||||
|
csv_file << queries_time << ";";
|
||||||
|
}
|
||||||
|
//**************************** nanoflann ************************************
|
||||||
|
{
|
||||||
|
std::cout << "\n=== nanoflann ===\n";
|
||||||
|
|
||||||
|
typedef CGAL::Tangential_complex_::
|
||||||
|
Point_cloud_data_structure__nanoflann<Kernel, Points>
|
||||||
|
Points_ds;
|
||||||
|
|
||||||
|
t.reset();
|
||||||
|
Points_ds points_ds(points, k);
|
||||||
|
double init_time = t.elapsed();
|
||||||
|
std::cout << "Init: " << init_time << std::endl;
|
||||||
|
t.reset();
|
||||||
|
|
||||||
|
for (std::size_t i = 0 ; i < NUM_QUERIES ; ++i)
|
||||||
|
{
|
||||||
|
std::size_t pt_idx = random_generator.get_int(0, points.size() - 1);
|
||||||
|
std::size_t neighbors_indices[NUM_NEIGHBORS];
|
||||||
|
FT neighbors_sq_distances[NUM_NEIGHBORS];
|
||||||
|
points_ds.query_ANN(
|
||||||
|
points[pt_idx], NUM_NEIGHBORS, neighbors_indices, neighbors_sq_distances);
|
||||||
|
}
|
||||||
|
double queries_time = t.elapsed();
|
||||||
|
std::cout << NUM_QUERIES << " queries among "
|
||||||
|
<< points.size() << " points: " << queries_time << std::endl;
|
||||||
|
csv_file << queries_time << ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
//******************************* ANN ***************************************
|
||||||
|
{
|
||||||
|
std::cout << "\n=== ANN ===\n";
|
||||||
|
|
||||||
|
typedef CGAL::Tangential_complex_::
|
||||||
|
Point_cloud_data_structure__ANN<Kernel, Points>
|
||||||
|
Points_ds;
|
||||||
|
|
||||||
|
t.reset();
|
||||||
|
Points_ds points_ds(points, k);
|
||||||
|
double init_time = t.elapsed();
|
||||||
|
std::cout << "Init: " << init_time << std::endl;
|
||||||
|
t.reset();
|
||||||
|
|
||||||
|
for (std::size_t i = 0 ; i < NUM_QUERIES ; ++i)
|
||||||
|
{
|
||||||
|
std::size_t pt_idx = random_generator.get_int(0, points.size() - 1);
|
||||||
|
int neighbors_indices[NUM_NEIGHBORS];
|
||||||
|
double neighbors_sq_distances[NUM_NEIGHBORS];
|
||||||
|
points_ds.query_ANN(
|
||||||
|
points[pt_idx], NUM_NEIGHBORS, neighbors_indices, neighbors_sq_distances);
|
||||||
|
}
|
||||||
|
double queries_time = t.elapsed();
|
||||||
|
std::cout << NUM_QUERIES << " queries among "
|
||||||
|
<< points.size() << " points: " << queries_time << std::endl;
|
||||||
|
csv_file << queries_time << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CGAL_MESH_3_TEST_TEST_UTILITIES_H
|
||||||
|
|
@ -123,7 +123,7 @@ public:
|
||||||
using Base::vertices_begin;
|
using Base::vertices_begin;
|
||||||
using Base::vertices_end;
|
using Base::vertices_end;
|
||||||
// using Base::
|
// using Base::
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//*** Side_of_oriented_subsphere_d ***
|
//*** Side_of_oriented_subsphere_d ***
|
||||||
typedef typename Base::Flat_orientation_d Flat_orientation_d;
|
typedef typename Base::Flat_orientation_d Flat_orientation_d;
|
||||||
|
|
@ -160,12 +160,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// With this constructor,
|
// With this constructor,
|
||||||
// the user can specify a Flat_orientation_d object to be used for
|
// the user can specify a Flat_orientation_d object to be used for
|
||||||
// orienting simplices of a specific dimension
|
// orienting simplices of a specific dimension
|
||||||
// (= preset_flat_orientation_.first)
|
// (= preset_flat_orientation_.first)
|
||||||
// It it used by the dark triangulations created by DT::remove
|
// It it used by the dark triangulations created by DT::remove
|
||||||
Delaunay_triangulation(
|
Delaunay_triangulation(
|
||||||
int dim,
|
int dim,
|
||||||
const std::pair<int, const Flat_orientation_d *> &preset_flat_orientation,
|
const std::pair<int, const Flat_orientation_d *> &preset_flat_orientation,
|
||||||
const Geom_traits &k = Geom_traits())
|
const Geom_traits &k = Geom_traits())
|
||||||
: Base(dim, preset_flat_orientation, k)
|
: Base(dim, preset_flat_orientation, k)
|
||||||
|
|
@ -180,8 +180,8 @@ public:
|
||||||
Side_of_oriented_subsphere_d side_of_oriented_subsphere_predicate() const
|
Side_of_oriented_subsphere_d side_of_oriented_subsphere_predicate() const
|
||||||
{
|
{
|
||||||
return Side_of_oriented_subsphere_d (
|
return Side_of_oriented_subsphere_d (
|
||||||
flat_orientation_,
|
flat_orientation_,
|
||||||
geom_traits().construct_flat_orientation_d_object(),
|
geom_traits().construct_flat_orientation_d_object(),
|
||||||
geom_traits().in_flat_side_of_oriented_sphere_d_object()
|
geom_traits().in_flat_side_of_oriented_sphere_d_object()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -293,7 +293,7 @@ public:
|
||||||
|
|
||||||
Orientation o = ori_(
|
Orientation o = ori_(
|
||||||
boost::make_transform_iterator(s->vertices_begin(), spivi),
|
boost::make_transform_iterator(s->vertices_begin(), spivi),
|
||||||
boost::make_transform_iterator(s->vertices_begin() + cur_dim_ + 1,
|
boost::make_transform_iterator(s->vertices_begin() + cur_dim_ + 1,
|
||||||
spivi));
|
spivi));
|
||||||
|
|
||||||
if( POSITIVE == o )
|
if( POSITIVE == o )
|
||||||
|
|
@ -322,9 +322,9 @@ public:
|
||||||
return pred_(dc_.full_cell(f)->neighbor(dc_.index_of_covertex(f)));
|
return pred_(dc_.full_cell(f)->neighbor(dc_.index_of_covertex(f)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
|
||||||
|
|
||||||
bool is_valid(bool verbose = false, int level = 0) const;
|
bool is_valid(bool verbose = false, int level = 0) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -341,7 +341,7 @@ private:
|
||||||
Conflict_traversal_pred_in_fullspace;
|
Conflict_traversal_pred_in_fullspace;
|
||||||
};
|
};
|
||||||
|
|
||||||
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||||
// FUNCTIONS THAT ARE MEMBER METHODS:
|
// FUNCTIONS THAT ARE MEMBER METHODS:
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
|
||||||
|
|
@ -514,7 +514,7 @@ Delaunay_triangulation<DCTraits, TDS>
|
||||||
typedef typename Base::template Full_cell_set<Dark_s_handle> Dark_full_cells;
|
typedef typename Base::template Full_cell_set<Dark_s_handle> Dark_full_cells;
|
||||||
Dark_full_cells conflict_zone;
|
Dark_full_cells conflict_zone;
|
||||||
std::back_insert_iterator<Dark_full_cells> dark_out(conflict_zone);
|
std::back_insert_iterator<Dark_full_cells> dark_out(conflict_zone);
|
||||||
|
|
||||||
dark_ft = dark_side.compute_conflict_zone(v->point(), dark_s, dark_out);
|
dark_ft = dark_side.compute_conflict_zone(v->point(), dark_s, dark_out);
|
||||||
// Make the dark simplices in the conflict zone searchable
|
// Make the dark simplices in the conflict zone searchable
|
||||||
conflict_zone.make_searchable();
|
conflict_zone.make_searchable();
|
||||||
|
|
@ -612,7 +612,7 @@ Delaunay_triangulation<DCTraits, TDS>
|
||||||
int li = light_s->index(dark_s->vertex(di)->data());
|
int li = light_s->index(dark_s->vertex(di)->data());
|
||||||
Rotor light_r(light_s, li, light_i);
|
Rotor light_r(light_s, li, light_i);
|
||||||
typename Dark_triangulation::Rotor dark_r(dark_s, di, dark_i);
|
typename Dark_triangulation::Rotor dark_r(dark_s, di, dark_i);
|
||||||
|
|
||||||
while (simps.contains(cpp11::get<0>(light_r)->neighbor(cpp11::get<1>(light_r))))
|
while (simps.contains(cpp11::get<0>(light_r)->neighbor(cpp11::get<1>(light_r))))
|
||||||
light_r = rotate_rotor(light_r);
|
light_r = rotate_rotor(light_r);
|
||||||
|
|
||||||
|
|
@ -871,27 +871,27 @@ template< typename DCTraits, typename TDS >
|
||||||
bool
|
bool
|
||||||
Delaunay_triangulation<DCTraits, TDS>
|
Delaunay_triangulation<DCTraits, TDS>
|
||||||
::is_valid(bool verbose, int level) const
|
::is_valid(bool verbose, int level) const
|
||||||
{
|
{
|
||||||
if (!Base::is_valid(verbose, level))
|
if (!Base::is_valid(verbose, level))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int dim = current_dimension();
|
int dim = current_dimension();
|
||||||
if (dim == maximal_dimension())
|
if (dim == maximal_dimension())
|
||||||
{
|
{
|
||||||
for (Finite_full_cell_const_iterator cit = finite_full_cells_begin() ;
|
for (Finite_full_cell_const_iterator cit = this->finite_full_cells_begin() ;
|
||||||
cit != finite_full_cells_end() ; ++cit )
|
cit != this->finite_full_cells_end() ; ++cit )
|
||||||
{
|
{
|
||||||
Full_cell_const_handle ch = cit.base();
|
Full_cell_const_handle ch = cit.base();
|
||||||
for(int i = 0; i < dim+1 ; ++i )
|
for(int i = 0; i < dim+1 ; ++i )
|
||||||
{
|
{
|
||||||
// If the i-th neighbor is not an infinite cell
|
// If the i-th neighbor is not an infinite cell
|
||||||
Vertex_handle opposite_vh =
|
Vertex_handle opposite_vh =
|
||||||
ch->neighbor(i)->vertex(ch->neighbor(i)->index(ch));
|
ch->neighbor(i)->vertex(ch->neighbor(i)->index(ch));
|
||||||
if (!is_infinite(opposite_vh))
|
if (!is_infinite(opposite_vh))
|
||||||
{
|
{
|
||||||
Side_of_oriented_sphere_d side =
|
Side_of_oriented_sphere_d side =
|
||||||
geom_traits().side_of_oriented_sphere_d_object();
|
geom_traits().side_of_oriented_sphere_d_object();
|
||||||
if (side(Point_const_iterator(ch->vertices_begin()),
|
if (side(Point_const_iterator(ch->vertices_begin()),
|
||||||
Point_const_iterator(ch->vertices_end()),
|
Point_const_iterator(ch->vertices_end()),
|
||||||
opposite_vh->point()) == ON_BOUNDED_SIDE)
|
opposite_vh->point()) == ON_BOUNDED_SIDE)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ input_point(std::istream & is, const Traits &traits, P & p)
|
||||||
{
|
{
|
||||||
typedef typename Traits::FT FT;
|
typedef typename Traits::FT FT;
|
||||||
std::vector<FT> coords;
|
std::vector<FT> coords;
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
|
|
@ -125,7 +125,7 @@ operator>>(std::istream &is, typename Wrap::Point_d<K> & p)
|
||||||
typedef typename Wrap::Point_d<K> P;
|
typedef typename Wrap::Point_d<K> P;
|
||||||
typedef typename K::FT FT;
|
typedef typename K::FT FT;
|
||||||
std::vector<FT> coords;
|
std::vector<FT> coords;
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
|
|
@ -165,7 +165,7 @@ operator>>(std::istream &is, typename Wrap::Weighted_point_d<K> & wp)
|
||||||
std::vector<FT> coords;
|
std::vector<FT> coords;
|
||||||
while (line_sstr >> temp)
|
while (line_sstr >> temp)
|
||||||
coords.push_back(temp);
|
coords.push_back(temp);
|
||||||
|
|
||||||
typename std::vector<FT>::iterator last = coords.end() - 1;
|
typename std::vector<FT>::iterator last = coords.end() - 1;
|
||||||
P p = P(coords.begin(), last);
|
P p = P(coords.begin(), last);
|
||||||
wp = WP(p, *last);
|
wp = WP(p, *last);
|
||||||
|
|
@ -175,7 +175,7 @@ operator>>(std::istream &is, typename Wrap::Weighted_point_d<K> & wp)
|
||||||
|
|
||||||
template < class GT, class TDS >
|
template < class GT, class TDS >
|
||||||
std::ostream &
|
std::ostream &
|
||||||
export_triangulation_to_off(std::ostream & os,
|
export_triangulation_to_off(std::ostream & os,
|
||||||
const Triangulation<GT,TDS> & tr,
|
const Triangulation<GT,TDS> & tr,
|
||||||
bool in_3D_export_surface_only = false)
|
bool in_3D_export_surface_only = false)
|
||||||
{
|
{
|
||||||
|
|
@ -188,7 +188,7 @@ export_triangulation_to_off(std::ostream & os,
|
||||||
typedef typename Tr::Full_cell_const_iterator Full_cell_iterator;
|
typedef typename Tr::Full_cell_const_iterator Full_cell_iterator;
|
||||||
typedef typename Tr::Full_cell Full_cell;
|
typedef typename Tr::Full_cell Full_cell;
|
||||||
typedef typename Full_cell::Vertex_handle_const_iterator Full_cell_vertex_iterator;
|
typedef typename Full_cell::Vertex_handle_const_iterator Full_cell_vertex_iterator;
|
||||||
|
|
||||||
if (tr.maximal_dimension() < 2 || tr.maximal_dimension() > 3)
|
if (tr.maximal_dimension() < 2 || tr.maximal_dimension() > 3)
|
||||||
{
|
{
|
||||||
std::cerr << "Warning: export_tds_to_off => dimension should be 2 or 3.";
|
std::cerr << "Warning: export_tds_to_off => dimension should be 2 or 3.";
|
||||||
|
|
@ -199,11 +199,11 @@ export_triangulation_to_off(std::ostream & os,
|
||||||
size_t n = tr.number_of_vertices();
|
size_t n = tr.number_of_vertices();
|
||||||
|
|
||||||
std::stringstream output;
|
std::stringstream output;
|
||||||
|
|
||||||
// write the vertices
|
// write the vertices
|
||||||
std::map<Vertex_handle, int> index_of_vertex;
|
std::map<Vertex_handle, int> index_of_vertex;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(Finite_vertex_iterator it = tr.finite_vertices_begin();
|
for(Finite_vertex_iterator it = tr.finite_vertices_begin();
|
||||||
it != tr.finite_vertices_end(); ++it, ++i)
|
it != tr.finite_vertices_end(); ++it, ++i)
|
||||||
{
|
{
|
||||||
Triangulation_IO::output_point(output, tr.geom_traits(), it->point());
|
Triangulation_IO::output_point(output, tr.geom_traits(), it->point());
|
||||||
|
|
@ -213,7 +213,7 @@ export_triangulation_to_off(std::ostream & os,
|
||||||
index_of_vertex[it.base()] = i;
|
index_of_vertex[it.base()] = i;
|
||||||
}
|
}
|
||||||
CGAL_assertion( i == n );
|
CGAL_assertion( i == n );
|
||||||
|
|
||||||
size_t number_of_triangles = 0;
|
size_t number_of_triangles = 0;
|
||||||
if (tr.maximal_dimension() == 2)
|
if (tr.maximal_dimension() == 2)
|
||||||
{
|
{
|
||||||
|
|
@ -248,7 +248,7 @@ export_triangulation_to_off(std::ostream & os,
|
||||||
output << index_of_vertex[*vit] << " ";
|
output << index_of_vertex[*vit] << " ";
|
||||||
}
|
}
|
||||||
output << std::endl;
|
output << std::endl;
|
||||||
++number_of_triangles;
|
++number_of_triangles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -284,7 +284,7 @@ export_triangulation_to_off(std::ostream & os,
|
||||||
}
|
}
|
||||||
|
|
||||||
os << "OFF \n"
|
os << "OFF \n"
|
||||||
<< n << " "
|
<< n << " "
|
||||||
<< number_of_triangles << " 0\n"
|
<< number_of_triangles << " 0\n"
|
||||||
<< output.str();
|
<< output.str();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class Regular_triangulation
|
||||||
typedef CGAL::Regular_triangulation_euclidean_traits<Traits_> RTTraits;
|
typedef CGAL::Regular_triangulation_euclidean_traits<Traits_> RTTraits;
|
||||||
typedef typename RTTraits::Dimension Maximal_dimension_;
|
typedef typename RTTraits::Dimension Maximal_dimension_;
|
||||||
typedef typename Default::Get<
|
typedef typename Default::Get<
|
||||||
TDS_,
|
TDS_,
|
||||||
Triangulation_data_structure<
|
Triangulation_data_structure<
|
||||||
Maximal_dimension_,
|
Maximal_dimension_,
|
||||||
Triangulation_vertex<RTTraits>,
|
Triangulation_vertex<RTTraits>,
|
||||||
|
|
@ -70,8 +70,9 @@ public: // PUBLIC NESTED TYPES
|
||||||
typedef typename Base::Full_cell Full_cell;
|
typedef typename Base::Full_cell Full_cell;
|
||||||
typedef typename Base::Facet Facet;
|
typedef typename Base::Facet Facet;
|
||||||
typedef typename Base::Face Face;
|
typedef typename Base::Face Face;
|
||||||
|
|
||||||
typedef Maximal_dimension_ Maximal_dimension;
|
typedef Maximal_dimension_ Maximal_dimension;
|
||||||
|
typedef typename Base::Point Point;
|
||||||
typedef typename RTTraits::Bare_point Bare_point;
|
typedef typename RTTraits::Bare_point Bare_point;
|
||||||
typedef typename RTTraits::Weighted_point Weighted_point;
|
typedef typename RTTraits::Weighted_point Weighted_point;
|
||||||
|
|
||||||
|
|
@ -154,7 +155,7 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS
|
||||||
|
|
||||||
Regular_triangulation(int dim, const Geom_traits &k = Geom_traits())
|
Regular_triangulation(int dim, const Geom_traits &k = Geom_traits())
|
||||||
|
|
@ -163,12 +164,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// With this constructor,
|
// With this constructor,
|
||||||
// the user can specify a Flat_orientation_d object to be used for
|
// the user can specify a Flat_orientation_d object to be used for
|
||||||
// orienting simplices of a specific dimension
|
// orienting simplices of a specific dimension
|
||||||
// (= preset_flat_orientation_.first)
|
// (= preset_flat_orientation_.first)
|
||||||
// It it used by the dark triangulations created by DT::remove
|
// It it used by the dark triangulations created by DT::remove
|
||||||
Regular_triangulation(
|
Regular_triangulation(
|
||||||
int dim,
|
int dim,
|
||||||
const std::pair<int, const Flat_orientation_d *> &preset_flat_orientation,
|
const std::pair<int, const Flat_orientation_d *> &preset_flat_orientation,
|
||||||
const Geom_traits &k = Geom_traits())
|
const Geom_traits &k = Geom_traits())
|
||||||
: Base(dim, preset_flat_orientation, k)
|
: Base(dim, preset_flat_orientation, k)
|
||||||
|
|
@ -183,8 +184,8 @@ public:
|
||||||
Power_test_in_flat_d power_test_in_flat_predicate() const
|
Power_test_in_flat_d power_test_in_flat_predicate() const
|
||||||
{
|
{
|
||||||
return Power_test_in_flat_d (
|
return Power_test_in_flat_d (
|
||||||
flat_orientation_,
|
flat_orientation_,
|
||||||
geom_traits().construct_flat_orientation_d_object(),
|
geom_traits().construct_flat_orientation_d_object(),
|
||||||
geom_traits().in_flat_power_test_d_object()
|
geom_traits().in_flat_power_test_d_object()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -244,13 +245,13 @@ public:
|
||||||
return number_of_vertices() - n;
|
return number_of_vertices() - n;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vertex_handle insert(const Weighted_point &,
|
Vertex_handle insert(const Weighted_point &,
|
||||||
const Locate_type,
|
const Locate_type,
|
||||||
const Face &,
|
const Face &,
|
||||||
const Facet &,
|
const Facet &,
|
||||||
const Full_cell_handle);
|
const Full_cell_handle);
|
||||||
|
|
||||||
Vertex_handle insert(const Weighted_point & p,
|
Vertex_handle insert(const Weighted_point & p,
|
||||||
const Full_cell_handle start = Full_cell_handle())
|
const Full_cell_handle start = Full_cell_handle())
|
||||||
{
|
{
|
||||||
Locate_type lt;
|
Locate_type lt;
|
||||||
|
|
@ -270,14 +271,14 @@ public:
|
||||||
Vertex_handle insert_in_conflicting_cell(
|
Vertex_handle insert_in_conflicting_cell(
|
||||||
const Weighted_point &, const Full_cell_handle,
|
const Weighted_point &, const Full_cell_handle,
|
||||||
const Vertex_handle only_if_this_vertex_is_in_the_cz = Vertex_handle());
|
const Vertex_handle only_if_this_vertex_is_in_the_cz = Vertex_handle());
|
||||||
|
|
||||||
Vertex_handle insert_if_in_star(const Weighted_point &,
|
Vertex_handle insert_if_in_star(const Weighted_point &,
|
||||||
const Vertex_handle,
|
const Vertex_handle,
|
||||||
const Locate_type,
|
const Locate_type,
|
||||||
const Face &,
|
const Face &,
|
||||||
const Facet &,
|
const Facet &,
|
||||||
const Full_cell_handle);
|
const Full_cell_handle);
|
||||||
|
|
||||||
Vertex_handle insert_if_in_star(
|
Vertex_handle insert_if_in_star(
|
||||||
const Weighted_point & p, const Vertex_handle star_center,
|
const Weighted_point & p, const Vertex_handle star_center,
|
||||||
const Full_cell_handle start = Full_cell_handle())
|
const Full_cell_handle start = Full_cell_handle())
|
||||||
|
|
@ -290,7 +291,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Vertex_handle insert_if_in_star(
|
Vertex_handle insert_if_in_star(
|
||||||
const Weighted_point & p, const Vertex_handle star_center,
|
const Weighted_point & p, const Vertex_handle star_center,
|
||||||
const Vertex_handle hint)
|
const Vertex_handle hint)
|
||||||
{
|
{
|
||||||
CGAL_assertion( Vertex_handle() != hint );
|
CGAL_assertion( Vertex_handle() != hint );
|
||||||
|
|
@ -346,7 +347,7 @@ public:
|
||||||
|
|
||||||
Orientation o = ori_(
|
Orientation o = ori_(
|
||||||
boost::make_transform_iterator(s->vertices_begin(), spivi),
|
boost::make_transform_iterator(s->vertices_begin(), spivi),
|
||||||
boost::make_transform_iterator(s->vertices_begin() + cur_dim_ + 1,
|
boost::make_transform_iterator(s->vertices_begin() + cur_dim_ + 1,
|
||||||
spivi));
|
spivi));
|
||||||
|
|
||||||
if( POSITIVE == o )
|
if( POSITIVE == o )
|
||||||
|
|
@ -375,16 +376,16 @@ public:
|
||||||
return pred_(rt_.full_cell(f)->neighbor(rt_.index_of_covertex(f)));
|
return pred_(rt_.full_cell(f)->neighbor(rt_.index_of_covertex(f)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
|
||||||
|
|
||||||
bool is_valid(bool verbose = false, int level = 0) const;
|
bool is_valid(bool verbose = false, int level = 0) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
bool
|
bool
|
||||||
does_cell_range_contain_vertex(InputIterator cz_begin, InputIterator cz_end,
|
does_cell_range_contain_vertex(InputIterator cz_begin, InputIterator cz_end,
|
||||||
Vertex_handle vh) const
|
Vertex_handle vh) const
|
||||||
{
|
{
|
||||||
// Check all vertices
|
// Check all vertices
|
||||||
|
|
@ -403,7 +404,7 @@ private:
|
||||||
|
|
||||||
template<typename InputIterator, typename OutputIterator>
|
template<typename InputIterator, typename OutputIterator>
|
||||||
void
|
void
|
||||||
process_conflict_zone(InputIterator cz_begin, InputIterator cz_end,
|
process_conflict_zone(InputIterator cz_begin, InputIterator cz_end,
|
||||||
OutputIterator vertices_out) const
|
OutputIterator vertices_out) const
|
||||||
{
|
{
|
||||||
// Get all vertices
|
// Get all vertices
|
||||||
|
|
@ -423,10 +424,10 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
void
|
void
|
||||||
process_cz_vertices_after_insertion(InputIterator vertices_begin,
|
process_cz_vertices_after_insertion(InputIterator vertices_begin,
|
||||||
InputIterator vertices_end)
|
InputIterator vertices_end)
|
||||||
{
|
{
|
||||||
// Get all vertices
|
// Get all vertices
|
||||||
|
|
@ -454,14 +455,14 @@ private:
|
||||||
Conflict_traversal_pred_in_subspace;
|
Conflict_traversal_pred_in_subspace;
|
||||||
typedef Conflict_traversal_predicate<Conflict_pred_in_fullspace>
|
typedef Conflict_traversal_predicate<Conflict_pred_in_fullspace>
|
||||||
Conflict_traversal_pred_in_fullspace;
|
Conflict_traversal_pred_in_fullspace;
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MEMBER VARIABLES
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MEMBER VARIABLES
|
||||||
std::vector<Weighted_point> m_hidden_points;
|
std::vector<Weighted_point> m_hidden_points;
|
||||||
|
|
||||||
}; // class Regular_triangulation
|
}; // class Regular_triangulation
|
||||||
|
|
||||||
|
|
||||||
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||||
// FUNCTIONS THAT ARE MEMBER METHODS:
|
// FUNCTIONS THAT ARE MEMBER METHODS:
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
|
||||||
|
|
@ -527,8 +528,8 @@ Regular_triangulation<Traits, TDS>
|
||||||
typedef Triangulation_full_cell<
|
typedef Triangulation_full_cell<
|
||||||
Geom_traits,
|
Geom_traits,
|
||||||
internal::Triangulation::Dark_full_cell_data<TDS> > Dark_full_cell_base;
|
internal::Triangulation::Dark_full_cell_data<TDS> > Dark_full_cell_base;
|
||||||
typedef Triangulation_data_structure<Maximal_dimension,
|
typedef Triangulation_data_structure<Maximal_dimension,
|
||||||
Dark_vertex_base,
|
Dark_vertex_base,
|
||||||
Dark_full_cell_base
|
Dark_full_cell_base
|
||||||
> Dark_tds;
|
> Dark_tds;
|
||||||
typedef Regular_triangulation<Traits, Dark_tds> Dark_triangulation;
|
typedef Regular_triangulation<Traits, Dark_tds> Dark_triangulation;
|
||||||
|
|
@ -639,7 +640,7 @@ Regular_triangulation<Traits, TDS>
|
||||||
typedef typename Base::template Full_cell_set<Dark_s_handle> Dark_full_cells;
|
typedef typename Base::template Full_cell_set<Dark_s_handle> Dark_full_cells;
|
||||||
Dark_full_cells conflict_zone;
|
Dark_full_cells conflict_zone;
|
||||||
std::back_insert_iterator<Dark_full_cells> dark_out(conflict_zone);
|
std::back_insert_iterator<Dark_full_cells> dark_out(conflict_zone);
|
||||||
|
|
||||||
dark_ft = dark_side.compute_conflict_zone(v->point(), dark_s, dark_out);
|
dark_ft = dark_side.compute_conflict_zone(v->point(), dark_s, dark_out);
|
||||||
// Make the dark simplices in the conflict zone searchable
|
// Make the dark simplices in the conflict zone searchable
|
||||||
conflict_zone.make_searchable();
|
conflict_zone.make_searchable();
|
||||||
|
|
@ -664,8 +665,8 @@ Regular_triangulation<Traits, TDS>
|
||||||
dark_incident_s.clear();
|
dark_incident_s.clear();
|
||||||
dark_out = std::back_inserter(dark_incident_s);
|
dark_out = std::back_inserter(dark_incident_s);
|
||||||
dark_side.tds().incident_full_cells(dark_v, dark_out);
|
dark_side.tds().incident_full_cells(dark_v, dark_out);
|
||||||
for(typename Dark_full_cells::iterator it = dark_incident_s.begin();
|
for(typename Dark_full_cells::iterator it = dark_incident_s.begin();
|
||||||
it != dark_incident_s.end();
|
it != dark_incident_s.end();
|
||||||
++it)
|
++it)
|
||||||
{
|
{
|
||||||
(*it)->data().count_ += 1;
|
(*it)->data().count_ += 1;
|
||||||
|
|
@ -739,7 +740,7 @@ Regular_triangulation<Traits, TDS>
|
||||||
int li = light_s->index(dark_s->vertex(di)->data());
|
int li = light_s->index(dark_s->vertex(di)->data());
|
||||||
Rotor light_r(light_s, li, light_i);
|
Rotor light_r(light_s, li, light_i);
|
||||||
typename Dark_triangulation::Rotor dark_r(dark_s, di, dark_i);
|
typename Dark_triangulation::Rotor dark_r(dark_s, di, dark_i);
|
||||||
|
|
||||||
while( simps.contains(cpp11::get<0>(light_r)->neighbor(cpp11::get<1>(light_r))) )
|
while( simps.contains(cpp11::get<0>(light_r)->neighbor(cpp11::get<1>(light_r))) )
|
||||||
light_r = rotate_rotor(light_r);
|
light_r = rotate_rotor(light_r);
|
||||||
|
|
||||||
|
|
@ -877,9 +878,9 @@ Regular_triangulation<Traits, TDS>
|
||||||
template< typename Traits, typename TDS >
|
template< typename Traits, typename TDS >
|
||||||
typename Regular_triangulation<Traits, TDS>::Vertex_handle
|
typename Regular_triangulation<Traits, TDS>::Vertex_handle
|
||||||
Regular_triangulation<Traits, TDS>
|
Regular_triangulation<Traits, TDS>
|
||||||
::insert_if_in_star(const Weighted_point & p,
|
::insert_if_in_star(const Weighted_point & p,
|
||||||
const Vertex_handle star_center,
|
const Vertex_handle star_center,
|
||||||
const Locate_type lt, const Face & f, const Facet & ft,
|
const Locate_type lt, const Face & f, const Facet & ft,
|
||||||
const Full_cell_handle s)
|
const Full_cell_handle s)
|
||||||
{
|
{
|
||||||
switch( lt )
|
switch( lt )
|
||||||
|
|
@ -917,7 +918,7 @@ Regular_triangulation<Traits, TDS>
|
||||||
template< typename Traits, typename TDS >
|
template< typename Traits, typename TDS >
|
||||||
typename Regular_triangulation<Traits, TDS>::Vertex_handle
|
typename Regular_triangulation<Traits, TDS>::Vertex_handle
|
||||||
Regular_triangulation<Traits, TDS>
|
Regular_triangulation<Traits, TDS>
|
||||||
::insert_in_conflicting_cell(const Weighted_point & p,
|
::insert_in_conflicting_cell(const Weighted_point & p,
|
||||||
const Full_cell_handle s,
|
const Full_cell_handle s,
|
||||||
const Vertex_handle only_if_this_vertex_is_in_the_cz)
|
const Vertex_handle only_if_this_vertex_is_in_the_cz)
|
||||||
{
|
{
|
||||||
|
|
@ -938,10 +939,10 @@ Regular_triangulation<Traits, TDS>
|
||||||
cs.reserve(64);
|
cs.reserve(64);
|
||||||
std::back_insert_iterator<Full_cell_h_vector> out(cs);
|
std::back_insert_iterator<Full_cell_h_vector> out(cs);
|
||||||
Facet ft = compute_conflict_zone(p, s, out);
|
Facet ft = compute_conflict_zone(p, s, out);
|
||||||
|
|
||||||
// Check if the CZ contains "only_if_this_vertex_is_in_the_cz"
|
// Check if the CZ contains "only_if_this_vertex_is_in_the_cz"
|
||||||
if (only_if_this_vertex_is_in_the_cz != Vertex_handle()
|
if (only_if_this_vertex_is_in_the_cz != Vertex_handle()
|
||||||
&& !does_cell_range_contain_vertex(cs.begin(), cs.end(),
|
&& !does_cell_range_contain_vertex(cs.begin(), cs.end(),
|
||||||
only_if_this_vertex_is_in_the_cz))
|
only_if_this_vertex_is_in_the_cz))
|
||||||
{
|
{
|
||||||
return Vertex_handle();
|
return Vertex_handle();
|
||||||
|
|
@ -950,7 +951,7 @@ Regular_triangulation<Traits, TDS>
|
||||||
// Otherwise, proceed with the insertion
|
// Otherwise, proceed with the insertion
|
||||||
std::vector<Vertex_handle> cz_vertices;
|
std::vector<Vertex_handle> cz_vertices;
|
||||||
cz_vertices.reserve(64);
|
cz_vertices.reserve(64);
|
||||||
process_conflict_zone(cs.begin(), cs.end(),
|
process_conflict_zone(cs.begin(), cs.end(),
|
||||||
std::back_inserter(cz_vertices));
|
std::back_inserter(cz_vertices));
|
||||||
|
|
||||||
Vertex_handle ret = insert_in_hole(p, cs.begin(), cs.end(), ft);
|
Vertex_handle ret = insert_in_hole(p, cs.begin(), cs.end(), ft);
|
||||||
|
|
@ -1031,8 +1032,8 @@ Regular_triangulation<Traits, TDS>
|
||||||
if( current_dimension() < maximal_dimension() )
|
if( current_dimension() < maximal_dimension() )
|
||||||
{
|
{
|
||||||
Conflict_pred_in_subspace c(
|
Conflict_pred_in_subspace c(
|
||||||
*this, p,
|
*this, p,
|
||||||
coaffine_orientation_predicate(),
|
coaffine_orientation_predicate(),
|
||||||
power_test_in_flat_predicate());
|
power_test_in_flat_predicate());
|
||||||
return c(s);
|
return c(s);
|
||||||
}
|
}
|
||||||
|
|
@ -1055,8 +1056,8 @@ Regular_triangulation<Traits, TDS>
|
||||||
if( current_dimension() < maximal_dimension() )
|
if( current_dimension() < maximal_dimension() )
|
||||||
{
|
{
|
||||||
Conflict_pred_in_subspace c(
|
Conflict_pred_in_subspace c(
|
||||||
*this, p,
|
*this, p,
|
||||||
coaffine_orientation_predicate(),
|
coaffine_orientation_predicate(),
|
||||||
power_test_in_flat_predicate());
|
power_test_in_flat_predicate());
|
||||||
Conflict_traversal_pred_in_subspace tp(*this, c);
|
Conflict_traversal_pred_in_subspace tp(*this, c);
|
||||||
return tds().gather_full_cells(s, tp, out);
|
return tds().gather_full_cells(s, tp, out);
|
||||||
|
|
@ -1077,7 +1078,7 @@ template< typename Traits, typename TDS >
|
||||||
bool
|
bool
|
||||||
Regular_triangulation<Traits, TDS>
|
Regular_triangulation<Traits, TDS>
|
||||||
::is_valid(bool verbose, int level) const
|
::is_valid(bool verbose, int level) const
|
||||||
{
|
{
|
||||||
if (!Base::is_valid(verbose, level))
|
if (!Base::is_valid(verbose, level))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -1088,16 +1089,16 @@ Regular_triangulation<Traits, TDS>
|
||||||
cit != finite_full_cells_end() ; ++cit )
|
cit != finite_full_cells_end() ; ++cit )
|
||||||
{
|
{
|
||||||
Full_cell_const_handle ch = cit.base();
|
Full_cell_const_handle ch = cit.base();
|
||||||
for(int i = 0; i < dim+1 ; ++i )
|
for(int i = 0; i < dim+1 ; ++i )
|
||||||
{
|
{
|
||||||
// If the i-th neighbor is not an infinite cell
|
// If the i-th neighbor is not an infinite cell
|
||||||
Vertex_handle opposite_vh =
|
Vertex_handle opposite_vh =
|
||||||
ch->neighbor(i)->vertex(ch->neighbor(i)->index(ch));
|
ch->neighbor(i)->vertex(ch->neighbor(i)->index(ch));
|
||||||
if (!is_infinite(opposite_vh))
|
if (!is_infinite(opposite_vh))
|
||||||
{
|
{
|
||||||
Power_test_d side =
|
Power_test_d side =
|
||||||
geom_traits().power_test_d_object();
|
geom_traits().power_test_d_object();
|
||||||
if (side(Point_const_iterator(ch->vertices_begin()),
|
if (side(Point_const_iterator(ch->vertices_begin()),
|
||||||
Point_const_iterator(ch->vertices_end()),
|
Point_const_iterator(ch->vertices_end()),
|
||||||
opposite_vh->point()) == ON_POSITIVE_SIDE)
|
opposite_vh->point()) == ON_POSITIVE_SIDE)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -611,7 +611,8 @@ public:
|
||||||
return incident_faces(v, dim, out, cmp, true);
|
return incident_faces(v, dim, out, cmp, true);
|
||||||
}
|
}
|
||||||
template< typename OutputIterator, typename Comparator = std::less<Vertex_const_handle> >
|
template< typename OutputIterator, typename Comparator = std::less<Vertex_const_handle> >
|
||||||
OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator, Comparator = Comparator(), bool = false) const;
|
OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator,
|
||||||
|
Comparator = Comparator(), bool = false) const;
|
||||||
#else
|
#else
|
||||||
template< typename OutputIterator, typename Comparator >
|
template< typename OutputIterator, typename Comparator >
|
||||||
OutputIterator incident_upper_faces(Vertex_const_handle v, const int dim, OutputIterator out, Comparator cmp = Comparator())
|
OutputIterator incident_upper_faces(Vertex_const_handle v, const int dim, OutputIterator out, Comparator cmp = Comparator())
|
||||||
|
|
@ -664,6 +665,9 @@ Triangulation_data_structure<Dim, Vb, Fcb>
|
||||||
{
|
{
|
||||||
// CGAL_expensive_precondition(is_vertex(v));
|
// CGAL_expensive_precondition(is_vertex(v));
|
||||||
CGAL_precondition(Vertex_handle() != v);
|
CGAL_precondition(Vertex_handle() != v);
|
||||||
|
CGAL_precondition(v->full_cell()->has_vertex(v));
|
||||||
|
if (!v->full_cell()->has_vertex(v)) // CJTODO TEMP
|
||||||
|
std::cout << "ERROR: incident_full_cells !v->full_cell()->has_vertex(v). Is the point cloud sparse enough?";
|
||||||
Face f(v->full_cell());
|
Face f(v->full_cell());
|
||||||
f.set_index(0, v->full_cell()->index(v));
|
f.set_index(0, v->full_cell()->index(v));
|
||||||
return incident_full_cells(f, out);
|
return incident_full_cells(f, out);
|
||||||
|
|
@ -713,7 +717,9 @@ Triangulation_data_structure<Dim, Vb, Fcb>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clear_visited_marks(start);
|
clear_visited_marks(start); // CJTODO: couldn't we use what is in "out"
|
||||||
|
// to make ot faster? (would require to
|
||||||
|
// replace the output iterator by a container)
|
||||||
return ft;
|
return ft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -998,7 +1004,7 @@ Triangulation_data_structure<Dim, Vb, Fcb>
|
||||||
associate_vertex_with_full_cell(new_s, facet_index, v);
|
associate_vertex_with_full_cell(new_s, facet_index, v);
|
||||||
set_neighbors(new_s,
|
set_neighbors(new_s,
|
||||||
facet_index,
|
facet_index,
|
||||||
neighbor(old_s, facet_index),
|
outside_neighbor,
|
||||||
mirror_index(old_s, facet_index));
|
mirror_index(old_s, facet_index));
|
||||||
|
|
||||||
// add the new full_cell to the list of new full_cells
|
// add the new full_cell to the list of new full_cells
|
||||||
|
|
|
||||||
|
|
@ -355,7 +355,7 @@ public:
|
||||||
#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
|
#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
|
||||||
{
|
{
|
||||||
#ifdef CGAL_TRIANGULATION_3_PROFILING
|
#ifdef CGAL_TRIANGULATION_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_type n = number_of_vertices();
|
size_type n = number_of_vertices();
|
||||||
|
|
@ -691,7 +691,7 @@ public:
|
||||||
size_type n = number_of_vertices();
|
size_type n = number_of_vertices();
|
||||||
|
|
||||||
#ifdef CGAL_TRIANGULATION_3_PROFILING
|
#ifdef CGAL_TRIANGULATION_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Parallel
|
// Parallel
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ namespace CGAL {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CGAL_TRIANGULATION_3_PROFILING
|
#ifdef CGAL_TRIANGULATION_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_type n = number_of_vertices();
|
size_type n = number_of_vertices();
|
||||||
|
|
@ -695,7 +695,7 @@ namespace CGAL {
|
||||||
size_type n = number_of_vertices();
|
size_type n = number_of_vertices();
|
||||||
|
|
||||||
#ifdef CGAL_TRIANGULATION_3_PROFILING
|
#ifdef CGAL_TRIANGULATION_3_PROFILING
|
||||||
WallClockTimer t;
|
Wall_clock_timer t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Parallel
|
// Parallel
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue