summaryrefslogtreecommitdiff
path: root/include/gudhi_patches
diff options
context:
space:
mode:
Diffstat (limited to 'include/gudhi_patches')
-rw-r--r--include/gudhi_patches/Bottleneck_distance_CGAL_patches.txt3
-rw-r--r--include/gudhi_patches/CGAL/Convex_hull.h56
-rw-r--r--include/gudhi_patches/CGAL/Delaunay_triangulation.h933
-rw-r--r--include/gudhi_patches/CGAL/Epeck_d.h53
-rw-r--r--include/gudhi_patches/CGAL/Epick_d.h71
-rw-r--r--include/gudhi_patches/CGAL/IO/Triangulation_off_ostream.h320
-rw-r--r--include/gudhi_patches/CGAL/Kd_tree.h582
-rw-r--r--include/gudhi_patches/CGAL/Kd_tree_node.h586
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Cartesian_LA_base.h177
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Cartesian_LA_functors.h344
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Cartesian_base.h40
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Cartesian_change_FT.h117
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Cartesian_complete.h33
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Cartesian_filter_K.h79
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Cartesian_filter_NT.h93
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Cartesian_per_dimension.h33
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Cartesian_static_filters.h95
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Coaffine.h330
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Define_kernel_types.h50
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Dimension_base.h49
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Filtered_predicate2.h137
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/KernelD_converter.h199
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Kernel_2_interface.h104
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Kernel_3_interface.h102
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Kernel_d_interface.h298
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Kernel_object_converter.h134
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/LA_eigen/LA.h175
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/LA_eigen/constructors.h162
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Lazy_cartesian.h188
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Types/Aff_transformation.h59
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Types/Hyperplane.h159
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Types/Iso_box.h88
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Types/Line.h66
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Types/Ray.h66
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Types/Segment.h121
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Types/Sphere.h132
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Types/Weighted_point.h205
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/array.h165
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/avx4.h213
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h76
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_points.h211
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_vectors_from_vectors.h201
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_points_from_vectors.h164
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim.h58
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h164
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/mix.h46
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/sse2.h145
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/v2int.h181
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Vector/vector.h167
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h305
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Hyperplane_d.h131
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Point_d.h284
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Ref_count_obj.h120
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Segment_d.h133
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Sphere_d.h130
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Vector_d.h266
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Weighted_point_d.h129
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/function_objects_cartesian.h1355
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/functor_properties.h40
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/functor_tags.h363
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/static_int.h61
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/store_kernel.h104
-rw-r--r--include/gudhi_patches/CGAL/NewKernel_d/utils.h306
-rw-r--r--include/gudhi_patches/CGAL/Orthogonal_incremental_neighbor_search.h620
-rw-r--r--include/gudhi_patches/CGAL/Regular_triangulation.h1169
-rw-r--r--include/gudhi_patches/CGAL/Regular_triangulation_traits_adapter.h288
-rw-r--r--include/gudhi_patches/CGAL/TDS_full_cell_default_storage_policy.h99
-rw-r--r--include/gudhi_patches/CGAL/TDS_full_cell_mirror_storage_policy.h71
-rw-r--r--include/gudhi_patches/CGAL/Triangulation.h1424
-rw-r--r--include/gudhi_patches/CGAL/Triangulation_data_structure.h1603
-rw-r--r--include/gudhi_patches/CGAL/Triangulation_ds_full_cell.h311
-rw-r--r--include/gudhi_patches/CGAL/Triangulation_ds_vertex.h154
-rw-r--r--include/gudhi_patches/CGAL/Triangulation_face.h111
-rw-r--r--include/gudhi_patches/CGAL/Triangulation_full_cell.h148
-rw-r--r--include/gudhi_patches/CGAL/Triangulation_vertex.h128
-rw-r--r--include/gudhi_patches/CGAL/argument_swaps.h88
-rw-r--r--include/gudhi_patches/CGAL/determinant_of_vectors.h117
-rw-r--r--include/gudhi_patches/CGAL/internal/Combination_enumerator.h148
-rw-r--r--include/gudhi_patches/CGAL/internal/Static_or_dynamic_array.h116
-rw-r--r--include/gudhi_patches/CGAL/internal/Triangulation/Dummy_TDS.h49
-rw-r--r--include/gudhi_patches/CGAL/internal/Triangulation/Triangulation_ds_iterators.h154
-rw-r--r--include/gudhi_patches/CGAL/internal/Triangulation/utilities.h154
-rw-r--r--include/gudhi_patches/CGAL/iterator_from_indices.h75
-rw-r--r--include/gudhi_patches/CGAL/transforming_iterator.h123
-rw-r--r--include/gudhi_patches/CGAL/transforming_pair_iterator.h127
-rw-r--r--include/gudhi_patches/CGAL/typeset.h117
-rw-r--r--include/gudhi_patches/Tangential_complex_CGAL_patches.txt82
87 files changed, 19433 insertions, 0 deletions
diff --git a/include/gudhi_patches/Bottleneck_distance_CGAL_patches.txt b/include/gudhi_patches/Bottleneck_distance_CGAL_patches.txt
new file mode 100644
index 00000000..a588d113
--- /dev/null
+++ b/include/gudhi_patches/Bottleneck_distance_CGAL_patches.txt
@@ -0,0 +1,3 @@
+CGAL/Kd_tree.h
+CGAL/Kd_tree_node.h
+CGAL/Orthogonal_incremental_neighbor_search.h
diff --git a/include/gudhi_patches/CGAL/Convex_hull.h b/include/gudhi_patches/CGAL/Convex_hull.h
new file mode 100644
index 00000000..a8f91bf8
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Convex_hull.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+/* RANDOM DESIGN IDEAS:
+- Use a policy tag to choose for incremental with inserts only or
+ incremental with removals and inserts.
+ In the first case: use Triangulation for storage.
+ In the second case: use Delaunay !
+ In this second case, we must keeps the points that are inserted in the hull,
+ as they may become part of the boundary later on, when some points are removed.
+- Constructor with range argument uses quickhull.
+*/
+
+#ifndef CGAL_CONVEX_HULL_H
+#define CGAL_CONVEX_HULL_H
+
+namespace CGAL {
+
+template < class CHTraits, class TDS_ = Default >
+class Convex_hull
+{
+ typedef typename Maximal_dimension<typename CHTraits::Point_d>::type
+ Maximal_dimension_;
+ typedef typename Default::Get<TDS_, Triangulation_data_structure
+ < Maximal_dimension_,
+ Triangulation_vertex<CHTraits>,
+ Triangulation_full_cell<CHTraits> >
+ >::type TDS;
+ typedef Convex_hull<CHTraits, TDS_> Self;
+
+ typedef typename CHTraits::Coaffine_orientation_d
+ Coaffine_orientation_d;
+ typedef typename CHTraits::Orientation_d Orientation_d;
+
+public:
+};
+
+} //namespace CGAL
+
+#endif // CGAL_CONVEX_HULL_H
diff --git a/include/gudhi_patches/CGAL/Delaunay_triangulation.h b/include/gudhi_patches/CGAL/Delaunay_triangulation.h
new file mode 100644
index 00000000..071cd184
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Delaunay_triangulation.h
@@ -0,0 +1,933 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_DELAUNAY_COMPLEX_H
+#define CGAL_DELAUNAY_COMPLEX_H
+
+#include <CGAL/tss.h>
+#include <CGAL/Triangulation.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/Default.h>
+
+#include <boost/iterator/transform_iterator.hpp>
+
+#include <algorithm>
+
+namespace CGAL {
+
+template< typename DCTraits, typename _TDS = Default >
+class Delaunay_triangulation
+: public Triangulation<DCTraits,
+ typename Default::Get<_TDS, Triangulation_data_structure<
+ typename DCTraits::Dimension,
+ Triangulation_vertex<DCTraits>,
+ Triangulation_full_cell<DCTraits> >
+ >::type >
+{
+ typedef typename DCTraits::Dimension Maximal_dimension_;
+ typedef typename Default::Get<_TDS, Triangulation_data_structure<
+ Maximal_dimension_,
+ Triangulation_vertex<DCTraits>,
+ Triangulation_full_cell<DCTraits> >
+ >::type TDS;
+ typedef Triangulation<DCTraits, TDS> Base;
+ typedef Delaunay_triangulation<DCTraits, _TDS> Self;
+
+ typedef typename DCTraits::Side_of_oriented_sphere_d
+ Side_of_oriented_sphere_d;
+ typedef typename DCTraits::Orientation_d Orientation_d;
+
+public: // PUBLIC NESTED TYPES
+
+ typedef DCTraits Geom_traits;
+ typedef typename Base::Triangulation_ds Triangulation_ds;
+
+ typedef typename Base::Vertex Vertex;
+ typedef typename Base::Full_cell Full_cell;
+ typedef typename Base::Facet Facet;
+ typedef typename Base::Face Face;
+
+ typedef typename Base::Maximal_dimension Maximal_dimension;
+ typedef typename DCTraits::Point_d Point;
+ typedef typename DCTraits::Point_d Point_d;
+
+ typedef typename Base::Vertex_handle Vertex_handle;
+ typedef typename Base::Vertex_iterator Vertex_iterator;
+ typedef typename Base::Vertex_const_handle Vertex_const_handle;
+ typedef typename Base::Vertex_const_iterator Vertex_const_iterator;
+
+ typedef typename Base::Full_cell_handle Full_cell_handle;
+ typedef typename Base::Full_cell_iterator Full_cell_iterator;
+ typedef typename Base::Full_cell_const_handle Full_cell_const_handle;
+ typedef typename Base::Full_cell_const_iterator Full_cell_const_iterator;
+ typedef typename Base::Finite_full_cell_const_iterator
+ Finite_full_cell_const_iterator;
+
+ typedef typename Base::size_type size_type;
+ typedef typename Base::difference_type difference_type;
+
+ typedef typename Base::Locate_type Locate_type;
+
+ //Tag to distinguish triangulations with weighted_points
+ typedef Tag_false Weighted_tag;
+
+protected: // DATA MEMBERS
+
+
+public:
+
+ using typename Base::Rotor;
+ using Base::maximal_dimension;
+ using Base::are_incident_full_cells_valid;
+ using Base::coaffine_orientation_predicate;
+ using Base::reset_flat_orientation;
+ using Base::current_dimension;
+ //using Base::star;
+ //using Base::incident_full_cells;
+ using Base::geom_traits;
+ using Base::index_of_covertex;
+ //using Base::index_of_second_covertex;
+ using Base::infinite_vertex;
+ using Base::rotate_rotor;
+ using Base::insert_in_hole;
+ using Base::insert_outside_convex_hull_1;
+ using Base::is_infinite;
+ using Base::locate;
+ using Base::points_begin;
+ using Base::set_neighbors;
+ using Base::new_full_cell;
+ using Base::number_of_vertices;
+ using Base::orientation;
+ using Base::tds;
+ using Base::reorient_full_cells;
+ using Base::full_cell;
+ using Base::full_cells_begin;
+ using Base::full_cells_end;
+ using Base::finite_full_cells_begin;
+ using Base::finite_full_cells_end;
+ using Base::vertices_begin;
+ using Base::vertices_end;
+ // using Base::
+
+private:
+ //*** Side_of_oriented_subsphere_d ***
+ typedef typename Base::Flat_orientation_d Flat_orientation_d;
+ typedef typename Base::Construct_flat_orientation_d Construct_flat_orientation_d;
+ typedef typename DCTraits::In_flat_side_of_oriented_sphere_d In_flat_side_of_oriented_sphere_d;
+ // Wrapper
+ struct Side_of_oriented_subsphere_d
+ {
+ boost::optional<Flat_orientation_d>* fop;
+ Construct_flat_orientation_d cfo;
+ In_flat_side_of_oriented_sphere_d ifsoos;
+
+ Side_of_oriented_subsphere_d(
+ boost::optional<Flat_orientation_d>& x,
+ Construct_flat_orientation_d const&y,
+ In_flat_side_of_oriented_sphere_d const&z)
+ : fop(&x), cfo(y), ifsoos(z) {}
+
+ template<class Iter>
+ CGAL::Orientation operator()(Iter a, Iter b, const Point & p)const
+ {
+ if(!*fop)
+ *fop=cfo(a,b);
+ return ifsoos(fop->get(),a,b,p);
+ }
+ };
+public:
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS
+
+ Delaunay_triangulation(int dim, const Geom_traits &k = Geom_traits())
+ : Base(dim, k)
+ {
+ }
+
+ // With this constructor,
+ // the user can specify a Flat_orientation_d object to be used for
+ // orienting simplices of a specific dimension
+ // (= preset_flat_orientation_.first)
+ // It it used by the dark triangulations created by DT::remove
+ Delaunay_triangulation(
+ int dim,
+ const std::pair<int, const Flat_orientation_d *> &preset_flat_orientation,
+ const Geom_traits &k = Geom_traits())
+ : Base(dim, preset_flat_orientation, k)
+ {
+ }
+
+ ~Delaunay_triangulation() {}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ACCESS
+
+ // Not Documented
+ Side_of_oriented_subsphere_d side_of_oriented_subsphere_predicate() const
+ {
+ return Side_of_oriented_subsphere_d (
+ flat_orientation_,
+ geom_traits().construct_flat_orientation_d_object(),
+ geom_traits().in_flat_side_of_oriented_sphere_d_object()
+ );
+ }
+
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
+
+ Full_cell_handle remove(Vertex_handle);
+ Full_cell_handle remove(const Point & p, Full_cell_handle hint = Full_cell_handle())
+ {
+ Locate_type lt;
+ Face f(maximal_dimension());
+ Facet ft;
+ Full_cell_handle s = locate(p, lt, f, ft, hint);
+ if( Base::ON_VERTEX == lt )
+ {
+ return remove(s->vertex(f.index(0)));
+ }
+ return Full_cell_handle();
+ }
+
+ template< typename ForwardIterator >
+ void remove(ForwardIterator start, ForwardIterator end)
+ {
+ while( start != end )
+ remove(*start++);
+ }
+
+ // Not documented
+ void remove_decrease_dimension(Vertex_handle);
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSERTIONS
+
+ template< typename ForwardIterator >
+ size_type insert(ForwardIterator start, ForwardIterator end)
+ {
+ size_type n = number_of_vertices();
+ std::vector<Point> points(start, end);
+ spatial_sort(points.begin(), points.end(), geom_traits());
+ Full_cell_handle hint;
+ for( typename std::vector<Point>::const_iterator p = points.begin(); p != points.end(); ++p )
+ {
+ hint = insert(*p, hint)->full_cell();
+ }
+ return number_of_vertices() - n;
+ }
+ Vertex_handle insert(const Point &, Locate_type, const Face &, const Facet &, Full_cell_handle);
+ Vertex_handle insert(const Point & p, Full_cell_handle start = Full_cell_handle())
+ {
+ Locate_type lt;
+ Face f(maximal_dimension());
+ Facet ft;
+ Full_cell_handle s = locate(p, lt, f, ft, start);
+ return insert(p, lt, f, ft, s);
+ }
+ Vertex_handle insert(const Point & p, Vertex_handle hint)
+ {
+ CGAL_assertion( Vertex_handle() != hint );
+ return insert(p, hint->full_cell());
+ }
+ Vertex_handle insert_outside_affine_hull(const Point &);
+ Vertex_handle insert_in_conflicting_cell(const Point &, Full_cell_handle);
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - GATHERING CONFLICTING SIMPLICES
+
+ bool is_in_conflict(const Point &, Full_cell_const_handle) const;
+ template< class OrientationPredicate >
+ Oriented_side perturbed_side_of_positive_sphere(const Point &,
+ Full_cell_const_handle, const OrientationPredicate &) const;
+
+ template< typename OutputIterator >
+ Facet compute_conflict_zone(const Point &, Full_cell_handle, OutputIterator) const;
+
+ template < typename OrientationPredicate, typename SideOfOrientedSpherePredicate >
+ class Conflict_predicate
+ {
+ const Self & dc_;
+ const Point & p_;
+ OrientationPredicate ori_;
+ SideOfOrientedSpherePredicate side_of_s_;
+ int cur_dim_;
+ public:
+ Conflict_predicate(
+ const Self & dc,
+ const Point & p,
+ const OrientationPredicate & ori,
+ const SideOfOrientedSpherePredicate & side)
+ : dc_(dc), p_(p), ori_(ori), side_of_s_(side), cur_dim_(dc.current_dimension()) {}
+
+ inline
+ bool operator()(Full_cell_const_handle s) const
+ {
+ bool ok;
+ if( ! dc_.is_infinite(s) )
+ {
+ Oriented_side side = side_of_s_(dc_.points_begin(s), dc_.points_begin(s) + cur_dim_ + 1, p_);
+ if( ON_POSITIVE_SIDE == side )
+ ok = true;
+ else if( ON_NEGATIVE_SIDE == side )
+ ok = false;
+ else
+ ok = ON_POSITIVE_SIDE == dc_.perturbed_side_of_positive_sphere<OrientationPredicate>(p_, s, ori_);
+ }
+ else
+ {
+ typedef typename Full_cell::Vertex_handle_const_iterator VHCI;
+ typedef Substitute_point_in_vertex_iterator<VHCI> F;
+ F spivi(dc_.infinite_vertex(), &p_);
+
+ Orientation o = ori_(
+ boost::make_transform_iterator(s->vertices_begin(), spivi),
+ boost::make_transform_iterator(s->vertices_begin() + cur_dim_ + 1,
+ spivi));
+
+ if( POSITIVE == o )
+ ok = true;
+ else if( o == NEGATIVE )
+ ok = false;
+ else
+ ok = (*this)(s->neighbor( s->index( dc_.infinite_vertex() ) ));
+ }
+ return ok;
+ }
+ };
+
+ template < typename ConflictPredicate >
+ class Conflict_traversal_predicate
+ {
+ const Self & dc_;
+ const ConflictPredicate & pred_;
+ public:
+ Conflict_traversal_predicate(const Self & dc, const ConflictPredicate & pred)
+ : dc_(dc), pred_(pred)
+ {}
+ inline
+ bool operator()(const Facet & f) const
+ {
+ return pred_(dc_.full_cell(f)->neighbor(dc_.index_of_covertex(f)));
+ }
+ };
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
+
+ bool is_valid(bool verbose = false, int level = 0) const;
+
+private:
+ // Some internal types to shorten notation
+ typedef typename Base::Coaffine_orientation_d Coaffine_orientation_d;
+ using Base::flat_orientation_;
+ typedef Conflict_predicate<Coaffine_orientation_d, Side_of_oriented_subsphere_d>
+ Conflict_pred_in_subspace;
+ typedef Conflict_predicate<Orientation_d, Side_of_oriented_sphere_d>
+ Conflict_pred_in_fullspace;
+ typedef Conflict_traversal_predicate<Conflict_pred_in_subspace>
+ Conflict_traversal_pred_in_subspace;
+ typedef Conflict_traversal_predicate<Conflict_pred_in_fullspace>
+ Conflict_traversal_pred_in_fullspace;
+};
+
+// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+// FUNCTIONS THAT ARE MEMBER METHODS:
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
+
+template< typename DCTraits, typename TDS >
+typename Delaunay_triangulation<DCTraits, TDS>::Full_cell_handle
+Delaunay_triangulation<DCTraits, TDS>
+::remove( Vertex_handle v )
+{
+ CGAL_precondition( ! is_infinite(v) );
+ CGAL_expensive_precondition( is_vertex(v) );
+
+ // THE CASE cur_dim == 0
+ if( 0 == current_dimension() )
+ {
+ remove_decrease_dimension(v);
+ return Full_cell_handle();
+ }
+ else if( 1 == current_dimension() )
+ { // THE CASE cur_dim == 1
+ if( 2 == number_of_vertices() )
+ {
+ remove_decrease_dimension(v);
+ return Full_cell_handle();
+ }
+ Full_cell_handle left = v->full_cell();
+ if( 0 == left->index(v) )
+ left = left->neighbor(1);
+ CGAL_assertion( 1 == left->index(v) );
+ Full_cell_handle right = left->neighbor(0);
+
+ tds().associate_vertex_with_full_cell(left, 1, right->vertex(1));
+ set_neighbors(left, 0, right->neighbor(0), right->mirror_index(0));
+
+ tds().delete_vertex(v);
+ tds().delete_full_cell(right);
+ return left;
+ }
+
+ // THE CASE cur_dim >= 2
+ // Gather the finite vertices sharing an edge with |v|
+ typedef typename Base::template Full_cell_set<Full_cell_handle> Simplices;
+ Simplices simps;
+ std::back_insert_iterator<Simplices> out(simps);
+ tds().incident_full_cells(v, out);
+ typedef std::set<Vertex_handle> Vertex_set;
+ Vertex_set verts;
+ Vertex_handle vh;
+ for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
+ for( int i = 0; i <= current_dimension(); ++i )
+ {
+ vh = (*it)->vertex(i);
+ if( is_infinite(vh) )
+ continue;
+ if( vh == v )
+ continue;
+ verts.insert(vh);
+ }
+
+ // After gathering finite neighboring vertices, create their Dark Delaunay triangulation
+ typedef Triangulation_vertex<Geom_traits, Vertex_handle> Dark_vertex_base;
+ typedef Triangulation_full_cell<Geom_traits,
+ internal::Triangulation::Dark_full_cell_data<Self> > Dark_full_cell_base;
+ typedef Triangulation_data_structure<Maximal_dimension, Dark_vertex_base, Dark_full_cell_base> Dark_tds;
+ typedef Delaunay_triangulation<DCTraits, Dark_tds> Dark_triangulation;
+ typedef typename Dark_triangulation::Face Dark_face;
+ typedef typename Dark_triangulation::Facet Dark_facet;
+ typedef typename Dark_triangulation::Vertex_handle Dark_v_handle;
+ typedef typename Dark_triangulation::Full_cell_handle Dark_s_handle;
+
+ // If flat_orientation_ is defined, we give it the Dark triangulation
+ // so that the orientation it uses for "current_dimension()"-simplices is
+ // coherent with the global triangulation
+ Dark_triangulation dark_side(
+ maximal_dimension(),
+ flat_orientation_ ?
+ std::pair<int, const Flat_orientation_d *>(current_dimension(), flat_orientation_.get_ptr())
+ : std::pair<int, const Flat_orientation_d *>((std::numeric_limits<int>::max)(), (Flat_orientation_d*) NULL) );
+
+ Dark_s_handle dark_s;
+ Dark_v_handle dark_v;
+ typedef std::map<Vertex_handle, Dark_v_handle> Vertex_map;
+ Vertex_map light_to_dark;
+ typename Vertex_set::iterator vit = verts.begin();
+ while( vit != verts.end() )
+ {
+ dark_v = dark_side.insert((*vit)->point(), dark_s);
+ dark_s = dark_v->full_cell();
+ dark_v->data() = *vit;
+ light_to_dark[*vit] = dark_v;
+ ++vit;
+ }
+
+ if( dark_side.current_dimension() != current_dimension() )
+ {
+ CGAL_assertion( dark_side.current_dimension() + 1 == current_dimension() );
+ // Here, the finite neighbors of |v| span a affine subspace of
+ // dimension one less than the current dimension. Two cases are possible:
+ if( (size_type)(verts.size() + 1) == number_of_vertices() )
+ {
+ remove_decrease_dimension(v);
+ return Full_cell_handle();
+ }
+ else
+ { // |v| is strictly outside the convex hull of the rest of the points. This is an
+ // easy case: first, modify the finite full_cells, then, delete the infinite ones.
+ // We don't even need the Dark triangulation.
+ Simplices infinite_simps;
+ {
+ Simplices finite_simps;
+ for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
+ if( is_infinite(*it) )
+ infinite_simps.push_back(*it);
+ else
+ finite_simps.push_back(*it);
+ simps.swap(finite_simps);
+ } // now, simps only contains finite simplices
+ // First, modify the finite full_cells:
+ for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
+ {
+ int v_idx = (*it)->index(v);
+ tds().associate_vertex_with_full_cell(*it, v_idx, infinite_vertex());
+ }
+ // Make the handles to infinite full cells searchable
+ infinite_simps.make_searchable();
+ // Then, modify the neighboring relation
+ for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
+ {
+ for( int i = 0; i <= current_dimension(); ++i )
+ {
+ if (is_infinite((*it)->vertex(i)))
+ continue;
+ (*it)->vertex(i)->set_full_cell(*it);
+ Full_cell_handle n = (*it)->neighbor(i);
+ // Was |n| a finite full cell prior to removing |v| ?
+ if( ! infinite_simps.contains(n) )
+ continue;
+ int n_idx = n->index(v);
+ set_neighbors(*it, i, n->neighbor(n_idx), n->neighbor(n_idx)->index(n));
+ }
+ }
+ Full_cell_handle ret_s;
+ // Then, we delete the infinite full_cells
+ for( typename Simplices::iterator it = infinite_simps.begin(); it != infinite_simps.end(); ++it )
+ tds().delete_full_cell(*it);
+ tds().delete_vertex(v);
+ return simps.front();
+ }
+ }
+ else // From here on, dark_side.current_dimension() == current_dimension()
+ {
+ dark_side.infinite_vertex()->data() = infinite_vertex();
+ light_to_dark[infinite_vertex()] = dark_side.infinite_vertex();
+ }
+
+ // Now, compute the conflict zone of v->point() in
+ // the dark side. This is precisely the set of full_cells
+ // that we have to glue back into the light side.
+ Dark_face dark_f(dark_side.maximal_dimension());
+ Dark_facet dark_ft;
+ typename Dark_triangulation::Locate_type lt;
+ dark_s = dark_side.locate(v->point(), lt, dark_f, dark_ft);
+ CGAL_assertion( lt != Dark_triangulation::ON_VERTEX
+ && lt != Dark_triangulation::OUTSIDE_AFFINE_HULL );
+
+ // |ret_s| is the full_cell that we return
+ Dark_s_handle dark_ret_s = dark_s;
+ Full_cell_handle ret_s;
+
+ typedef typename Base::template Full_cell_set<Dark_s_handle> Dark_full_cells;
+ Dark_full_cells 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);
+ // Make the dark simplices in the conflict zone searchable
+ conflict_zone.make_searchable();
+
+ // THE FOLLOWING SHOULD MAYBE GO IN TDS.
+ // Here is the plan:
+ // 1. Pick any Facet from boundary of the light zone
+ // 2. Find corresponding Facet on boundary of dark zone
+ // 3. stitch.
+
+ // 1. Build a facet on the boudary of the light zone:
+ Full_cell_handle light_s = *simps.begin();
+ Facet light_ft(light_s, light_s->index(v));
+
+ // 2. Find corresponding Dark_facet on boundary of the dark zone
+ Dark_full_cells dark_incident_s;
+ for( int i = 0; i <= current_dimension(); ++i )
+ {
+ if( index_of_covertex(light_ft) == i )
+ continue;
+ Dark_v_handle dark_v = light_to_dark[full_cell(light_ft)->vertex(i)];
+ dark_incident_s.clear();
+ dark_out = std::back_inserter(dark_incident_s);
+ dark_side.tds().incident_full_cells(dark_v, dark_out);
+ for( typename Dark_full_cells::iterator it = dark_incident_s.begin(); it != dark_incident_s.end(); ++it )
+ {
+ (*it)->data().count_ += 1;
+ }
+ }
+
+ for( typename Dark_full_cells::iterator it = dark_incident_s.begin(); it != dark_incident_s.end(); ++it )
+ {
+ if( current_dimension() != (*it)->data().count_ )
+ continue;
+ if( ! conflict_zone.contains(*it) )
+ continue;
+ // We found a full_cell incident to the dark facet corresponding to the light facet |light_ft|
+ int ft_idx = 0;
+ while( light_s->has_vertex( (*it)->vertex(ft_idx)->data() ) )
+ ++ft_idx;
+ dark_ft = Dark_facet(*it, ft_idx);
+ break;
+ }
+ // Pre-3. Now, we are ready to traverse both boundary and do the stiching.
+
+ // But first, we create the new full_cells in the light triangulation,
+ // with as much adjacency information as possible.
+
+ // Create new full_cells with vertices
+ for( typename Dark_full_cells::iterator it = conflict_zone.begin(); it != conflict_zone.end(); ++it )
+ {
+ Full_cell_handle new_s = new_full_cell();
+ (*it)->data().light_copy_ = new_s;
+ for( int i = 0; i <= current_dimension(); ++i )
+ tds().associate_vertex_with_full_cell(new_s, i, (*it)->vertex(i)->data());
+ if( dark_ret_s == *it )
+ ret_s = new_s;
+ }
+
+ // Setup adjacencies inside the hole
+ for( typename Dark_full_cells::iterator it = conflict_zone.begin(); it != conflict_zone.end(); ++it )
+ {
+ Full_cell_handle new_s = (*it)->data().light_copy_;
+ for( int i = 0; i <= current_dimension(); ++i )
+ if( conflict_zone.contains((*it)->neighbor(i)) )
+ tds().set_neighbors(new_s, i, (*it)->neighbor(i)->data().light_copy_, (*it)->mirror_index(i));
+ }
+
+ // 3. Stitch
+ simps.make_searchable();
+ typedef std::queue<std::pair<Facet, Dark_facet> > Queue;
+ Queue q;
+ q.push(std::make_pair(light_ft, dark_ft));
+ dark_s = dark_side.full_cell(dark_ft);
+ int dark_i = dark_side.index_of_covertex(dark_ft);
+ // mark dark_ft as visited:
+ // TODO try by marking with Dark_v_handle (vertex)
+ dark_s->neighbor(dark_i)->set_neighbor(dark_s->mirror_index(dark_i), Dark_s_handle());
+ while( ! q.empty() )
+ {
+ std::pair<Facet, Dark_facet> p = q.front();
+ q.pop();
+ light_ft = p.first;
+ dark_ft = p.second;
+ light_s = full_cell(light_ft);
+ int light_i = index_of_covertex(light_ft);
+ dark_s = dark_side.full_cell(dark_ft);
+ int dark_i = dark_side.index_of_covertex(dark_ft);
+ Full_cell_handle light_n = light_s->neighbor(light_i);
+ set_neighbors(dark_s->data().light_copy_, dark_i, light_n, light_s->mirror_index(light_i));
+ for( int di = 0; di <= current_dimension(); ++di )
+ {
+ if( di == dark_i )
+ continue;
+ int li = light_s->index(dark_s->vertex(di)->data());
+ Rotor light_r(light_s, li, light_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))))
+ light_r = rotate_rotor(light_r);
+
+ while (conflict_zone.contains(cpp11::get<0>(dark_r)->neighbor(cpp11::get<1>(dark_r))))
+ dark_r = dark_side.rotate_rotor(dark_r);
+
+ Dark_s_handle dark_ns = cpp11::get<0>(dark_r);
+ int dark_ni = cpp11::get<1>(dark_r);
+ Full_cell_handle light_ns = cpp11::get<0>(light_r);
+ int light_ni = cpp11::get<1>(light_r);
+ // mark dark_r as visited:
+ // TODO try by marking with Dark_v_handle (vertex)
+ Dark_s_handle outside = dark_ns->neighbor(dark_ni);
+ Dark_v_handle mirror = dark_ns->mirror_vertex(dark_ni, current_dimension());
+ int dn = outside->index(mirror);
+ if( Dark_s_handle() == outside->neighbor(dn) )
+ continue;
+ outside->set_neighbor(dn, Dark_s_handle());
+ q.push(std::make_pair(Facet(light_ns, light_ni), Dark_facet(dark_ns, dark_ni)));
+ }
+ }
+ tds().delete_full_cells(simps.begin(), simps.end());
+ tds().delete_vertex(v);
+ return ret_s;
+}
+
+template< typename DCTraits, typename TDS >
+void
+Delaunay_triangulation<DCTraits, TDS>
+::remove_decrease_dimension(Vertex_handle v)
+{
+ CGAL_precondition( current_dimension() >= 0 );
+ tds().remove_decrease_dimension(v, infinite_vertex());
+ // reset the predicates:
+ reset_flat_orientation();
+ if( 1 <= current_dimension() )
+ {
+ Full_cell_handle inf_v_cell = infinite_vertex()->full_cell();
+ int inf_v_index = inf_v_cell->index(infinite_vertex());
+ Full_cell_handle s = inf_v_cell->neighbor(inf_v_index);
+ Orientation o = orientation(s);
+ CGAL_assertion( ZERO != o );
+ if( NEGATIVE == o )
+ reorient_full_cells();
+ }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSERTIONS
+
+template< typename DCTraits, typename TDS >
+typename Delaunay_triangulation<DCTraits, TDS>::Vertex_handle
+Delaunay_triangulation<DCTraits, TDS>
+::insert(const Point & p, Locate_type lt, const Face & f, const Facet &, Full_cell_handle s)
+{
+ switch( lt )
+ {
+ case Base::OUTSIDE_AFFINE_HULL:
+ return insert_outside_affine_hull(p);
+ break;
+ case Base::ON_VERTEX:
+ {
+ Vertex_handle v = s->vertex(f.index(0));
+ v->set_point(p);
+ return v;
+ break;
+ }
+ default:
+ if( 1 == current_dimension() )
+ {
+ if( Base::OUTSIDE_CONVEX_HULL == lt )
+ {
+ return insert_outside_convex_hull_1(p, s);
+ }
+ Vertex_handle v = tds().insert_in_full_cell(s);
+ v->set_point(p);
+ return v;
+ }
+ else
+ return insert_in_conflicting_cell(p, s);
+ break;
+ }
+}
+
+/*
+[Undocumented function]
+
+Inserts the point `p` in the Delaunay triangulation. Returns a handle to the
+(possibly newly created) vertex at that position.
+\pre The point `p`
+must lie outside the affine hull of the Delaunay triangulation. This implies that
+`dt`.`current_dimension()` must be less than `dt`.`maximal_dimension()`.
+*/
+template< typename DCTraits, typename TDS >
+typename Delaunay_triangulation<DCTraits, TDS>::Vertex_handle
+Delaunay_triangulation<DCTraits, TDS>
+::insert_outside_affine_hull(const Point & p)
+{
+ // we don't use Base::insert_outside_affine_hull(...) because here, we
+ // also need to reset the side_of_oriented_subsphere functor.
+ CGAL_precondition( current_dimension() < maximal_dimension() );
+ Vertex_handle v = tds().insert_increase_dimension(infinite_vertex());
+ // reset the predicates:
+ reset_flat_orientation();
+ v->set_point(p);
+ if( current_dimension() >= 1 )
+ {
+ Full_cell_handle inf_v_cell = infinite_vertex()->full_cell();
+ int inf_v_index = inf_v_cell->index(infinite_vertex());
+ Full_cell_handle s = inf_v_cell->neighbor(inf_v_index);
+ Orientation o = orientation(s);
+ CGAL_assertion( ZERO != o );
+ if( NEGATIVE == o )
+ reorient_full_cells();
+
+ // We just inserted the second finite point and the right infinite
+ // cell is like : (inf_v, v), but we want it to be (v, inf_v) to be
+ // consistent with the rest of the cells
+ if (current_dimension() == 1)
+ {
+ // Is "inf_v_cell" the right infinite cell?
+ // Then inf_v_index should be 1
+ if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
+ && inf_v_index == 0)
+ {
+ inf_v_cell->swap_vertices(
+ current_dimension() - 1, current_dimension());
+ }
+ // Otherwise, let's find the right infinite cell
+ else
+ {
+ inf_v_cell = inf_v_cell->neighbor((inf_v_index + 1) % 2);
+ inf_v_index = inf_v_cell->index(infinite_vertex());
+ // Is "inf_v_cell" the right infinite cell?
+ // Then inf_v_index should be 1
+ if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
+ && inf_v_index == 0)
+ {
+ inf_v_cell->swap_vertices(
+ current_dimension() - 1, current_dimension());
+ }
+ }
+ }
+ }
+ return v;
+}
+
+/*!
+[Undocumented function]
+
+Inserts the point `p` in the Delaunay triangulation. Returns a handle to the
+(possibly newly created) vertex at that position.
+\pre The point `p` must be in conflict with the full cell `c`.
+*/
+template< typename DCTraits, typename TDS >
+typename Delaunay_triangulation<DCTraits, TDS>::Vertex_handle
+Delaunay_triangulation<DCTraits, TDS>
+::insert_in_conflicting_cell(const Point & p, Full_cell_handle s)
+{
+ CGAL_precondition(is_in_conflict(p, s));
+
+ // for storing conflicting full_cells.
+ typedef std::vector<Full_cell_handle> Full_cell_h_vector;
+ CGAL_STATIC_THREAD_LOCAL_VARIABLE(Full_cell_h_vector,cs,0);
+ cs.clear();
+
+ std::back_insert_iterator<Full_cell_h_vector> out(cs);
+ Facet ft = compute_conflict_zone(p, s, out);
+ return insert_in_hole(p, cs.begin(), cs.end(), ft);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GATHERING CONFLICTING SIMPLICES
+
+// NOT DOCUMENTED
+template< typename DCTraits, typename TDS >
+template< typename OrientationPred >
+Oriented_side
+Delaunay_triangulation<DCTraits, TDS>
+::perturbed_side_of_positive_sphere(const Point & p, Full_cell_const_handle s,
+ const OrientationPred & ori) const
+{
+ CGAL_precondition_msg( ! is_infinite(s), "full cell must be finite");
+ CGAL_expensive_precondition( POSITIVE == orientation(s) );
+ typedef std::vector<const Point *> Points;
+ Points points(current_dimension() + 2);
+ int i(0);
+ for( ; i <= current_dimension(); ++i )
+ points[i] = &(s->vertex(i)->point());
+ points[i] = &p;
+ std::sort(points.begin(), points.end(),
+ internal::Triangulation::Compare_points_for_perturbation<Self>(*this));
+ typename Points::const_reverse_iterator cut_pt = points.rbegin();
+ Points test_points;
+ while( cut_pt != points.rend() )
+ {
+ if( &p == *cut_pt )
+ // because the full_cell "s" is assumed to be positively oriented
+ return ON_NEGATIVE_SIDE; // we consider |p| to lie outside the sphere
+ test_points.clear();
+ typename Base::Point_const_iterator spit = points_begin(s);
+ int adjust_sign = -1;
+ for( i = 0; i < current_dimension(); ++i )
+ {
+ if( &(*spit) == *cut_pt )
+ {
+ ++spit;
+ adjust_sign = (((current_dimension() + i) % 2) == 0) ? -1 : +1;
+ }
+ test_points.push_back(&(*spit));
+ ++spit;
+ }
+ test_points.push_back(&p);
+
+ typedef typename CGAL::Iterator_project<typename Points::iterator,
+ internal::Triangulation::Point_from_pointer<Self>,
+ const Point &, const Point *> Point_pointer_iterator;
+
+ Orientation ori_value = ori(
+ Point_pointer_iterator(test_points.begin()),
+ Point_pointer_iterator(test_points.end()));
+
+ if( ZERO != ori_value )
+ return Oriented_side( - adjust_sign * ori_value );
+
+ ++cut_pt;
+ }
+ CGAL_assertion(false); // we should never reach here
+ return ON_NEGATIVE_SIDE;
+}
+
+template< typename DCTraits, typename TDS >
+bool
+Delaunay_triangulation<DCTraits, TDS>
+::is_in_conflict(const Point & p, Full_cell_const_handle s) const
+{
+ CGAL_precondition( 2 <= current_dimension() );
+ if( current_dimension() < maximal_dimension() )
+ {
+ Conflict_pred_in_subspace c(*this, p, coaffine_orientation_predicate(), side_of_oriented_subsphere_predicate());
+ return c(s);
+ }
+ else
+ {
+ Orientation_d ori = geom_traits().orientation_d_object();
+ Side_of_oriented_sphere_d side = geom_traits().side_of_oriented_sphere_d_object();
+ Conflict_pred_in_fullspace c(*this, p, ori, side);
+ return c(s);
+ }
+}
+
+template< typename DCTraits, typename TDS >
+template< typename OutputIterator >
+typename Delaunay_triangulation<DCTraits, TDS>::Facet
+Delaunay_triangulation<DCTraits, TDS>
+::compute_conflict_zone(const Point & p, Full_cell_handle s, OutputIterator out) const
+{
+ CGAL_precondition( 2 <= current_dimension() );
+ if( current_dimension() < maximal_dimension() )
+ {
+ Conflict_pred_in_subspace c(*this, p, coaffine_orientation_predicate(), side_of_oriented_subsphere_predicate());
+ Conflict_traversal_pred_in_subspace tp(*this, c);
+ return tds().gather_full_cells(s, tp, out);
+ }
+ else
+ {
+ Orientation_d ori = geom_traits().orientation_d_object();
+ Side_of_oriented_sphere_d side = geom_traits().side_of_oriented_sphere_d_object();
+ Conflict_pred_in_fullspace c(*this, p, ori, side);
+ Conflict_traversal_pred_in_fullspace tp(*this, c);
+ return tds().gather_full_cells(s, tp, out);
+ }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
+
+template< typename DCTraits, typename TDS >
+bool
+Delaunay_triangulation<DCTraits, TDS>
+::is_valid(bool verbose, int level) const
+{
+ if (!Base::is_valid(verbose, level))
+ return false;
+
+ int dim = current_dimension();
+ if (dim == maximal_dimension())
+ {
+ for (Finite_full_cell_const_iterator cit = this->finite_full_cells_begin() ;
+ cit != this->finite_full_cells_end() ; ++cit )
+ {
+ Full_cell_const_handle ch = cit.base();
+ for(int i = 0; i < dim+1 ; ++i )
+ {
+ // If the i-th neighbor is not an infinite cell
+ Vertex_handle opposite_vh =
+ ch->neighbor(i)->vertex(ch->neighbor(i)->index(ch));
+ if (!is_infinite(opposite_vh))
+ {
+ Side_of_oriented_sphere_d side =
+ geom_traits().side_of_oriented_sphere_d_object();
+ if (side(Point_const_iterator(ch->vertices_begin()),
+ Point_const_iterator(ch->vertices_end()),
+ opposite_vh->point()) == ON_BOUNDED_SIDE)
+ {
+ if (verbose)
+ CGAL_warning_msg(false, "Non-empty sphere");
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+
+} //namespace CGAL
+
+#endif // CGAL_DELAUNAY_COMPLEX_H
diff --git a/include/gudhi_patches/CGAL/Epeck_d.h b/include/gudhi_patches/CGAL/Epeck_d.h
new file mode 100644
index 00000000..52bce84c
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Epeck_d.h
@@ -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
diff --git a/include/gudhi_patches/CGAL/Epick_d.h b/include/gudhi_patches/CGAL/Epick_d.h
new file mode 100644
index 00000000..64438539
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Epick_d.h
@@ -0,0 +1,71 @@
+// 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_EPICK_D_H
+#define CGAL_EPICK_D_H
+#include <CGAL/NewKernel_d/Cartesian_base.h>
+#include <CGAL/NewKernel_d/Cartesian_static_filters.h>
+#include <CGAL/NewKernel_d/Cartesian_filter_K.h>
+#include <CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h>
+#include <CGAL/NewKernel_d/Kernel_d_interface.h>
+#include <CGAL/internal/Exact_type_selector.h>
+#include <CGAL/Interval_nt.h>
+#include <CGAL/NewKernel_d/Types/Weighted_point.h>
+
+
+namespace CGAL {
+#define CGAL_BASE \
+ Cartesian_filter_K< \
+ Cartesian_base_d<double, Dim>, \
+ Cartesian_base_d<Interval_nt_advanced, Dim>, \
+ Cartesian_base_d<internal::Exact_field_selector<double>::Type, Dim> \
+ >
+template<class Dim>
+struct Epick_d_help1
+: CGAL_BASE
+{
+ CGAL_CONSTEXPR Epick_d_help1(){}
+ CGAL_CONSTEXPR Epick_d_help1(int d):CGAL_BASE(d){}
+};
+#undef CGAL_BASE
+#define CGAL_BASE \
+ Cartesian_static_filters<Dim,Epick_d_help1<Dim>,Epick_d_help2<Dim> >
+template<class Dim>
+struct Epick_d_help2
+: CGAL_BASE
+{
+ CGAL_CONSTEXPR Epick_d_help2(){}
+ CGAL_CONSTEXPR Epick_d_help2(int d):CGAL_BASE(d){}
+};
+#undef CGAL_BASE
+#define CGAL_BASE \
+ Kernel_d_interface< \
+ Cartesian_wrap< \
+ Epick_d_help2<Dim>, \
+ Epick_d<Dim> > >
+template<class Dim>
+struct Epick_d
+: CGAL_BASE
+{
+ CGAL_CONSTEXPR Epick_d(){}
+ CGAL_CONSTEXPR Epick_d(int d):CGAL_BASE(d){}
+};
+#undef CGAL_BASE
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/IO/Triangulation_off_ostream.h b/include/gudhi_patches/CGAL/IO/Triangulation_off_ostream.h
new file mode 100644
index 00000000..701f0820
--- /dev/null
+++ b/include/gudhi_patches/CGAL/IO/Triangulation_off_ostream.h
@@ -0,0 +1,320 @@
+// 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 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) : Clement Jamin
+
+
+#ifndef CGAL_TRIANGULATION_IO_H
+#define CGAL_TRIANGULATION_IO_H
+
+#include <CGAL/Epick_d.h>
+#include <CGAL/Triangulation.h>
+#include <sstream>
+#include <iostream>
+
+namespace CGAL {
+
+namespace Triangulation_IO
+{
+// TODO: test if the stream is binary or text?
+template<typename Traits, typename P>
+int
+output_point(std::ostream & os, const Traits &traits, const P & p)
+{
+ typedef typename Traits::Compute_coordinate_d Ccd;
+ const Ccd ccd = traits.compute_coordinate_d_object();
+ const int dim = traits.point_dimension_d_object()(p);
+ if (dim > 0)
+ {
+ os << ccd(p, 0);
+ for (int i = 1 ; i < dim ; ++i)
+ os << " " << CGAL::to_double(ccd(p, i));
+ }
+ return dim;
+}
+
+// TODO: test if the stream is binary or text?
+template<typename Traits, typename P>
+int
+output_weighted_point(std::ostream & os, const Traits &traits, const P & p,
+ bool output_weight = true)
+{
+ typedef typename Traits::Compute_coordinate_d Ccd;
+ typename Traits::Construct_point_d cp =
+ traits.construct_point_d_object();
+ typename Traits::Compute_weight_d pt_weight = traits.compute_weight_d_object();
+ const Ccd ccd = traits.compute_coordinate_d_object();
+ const int dim = traits.point_dimension_d_object()(p);
+ if (dim > 0)
+ {
+ output_point(os, traits, p);
+ if (output_weight)
+ os << " " << pt_weight(p);
+ }
+ return dim;
+}
+
+// TODO: test if the stream is binary or text?
+template<typename Traits, typename FCH>
+void
+output_full_cell(std::ostream & os, const Traits &traits, const FCH & fch,
+ bool output_weights = false)
+{
+ typename FCH::value_type::Vertex_handle_iterator vit = fch->vertices_begin();
+ for( ; vit != fch->vertices_end(); ++vit )
+ {
+ int dim;
+ if (output_weights)
+ dim = output_weighted_point(os, traits, (*vit)->point());
+ else
+ dim = output_point(os, traits, (*vit)->point());
+ if (dim > 0)
+ os << std::endl;
+ }
+}
+
+// TODO: test if the stream is binary or text?
+/*template<typename Traits, typename P>
+void
+input_point(std::istream & is, const Traits &traits, P & p)
+{
+ typedef typename Traits::FT FT;
+ std::vector<FT> coords;
+
+ std::string line;
+ for(;;)
+ {
+ if (!std::getline(is, line))
+ return is;
+ if (line != "")
+ break;
+ }
+ std::stringstream line_sstr(line);
+ FT temp;
+ while (line_sstr >> temp)
+ coords.push_back(temp);
+
+ p = traits.construct_point_d_object()(coords.begin(), coords.end());
+}*/
+
+} // namespace Triangulation_IO
+
+///////////////////////////////////////////////////////////////
+// TODO: replace these operator>> by an "input_point" function
+///////////////////////////////////////////////////////////////
+
+// TODO: test if the stream is binary or text?
+template<typename K>
+std::istream &
+operator>>(std::istream &is, typename Wrap::Point_d<K> & p)
+{
+ typedef typename Wrap::Point_d<K> P;
+ typedef typename K::FT FT;
+ std::vector<FT> coords;
+
+ std::string line;
+ for(;;)
+ {
+ if (!std::getline(is, line))
+ return is;
+ if (line != "")
+ break;
+ }
+ std::stringstream line_sstr(line);
+ FT temp;
+ while (line_sstr >> temp)
+ coords.push_back(temp);
+
+ p = P(coords.begin(), coords.end());
+ return is;
+}
+
+// TODO: test if the stream is binary or text?
+template<typename K>
+std::istream &
+operator>>(std::istream &is, typename Wrap::Weighted_point_d<K> & wp)
+{
+ typedef typename Wrap::Point_d<K> P;
+ typedef typename Wrap::Weighted_point_d<K> WP;
+ typedef typename K::FT FT;
+
+ std::string line;
+ for(;;)
+ {
+ if (!std::getline(is, line))
+ return is;
+ if (line != "")
+ break;
+ }
+ std::stringstream line_sstr(line);
+ FT temp;
+ std::vector<FT> coords;
+ while (line_sstr >> temp)
+ coords.push_back(temp);
+
+ typename std::vector<FT>::iterator last = coords.end() - 1;
+ P p = P(coords.begin(), last);
+ wp = WP(p, *last);
+
+ return is;
+}
+
+// TODO: test if the stream is binary or text?
+template<typename K>
+std::istream &
+operator>>(std::istream &is, typename Wrap::Vector_d<K> & v)
+{
+ typedef typename Wrap::Vector_d<K> V;
+ typedef typename K::FT FT;
+ std::vector<FT> coords;
+
+ std::string line;
+ for (;;)
+ {
+ if (!std::getline(is, line))
+ return is;
+ if (line != "")
+ break;
+ }
+ std::stringstream line_sstr(line);
+ FT temp;
+ while (line_sstr >> temp)
+ coords.push_back(temp);
+
+ v = V(coords.begin(), coords.end());
+ return is;
+}
+
+template < class GT, class TDS >
+std::ostream &
+export_triangulation_to_off(std::ostream & os,
+ const Triangulation<GT,TDS> & tr,
+ bool in_3D_export_surface_only = false)
+{
+ typedef Triangulation<GT,TDS> Tr;
+ typedef typename Tr::Vertex_const_handle Vertex_handle;
+ typedef typename Tr::Finite_vertex_const_iterator Finite_vertex_iterator;
+ typedef typename Tr::Finite_full_cell_const_iterator Finite_full_cell_iterator;
+ typedef typename Tr::Full_cell_const_iterator Full_cell_iterator;
+ typedef typename Tr::Full_cell Full_cell;
+ typedef typename Full_cell::Vertex_handle_const_iterator Full_cell_vertex_iterator;
+
+ if (tr.maximal_dimension() < 2 || tr.maximal_dimension() > 3)
+ {
+ std::cerr << "Warning: export_tds_to_off => dimension should be 2 or 3.";
+ os << "Warning: export_tds_to_off => dimension should be 2 or 3.";
+ return os;
+ }
+
+ size_t n = tr.number_of_vertices();
+
+ std::stringstream output;
+
+ // write the vertices
+ std::map<Vertex_handle, int> index_of_vertex;
+ int i = 0;
+ for(Finite_vertex_iterator it = tr.finite_vertices_begin();
+ it != tr.finite_vertices_end(); ++it, ++i)
+ {
+ Triangulation_IO::output_point(output, tr.geom_traits(), it->point());
+ if (tr.maximal_dimension() == 2)
+ output << " 0";
+ output << std::endl;
+ index_of_vertex[it.base()] = i;
+ }
+ CGAL_assertion( i == n );
+
+ size_t number_of_triangles = 0;
+ if (tr.maximal_dimension() == 2)
+ {
+ for (Finite_full_cell_iterator fch = tr.finite_full_cells_begin() ;
+ fch != tr.finite_full_cells_end() ; ++fch)
+ {
+ output << "3 ";
+ for (Full_cell_vertex_iterator vit = fch->vertices_begin() ;
+ vit != fch->vertices_end() ; ++vit)
+ {
+ output << index_of_vertex[*vit] << " ";
+ }
+ output << std::endl;
+ ++number_of_triangles;
+ }
+ }
+ else if (tr.maximal_dimension() == 3)
+ {
+ if (in_3D_export_surface_only)
+ {
+ // Parse boundary facets
+ for (Full_cell_iterator fch = tr.full_cells_begin() ;
+ fch != tr.full_cells_end() ; ++fch)
+ {
+ if (tr.is_infinite(fch))
+ {
+ output << "3 ";
+ for (Full_cell_vertex_iterator vit = fch->vertices_begin() ;
+ vit != fch->vertices_end() ; ++vit)
+ {
+ if (!tr.is_infinite(*vit))
+ output << index_of_vertex[*vit] << " ";
+ }
+ output << std::endl;
+ ++number_of_triangles;
+ }
+ }
+ }
+ else
+ {
+ // Parse finite cells
+ for (Finite_full_cell_iterator fch = tr.finite_full_cells_begin() ;
+ fch != tr.finite_full_cells_end() ; ++fch)
+ {
+ output << "3 "
+ << index_of_vertex[fch->vertex(0)] << " "
+ << index_of_vertex[fch->vertex(1)] << " "
+ << index_of_vertex[fch->vertex(2)]
+ << std::endl;
+ output << "3 "
+ << index_of_vertex[fch->vertex(0)] << " "
+ << index_of_vertex[fch->vertex(2)] << " "
+ << index_of_vertex[fch->vertex(3)]
+ << std::endl;
+ output << "3 "
+ << index_of_vertex[fch->vertex(1)] << " "
+ << index_of_vertex[fch->vertex(2)] << " "
+ << index_of_vertex[fch->vertex(3)]
+ << std::endl;
+ output << "3 "
+ << index_of_vertex[fch->vertex(0)] << " "
+ << index_of_vertex[fch->vertex(1)] << " "
+ << index_of_vertex[fch->vertex(3)]
+ << std::endl;
+ number_of_triangles += 4;
+ }
+ }
+ }
+
+ os << "OFF \n"
+ << n << " "
+ << number_of_triangles << " 0\n"
+ << output.str();
+
+ return os;
+}
+
+} //namespace CGAL
+
+#endif // CGAL_TRIANGULATION_IO_H
diff --git a/include/gudhi_patches/CGAL/Kd_tree.h b/include/gudhi_patches/CGAL/Kd_tree.h
new file mode 100644
index 00000000..f085b0da
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Kd_tree.h
@@ -0,0 +1,582 @@
+// Copyright (c) 2002,2011,2014 Utrecht University (The Netherlands), Max-Planck-Institute Saarbruecken (Germany).
+// 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) : Hans Tangelder (<hanst@cs.uu.nl>),
+// : Waqar Khan <wkhan@mpi-inf.mpg.de>
+
+#ifndef CGAL_KD_TREE_H
+#define CGAL_KD_TREE_H
+
+#include "Kd_tree_node.h"
+
+#include <CGAL/basic.h>
+#include <CGAL/assertions.h>
+#include <vector>
+
+#include <CGAL/algorithm.h>
+#include <CGAL/internal/Get_dimension_tag.h>
+#include <CGAL/Search_traits.h>
+
+
+#include <deque>
+#include <boost/container/deque.hpp>
+#include <boost/optional.hpp>
+
+#ifdef CGAL_HAS_THREADS
+#include <CGAL/mutex.h>
+#endif
+
+namespace CGAL {
+
+//template <class SearchTraits, class Splitter_=Median_of_rectangle<SearchTraits>, class UseExtendedNode = Tag_true >
+template <class SearchTraits, class Splitter_=Sliding_midpoint<SearchTraits>, class UseExtendedNode = Tag_true >
+class Kd_tree {
+
+public:
+ typedef SearchTraits Traits;
+ typedef Splitter_ Splitter;
+ typedef typename SearchTraits::Point_d Point_d;
+ typedef typename Splitter::Container Point_container;
+
+ typedef typename SearchTraits::FT FT;
+ typedef Kd_tree_node<SearchTraits, Splitter, UseExtendedNode > Node;
+ typedef Kd_tree_leaf_node<SearchTraits, Splitter, UseExtendedNode > Leaf_node;
+ typedef Kd_tree_internal_node<SearchTraits, Splitter, UseExtendedNode > Internal_node;
+ typedef Kd_tree<SearchTraits, Splitter> Tree;
+ typedef Kd_tree<SearchTraits, Splitter,UseExtendedNode> Self;
+
+ typedef Node* Node_handle;
+ typedef const Node* Node_const_handle;
+ typedef Leaf_node* Leaf_node_handle;
+ typedef const Leaf_node* Leaf_node_const_handle;
+ typedef Internal_node* Internal_node_handle;
+ typedef const Internal_node* Internal_node_const_handle;
+ typedef typename std::vector<const Point_d*>::const_iterator Point_d_iterator;
+ typedef typename std::vector<const Point_d*>::const_iterator Point_d_const_iterator;
+ typedef typename Splitter::Separator Separator;
+ typedef typename std::vector<Point_d>::const_iterator iterator;
+ typedef typename std::vector<Point_d>::const_iterator const_iterator;
+
+ typedef typename std::vector<Point_d>::size_type size_type;
+
+ typedef typename internal::Get_dimension_tag<SearchTraits>::Dimension D;
+
+private:
+ SearchTraits traits_;
+ Splitter split;
+
+
+ // wokaround for https://svn.boost.org/trac/boost/ticket/9332
+#if (_MSC_VER == 1800) && (BOOST_VERSION == 105500)
+ std::deque<Internal_node> internal_nodes;
+ std::deque<Leaf_node> leaf_nodes;
+#else
+ boost::container::deque<Internal_node> internal_nodes;
+ boost::container::deque<Leaf_node> leaf_nodes;
+#endif
+
+ Node_handle tree_root;
+
+ Kd_tree_rectangle<FT,D>* bbox;
+ std::vector<Point_d> pts;
+
+ // Instead of storing the points in arrays in the Kd_tree_node
+ // we put all the data in a vector in the Kd_tree.
+ // and we only store an iterator range in the Kd_tree_node.
+ //
+ std::vector<const Point_d*> data;
+
+
+ #ifdef CGAL_HAS_THREADS
+ mutable CGAL_MUTEX building_mutex;//mutex used to protect const calls inducing build()
+ #endif
+ bool built_;
+ bool removed_;
+
+ // protected copy constructor
+ Kd_tree(const Tree& tree)
+ : traits_(tree.traits_),built_(tree.built_)
+ {};
+
+
+ // Instead of the recursive construction of the tree in the class Kd_tree_node
+ // we do this in the tree class. The advantage is that we then can optimize
+ // the allocation of the nodes.
+
+ // The leaf node
+ Node_handle
+ create_leaf_node(Point_container& c)
+ {
+ Leaf_node node(true , static_cast<unsigned int>(c.size()));
+ std::ptrdiff_t tmp = c.begin() - data.begin();
+ node.data = pts.begin() + tmp;
+
+ leaf_nodes.push_back(node);
+ Leaf_node_handle nh = &leaf_nodes.back();
+
+
+ return nh;
+ }
+
+
+ // The internal node
+
+ Node_handle
+ create_internal_node(Point_container& c, const Tag_true&)
+ {
+ return create_internal_node_use_extension(c);
+ }
+
+ Node_handle
+ create_internal_node(Point_container& c, const Tag_false&)
+ {
+ return create_internal_node(c);
+ }
+
+
+
+ // TODO: Similiar to the leaf_init function above, a part of the code should be
+ // moved to a the class Kd_tree_node.
+ // It is not proper yet, but the goal was to see if there is
+ // a potential performance gain through the Compact_container
+ Node_handle
+ create_internal_node_use_extension(Point_container& c)
+ {
+ Internal_node node(false);
+ internal_nodes.push_back(node);
+ Internal_node_handle nh = &internal_nodes.back();
+
+ Separator sep;
+ Point_container c_low(c.dimension(),traits_);
+ split(sep, c, c_low);
+ nh->set_separator(sep);
+
+ int cd = nh->cutting_dimension();
+ if(!c_low.empty()){
+ nh->lower_low_val = c_low.tight_bounding_box().min_coord(cd);
+ nh->lower_high_val = c_low.tight_bounding_box().max_coord(cd);
+ }
+ else{
+ nh->lower_low_val = nh->cutting_value();
+ nh->lower_high_val = nh->cutting_value();
+ }
+ if(!c.empty()){
+ nh->upper_low_val = c.tight_bounding_box().min_coord(cd);
+ nh->upper_high_val = c.tight_bounding_box().max_coord(cd);
+ }
+ else{
+ nh->upper_low_val = nh->cutting_value();
+ nh->upper_high_val = nh->cutting_value();
+ }
+
+ CGAL_assertion(nh->cutting_value() >= nh->lower_low_val);
+ CGAL_assertion(nh->cutting_value() <= nh->upper_high_val);
+
+ if (c_low.size() > split.bucket_size()){
+ nh->lower_ch = create_internal_node_use_extension(c_low);
+ }else{
+ nh->lower_ch = create_leaf_node(c_low);
+ }
+ if (c.size() > split.bucket_size()){
+ nh->upper_ch = create_internal_node_use_extension(c);
+ }else{
+ nh->upper_ch = create_leaf_node(c);
+ }
+
+
+
+
+ return nh;
+ }
+
+
+ // Note also that I duplicated the code to get rid if the if's for
+ // the boolean use_extension which was constant over the construction
+ Node_handle
+ create_internal_node(Point_container& c)
+ {
+ Internal_node node(false);
+ internal_nodes.push_back(node);
+ Internal_node_handle nh = &internal_nodes.back();
+ Separator sep;
+
+ Point_container c_low(c.dimension(),traits_);
+ split(sep, c, c_low);
+ nh->set_separator(sep);
+
+ if (c_low.size() > split.bucket_size()){
+ nh->lower_ch = create_internal_node(c_low);
+ }else{
+ nh->lower_ch = create_leaf_node(c_low);
+ }
+ if (c.size() > split.bucket_size()){
+ nh->upper_ch = create_internal_node(c);
+ }else{
+ nh->upper_ch = create_leaf_node(c);
+ }
+
+
+
+ return nh;
+ }
+
+
+
+public:
+
+ Kd_tree(Splitter s = Splitter(),const SearchTraits traits=SearchTraits())
+ : traits_(traits),split(s), built_(false), removed_(false)
+ {}
+
+ template <class InputIterator>
+ Kd_tree(InputIterator first, InputIterator beyond,
+ Splitter s = Splitter(),const SearchTraits traits=SearchTraits())
+ : traits_(traits),split(s), built_(false), removed_(false)
+ {
+ pts.insert(pts.end(), first, beyond);
+ }
+
+ bool empty() const {
+ return pts.empty();
+ }
+
+ void
+ build()
+ {
+ // This function is not ready to be called when a tree already exists, one
+ // must call invalidate_built() first.
+ CGAL_assertion(!is_built());
+ CGAL_assertion(!removed_);
+ const Point_d& p = *pts.begin();
+ typename SearchTraits::Construct_cartesian_const_iterator_d ccci=traits_.construct_cartesian_const_iterator_d_object();
+ int dim = static_cast<int>(std::distance(ccci(p), ccci(p,0)));
+
+ data.reserve(pts.size());
+ for(unsigned int i = 0; i < pts.size(); i++){
+ data.push_back(&pts[i]);
+ }
+ Point_container c(dim, data.begin(), data.end(),traits_);
+ bbox = new Kd_tree_rectangle<FT,D>(c.bounding_box());
+ if (c.size() <= split.bucket_size()){
+ tree_root = create_leaf_node(c);
+ }else {
+ tree_root = create_internal_node(c, UseExtendedNode());
+ }
+
+ //Reorder vector for spatial locality
+ std::vector<Point_d> ptstmp;
+ ptstmp.resize(pts.size());
+ for (std::size_t i = 0; i < pts.size(); ++i){
+ ptstmp[i] = *data[i];
+ }
+ for(std::size_t i = 0; i < leaf_nodes.size(); ++i){
+ std::ptrdiff_t tmp = leaf_nodes[i].begin() - pts.begin();
+ leaf_nodes[i].data = ptstmp.begin() + tmp;
+ }
+ pts.swap(ptstmp);
+
+ data.clear();
+
+ built_ = true;
+ }
+
+private:
+ //any call to this function is for the moment not threadsafe
+ void const_build() const {
+ #ifdef CGAL_HAS_THREADS
+ //this ensure that build() will be called once
+ CGAL_SCOPED_LOCK(building_mutex);
+ if(!is_built())
+ #endif
+ const_cast<Self*>(this)->build(); //THIS IS NOT THREADSAFE
+ }
+public:
+
+ bool is_built() const
+ {
+ return built_;
+ }
+
+ void invalidate_built()
+ {
+ if(removed_){
+ // Walk the tree to collect the remaining points.
+ // Writing directly to pts would likely work, but better be safe.
+ std::vector<Point_d> ptstmp;
+ //ptstmp.resize(root()->num_items());
+ root()->tree_items(std::back_inserter(ptstmp));
+ pts.swap(ptstmp);
+ removed_=false;
+ CGAL_assertion(is_built()); // the rest of the cleanup must happen
+ }
+ if(is_built()){
+ internal_nodes.clear();
+ leaf_nodes.clear();
+ data.clear();
+ delete bbox;
+ built_ = false;
+ }
+ }
+
+ void clear()
+ {
+ invalidate_built();
+ pts.clear();
+ removed_ = false;
+ }
+
+ void
+ insert(const Point_d& p)
+ {
+ invalidate_built();
+ pts.push_back(p);
+ }
+
+ template <class InputIterator>
+ void
+ insert(InputIterator first, InputIterator beyond)
+ {
+ invalidate_built();
+ pts.insert(pts.end(),first, beyond);
+ }
+
+private:
+ struct Equal_by_coordinates {
+ SearchTraits const* traits;
+ Point_d const* pp;
+ bool operator()(Point_d const&q) const {
+ typename SearchTraits::Construct_cartesian_const_iterator_d ccci=traits->construct_cartesian_const_iterator_d_object();
+ return std::equal(ccci(*pp), ccci(*pp,0), ccci(q));
+ }
+ };
+ Equal_by_coordinates equal_by_coordinates(Point_d const&p){
+ Equal_by_coordinates ret = { &traits(), &p };
+ return ret;
+ }
+
+public:
+ void
+ remove(const Point_d& p)
+ {
+ remove(p, equal_by_coordinates(p));
+ }
+
+ template<class Equal>
+ void
+ remove(const Point_d& p, Equal const& equal_to_p)
+ {
+#if 0
+ // This code could have quadratic runtime.
+ if (!is_built()) {
+ std::vector<Point_d>::iterator pi = std::find(pts.begin(), pts.end(), p);
+ // Precondition: the point must be there.
+ CGAL_assertion (pi != pts.end());
+ pts.erase(pi);
+ return;
+ }
+#endif
+ bool success = remove_(p, 0, false, 0, false, root(), equal_to_p);
+ CGAL_assertion(success);
+
+ // Do not set the flag is the tree has been cleared.
+ if(is_built())
+ removed_ |= success;
+ }
+private:
+ template<class Equal>
+ bool remove_(const Point_d& p,
+ Internal_node_handle grandparent, bool parent_islower,
+ Internal_node_handle parent, bool islower,
+ Node_handle node, Equal const& equal_to_p) {
+ // Recurse to locate the point
+ if (!node->is_leaf()) {
+ Internal_node_handle newparent = static_cast<Internal_node_handle>(node);
+ // FIXME: This should be if(x<y) remove low; else remove up;
+ if (traits().construct_cartesian_const_iterator_d_object()(p)[newparent->cutting_dimension()] <= newparent->cutting_value()) {
+ if (remove_(p, parent, islower, newparent, true, newparent->lower(), equal_to_p))
+ return true;
+ }
+ //if (traits().construct_cartesian_const_iterator_d_object()(p)[newparent->cutting_dimension()] >= newparent->cutting_value())
+ return remove_(p, parent, islower, newparent, false, newparent->upper(), equal_to_p);
+
+ CGAL_assertion(false); // Point was not found
+ }
+
+ // Actual removal
+ Leaf_node_handle lnode = static_cast<Leaf_node_handle>(node);
+ if (lnode->size() > 1) {
+ iterator pi = std::find_if(lnode->begin(), lnode->end(), equal_to_p);
+ // FIXME: we should ensure this never happens
+ if (pi == lnode->end()) return false;
+ iterator lasti = lnode->end() - 1;
+ if (pi != lasti) {
+ // Hack to get a non-const iterator
+ std::iter_swap(pts.begin()+(pi-pts.begin()), pts.begin()+(lasti-pts.begin()));
+ }
+ lnode->drop_last_point();
+ } else if (!equal_to_p(*lnode->begin())) {
+ // FIXME: we should ensure this never happens
+ return false;
+ } else if (grandparent) {
+ Node_handle brother = islower ? parent->upper() : parent->lower();
+ if (parent_islower)
+ grandparent->set_lower(brother);
+ else
+ grandparent->set_upper(brother);
+ } else if (parent) {
+ tree_root = islower ? parent->upper() : parent->lower();
+ } else {
+ clear();
+ }
+ return true;
+ }
+
+public:
+ //For efficiency; reserve the size of the points vectors in advance (if the number of points is already known).
+ void reserve(size_t size)
+ {
+ pts.reserve(size);
+ }
+
+ //Get the capacity of the underlying points vector.
+ size_t capacity()
+ {
+ return pts.capacity();
+ }
+
+
+ template <class OutputIterator, class FuzzyQueryItem>
+ OutputIterator
+ search(OutputIterator it, const FuzzyQueryItem& q) const
+ {
+ if(! pts.empty()){
+
+ if(! is_built()){
+ const_build();
+ }
+ Kd_tree_rectangle<FT,D> b(*bbox);
+ return tree_root->search(it,q,b);
+ }
+ return it;
+ }
+
+
+ template <class FuzzyQueryItem>
+ boost::optional<Point_d>
+ search_any_point(const FuzzyQueryItem& q) const
+ {
+ if(! pts.empty()){
+
+ if(! is_built()){
+ const_build();
+ }
+ Kd_tree_rectangle<FT,D> b(*bbox);
+ return tree_root->search_any_point(q,b);
+ }
+ return boost::none;
+ }
+
+
+ ~Kd_tree() {
+ if(is_built()){
+ delete bbox;
+ }
+ }
+
+
+ const SearchTraits&
+ traits() const
+ {
+ return traits_;
+ }
+
+ Node_const_handle
+ root() const
+ {
+ if(! is_built()){
+ const_build();
+ }
+ return tree_root;
+ }
+
+ Node_handle
+ root()
+ {
+ if(! is_built()){
+ build();
+ }
+ return tree_root;
+ }
+
+ void
+ print() const
+ {
+ if(! is_built()){
+ const_build();
+ }
+ root()->print();
+ }
+
+ const Kd_tree_rectangle<FT,D>&
+ bounding_box() const
+ {
+ if(! is_built()){
+ const_build();
+ }
+ return *bbox;
+ }
+
+ const_iterator
+ begin() const
+ {
+ return pts.begin();
+ }
+
+ const_iterator
+ end() const
+ {
+ return pts.end();
+ }
+
+ size_type
+ size() const
+ {
+ return pts.size();
+ }
+
+ // Print statistics of the tree.
+ std::ostream&
+ statistics(std::ostream& s) const
+ {
+ if(! is_built()){
+ const_build();
+ }
+ s << "Tree statistics:" << std::endl;
+ s << "Number of items stored: "
+ << root()->num_items() << std::endl;
+ s << "Number of nodes: "
+ << root()->num_nodes() << std::endl;
+ s << " Tree depth: " << root()->depth() << std::endl;
+ return s;
+ }
+
+
+};
+
+} // namespace CGAL
+
+#endif // CGAL_KD_TREE_H
diff --git a/include/gudhi_patches/CGAL/Kd_tree_node.h b/include/gudhi_patches/CGAL/Kd_tree_node.h
new file mode 100644
index 00000000..909ee260
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Kd_tree_node.h
@@ -0,0 +1,586 @@
+// Copyright (c) 2002,2011 Utrecht University (The Netherlands).
+// 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$
+//
+//
+// Authors : Hans Tangelder (<hanst@cs.uu.nl>)
+
+#ifndef CGAL_KD_TREE_NODE_H
+#define CGAL_KD_TREE_NODE_H
+
+#include "CGAL/Splitters.h"
+
+#include <CGAL/Compact_container.h>
+#include <boost/cstdint.hpp>
+
+namespace CGAL {
+
+ template <class SearchTraits, class Splitter, class UseExtendedNode>
+ class Kd_tree;
+
+ template < class TreeTraits, class Splitter, class UseExtendedNode >
+ class Kd_tree_node {
+
+ friend class Kd_tree<TreeTraits,Splitter,UseExtendedNode>;
+
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Node_handle Node_handle;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Node_const_handle Node_const_handle;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Internal_node_handle Internal_node_handle;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Internal_node_const_handle Internal_node_const_handle;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Leaf_node_handle Leaf_node_handle;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Leaf_node_const_handle Leaf_node_const_handle;
+ typedef typename TreeTraits::Point_d Point_d;
+
+ typedef typename TreeTraits::FT FT;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Separator Separator;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Point_d_iterator Point_d_iterator;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::iterator iterator;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::D D;
+
+ bool leaf;
+
+ public :
+ Kd_tree_node(bool leaf_)
+ :leaf(leaf_){}
+
+ bool is_leaf() const{
+ return leaf;
+ }
+
+ std::size_t
+ num_items() const
+ {
+ if (is_leaf()){
+ Leaf_node_const_handle node =
+ static_cast<Leaf_node_const_handle>(this);
+ return node->size();
+ }
+ else {
+ Internal_node_const_handle node =
+ static_cast<Internal_node_const_handle>(this);
+ return node->lower()->num_items() + node->upper()->num_items();
+ }
+ }
+
+ std::size_t
+ num_nodes() const
+ {
+ if (is_leaf()) return 1;
+ else {
+ Internal_node_const_handle node =
+ static_cast<Internal_node_const_handle>(this);
+ return node->lower()->num_nodes() + node->upper()->num_nodes();
+ }
+ }
+
+ int
+ depth(const int current_max_depth) const
+ {
+ if (is_leaf()){
+ return current_max_depth;
+ }
+ else {
+ Internal_node_const_handle node =
+ static_cast<Internal_node_const_handle>(this);
+ return
+ (std::max)( node->lower()->depth(current_max_depth + 1),
+ node->upper()->depth(current_max_depth + 1));
+ }
+ }
+
+ int
+ depth() const
+ {
+ return depth(1);
+ }
+
+ template <class OutputIterator>
+ OutputIterator
+ tree_items(OutputIterator it) const {
+ if (is_leaf()) {
+ Leaf_node_const_handle node =
+ static_cast<Leaf_node_const_handle>(this);
+ if (node->size()>0)
+ for (iterator i=node->begin(); i != node->end(); i++)
+ {*it=*i; ++it;}
+ }
+ else {
+ Internal_node_const_handle node =
+ static_cast<Internal_node_const_handle>(this);
+ it=node->lower()->tree_items(it);
+ it=node->upper()->tree_items(it);
+ }
+ return it;
+ }
+
+
+ boost::optional<Point_d>
+ any_tree_item() const {
+ boost::optional<Point_d> result = boost::none;
+ if (is_leaf()) {
+ Leaf_node_const_handle node =
+ static_cast<Leaf_node_const_handle>(this);
+ if (node->size()>0){
+ return boost::make_optional(*(node->begin()));
+ }
+ }
+ else {
+ Internal_node_const_handle node =
+ static_cast<Internal_node_const_handle>(this);
+ result = node->lower()->any_tree_item();
+ if(! result){
+ result = node->upper()->any_tree_item();
+ }
+ }
+ return result;
+ }
+
+
+ void
+ indent(int d) const
+ {
+ for(int i = 0; i < d; i++){
+ std::cout << " ";
+ }
+ }
+
+
+ void
+ print(int d = 0) const
+ {
+ if (is_leaf()) {
+ Leaf_node_const_handle node =
+ static_cast<Leaf_node_const_handle>(this);
+ indent(d);
+ std::cout << "leaf" << std::endl;
+ if (node->size()>0)
+ for (iterator i=node->begin(); i != node->end(); i++)
+ {indent(d);std::cout << *i << std::endl;}
+ }
+ else {
+ Internal_node_const_handle node =
+ static_cast<Internal_node_const_handle>(this);
+ indent(d);
+ std::cout << "lower tree" << std::endl;
+ node->lower()->print(d+1);
+ indent(d);
+ std::cout << "separator: dim = " << node->cutting_dimension() << " val = " << node->cutting_value() << std::endl;
+ indent(d);
+ std::cout << "upper tree" << std::endl;
+ node->upper()->print(d+1);
+ }
+ }
+
+
+ template <class OutputIterator, class FuzzyQueryItem>
+ OutputIterator
+ search(OutputIterator it, const FuzzyQueryItem& q,
+ Kd_tree_rectangle<FT,D>& b) const
+ {
+ if (is_leaf()) {
+ Leaf_node_const_handle node =
+ static_cast<Leaf_node_const_handle>(this);
+ if (node->size()>0)
+ for (iterator i=node->begin(); i != node->end(); i++)
+ if (q.contains(*i))
+ {*it++=*i;}
+ }
+ else {
+ Internal_node_const_handle node =
+ static_cast<Internal_node_const_handle>(this);
+ // after splitting b denotes the lower part of b
+ Kd_tree_rectangle<FT,D> b_upper(b);
+ b.split(b_upper, node->cutting_dimension(),
+ node->cutting_value());
+
+ if (q.outer_range_contains(b))
+ it=node->lower()->tree_items(it);
+ else
+ if (q.inner_range_intersects(b))
+ it=node->lower()->search(it,q,b);
+ if (q.outer_range_contains(b_upper))
+ it=node->upper()->tree_items(it);
+ else
+ if (q.inner_range_intersects(b_upper))
+ it=node->upper()->search(it,q,b_upper);
+ };
+ return it;
+ }
+
+
+ template <class FuzzyQueryItem>
+ boost::optional<Point_d>
+ search_any_point(const FuzzyQueryItem& q,
+ Kd_tree_rectangle<FT,D>& b) const
+ {
+ boost::optional<Point_d> result = boost::none;
+ if (is_leaf()) {
+ Leaf_node_const_handle node =
+ static_cast<Leaf_node_const_handle>(this);
+ if (node->size()>0)
+ for (iterator i=node->begin(); i != node->end(); i++)
+ if (q.contains(*i))
+ { result = *i; break; }
+ }
+ else {
+ Internal_node_const_handle node =
+ static_cast<Internal_node_const_handle>(this);
+ // after splitting b denotes the lower part of b
+ Kd_tree_rectangle<FT,D> b_upper(b);
+ b.split(b_upper, node->cutting_dimension(),
+ node->cutting_value());
+
+ if (q.outer_range_contains(b)){
+ result = node->lower()->any_tree_item();
+ }else{
+ if (q.inner_range_intersects(b)){
+ result = node->lower()->search_any_point(q,b);
+ }
+ }
+ if(result){
+ return result;
+ }
+ if (q.outer_range_contains(b_upper)){
+ result = node->upper()->any_tree_item();
+ }else{
+ if (q.inner_range_intersects(b_upper))
+ result = node->upper()->search_any_point(q,b_upper);
+ }
+ }
+ return result;
+ }
+
+ };
+
+
+ template < class TreeTraits, class Splitter, class UseExtendedNode >
+ class Kd_tree_leaf_node : public Kd_tree_node< TreeTraits, Splitter, UseExtendedNode >{
+
+ friend class Kd_tree<TreeTraits,Splitter,UseExtendedNode>;
+
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::iterator iterator;
+ typedef Kd_tree_node< TreeTraits, Splitter, UseExtendedNode> Base;
+ typedef typename TreeTraits::Point_d Point_d;
+
+ private:
+
+ // private variables for leaf nodes
+ boost::int32_t n; // denotes number of items in a leaf node
+ iterator data; // iterator to data in leaf node
+
+
+ public:
+
+ // default constructor
+ Kd_tree_leaf_node()
+ {}
+
+ Kd_tree_leaf_node(bool leaf_ )
+ : Base(leaf_)
+ {}
+
+ Kd_tree_leaf_node(bool leaf_,unsigned int n_ )
+ : Base(leaf_), n(n_)
+ {}
+
+ // members for all nodes
+
+ // members for leaf nodes only
+ inline
+ unsigned int
+ size() const
+ {
+ return n;
+ }
+
+ inline
+ iterator
+ begin() const
+ {
+ return data;
+ }
+
+ inline
+ iterator
+ end() const
+ {
+ return data + n;
+ }
+
+ inline
+ void
+ drop_last_point()
+ {
+ --n;
+ }
+
+ }; //leaf node
+
+
+
+ template < class TreeTraits, class Splitter, class UseExtendedNode>
+ class Kd_tree_internal_node : public Kd_tree_node< TreeTraits, Splitter, UseExtendedNode >{
+
+ friend class Kd_tree<TreeTraits,Splitter,UseExtendedNode>;
+
+ typedef Kd_tree_node< TreeTraits, Splitter, UseExtendedNode> Base;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Node_handle Node_handle;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Node_const_handle Node_const_handle;
+
+ typedef typename TreeTraits::FT FT;
+ typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Separator Separator;
+
+ private:
+
+ // private variables for internal nodes
+ boost::int32_t cut_dim;
+ FT cut_val;
+ Node_handle lower_ch, upper_ch;
+
+
+ // private variables for extended internal nodes
+ FT upper_low_val;
+ FT upper_high_val;
+ FT lower_low_val;
+ FT lower_high_val;
+
+
+ public:
+
+ // default constructor
+ Kd_tree_internal_node()
+ {}
+
+ Kd_tree_internal_node(bool leaf_)
+ : Base(leaf_)
+ {}
+
+
+ // members for internal node and extended internal node
+
+ inline
+ Node_const_handle
+ lower() const
+ {
+ return lower_ch;
+ }
+
+ inline
+ Node_const_handle
+ upper() const
+ {
+ return upper_ch;
+ }
+
+ inline
+ Node_handle
+ lower()
+ {
+ return lower_ch;
+ }
+
+ inline
+ Node_handle
+ upper()
+ {
+ return upper_ch;
+ }
+
+ inline
+ void
+ set_lower(Node_handle nh)
+ {
+ lower_ch = nh;
+ }
+
+ inline
+ void
+ set_upper(Node_handle nh)
+ {
+ upper_ch = nh;
+ }
+
+ // inline Separator& separator() {return sep; }
+ // use instead
+ inline
+ void set_separator(Separator& sep){
+ cut_dim = sep.cutting_dimension();
+ cut_val = sep.cutting_value();
+ }
+
+ inline
+ FT
+ cutting_value() const
+ {
+ return cut_val;
+ }
+
+ inline
+ int
+ cutting_dimension() const
+ {
+ return cut_dim;
+ }
+
+ // members for extended internal node only
+ inline
+ FT
+ upper_low_value() const
+ {
+ return upper_low_val;
+ }
+
+ inline
+ FT
+ upper_high_value() const
+ {
+ return upper_high_val;
+ }
+
+ inline
+ FT
+ lower_low_value() const
+ {
+ return lower_low_val;
+ }
+
+ inline
+ FT
+ lower_high_value() const
+ {
+ return lower_high_val;
+ }
+
+ /*Separator&
+ separator()
+ {
+ return Separator(cutting_dimension,cutting_value);
+ }*/
+
+
+ };//internal node
+
+ template < class TreeTraits, class Splitter>
+ class Kd_tree_internal_node<TreeTraits,Splitter,Tag_false> : public Kd_tree_node< TreeTraits, Splitter, Tag_false >{
+
+ friend class Kd_tree<TreeTraits,Splitter,Tag_false>;
+
+ typedef Kd_tree_node< TreeTraits, Splitter, Tag_false> Base;
+ typedef typename Kd_tree<TreeTraits,Splitter,Tag_false>::Node_handle Node_handle;
+ typedef typename Kd_tree<TreeTraits,Splitter,Tag_false>::Node_const_handle Node_const_handle;
+
+ typedef typename TreeTraits::FT FT;
+ typedef typename Kd_tree<TreeTraits,Splitter,Tag_false>::Separator Separator;
+
+ private:
+
+ // private variables for internal nodes
+ boost::uint8_t cut_dim;
+ FT cut_val;
+
+ Node_handle lower_ch, upper_ch;
+
+ public:
+
+ // default constructor
+ Kd_tree_internal_node()
+ {}
+
+ Kd_tree_internal_node(bool leaf_)
+ : Base(leaf_)
+ {}
+
+
+ // members for internal node and extended internal node
+
+ inline
+ Node_const_handle
+ lower() const
+ {
+ return lower_ch;
+ }
+
+ inline
+ Node_const_handle
+ upper() const
+ {
+ return upper_ch;
+ }
+
+ inline
+ Node_handle
+ lower()
+ {
+ return lower_ch;
+ }
+
+ inline
+ Node_handle
+ upper()
+ {
+ return upper_ch;
+ }
+
+ inline
+ void
+ set_lower(Node_handle nh)
+ {
+ lower_ch = nh;
+ }
+
+ inline
+ void
+ set_upper(Node_handle nh)
+ {
+ upper_ch = nh;
+ }
+
+ // inline Separator& separator() {return sep; }
+ // use instead
+
+ inline
+ void set_separator(Separator& sep){
+ cut_dim = sep.cutting_dimension();
+ cut_val = sep.cutting_value();
+ }
+
+ inline
+ FT
+ cutting_value() const
+ {
+ return cut_val;
+ }
+
+ inline
+ int
+ cutting_dimension() const
+ {
+ return cut_dim;
+ }
+
+ /* Separator&
+ separator()
+ {
+ return Separator(cutting_dimension,cutting_value);
+ }*/
+
+
+ };//internal node
+
+
+
+} // namespace CGAL
+#endif // CGAL_KDTREE_NODE_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_LA_base.h b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_LA_base.h
new file mode 100644
index 00000000..c13a9801
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_LA_base.h
@@ -0,0 +1,177 @@
+// 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_KERNEL_D_CARTESIAN_LA_BASE_H
+#define CGAL_KERNEL_D_CARTESIAN_LA_BASE_H
+
+#include <CGAL/basic.h>
+#include <CGAL/Origin.h>
+#include <boost/type_traits/integral_constant.hpp>
+#include <CGAL/representation_tags.h>
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Uncertain.h>
+#include <CGAL/typeset.h>
+#include <CGAL/NewKernel_d/Dimension_base.h>
+#include <CGAL/NewKernel_d/Cartesian_LA_functors.h>
+#include <CGAL/NewKernel_d/Vector/array.h>
+#include <CGAL/NewKernel_d/Vector/vector.h>
+#include <CGAL/NewKernel_d/Vector/mix.h>
+#ifdef CGAL_EIGEN3_ENABLED
+#include <CGAL/NewKernel_d/LA_eigen/LA.h>
+#else
+#error Eigen3 is required
+#endif
+
+namespace CGAL {
+
+template < typename FT_, typename Dim_,
+#if 1
+ typename Vec_=Mix_vector<Array_vector<FT_, Dim_>,
+ Vector_vector<FT_, Dim_>,
+ FT_, Dim_>,
+#elif 0
+ typename Vec_=Array_vector<FT_, Dim_>,
+#elif 0
+ typename Vec_=Vector_vector<FT_, Dim_>,
+#else
+ // Dangerous because of alignment. Ok on x86_64 without AVX.
+ typename Vec_=LA_eigen<FT_, Dim_>,
+#endif
+ typename LA_=LA_eigen<FT_,Dim_> >
+ /* Default LA to Vec or to LA_eigen? */
+struct Cartesian_LA_base_d : public Dimension_base<Dim_>
+{
+ typedef Cartesian_LA_base_d<FT_,Dim_> Self;
+ typedef Cartesian_tag Rep_tag;
+ typedef Cartesian_tag Kernel_tag;
+ typedef Dim_ Default_ambient_dimension;
+ typedef Dim_ Max_ambient_dimension;
+ typedef Dim_ Dimension;
+ typedef LA_ LA;
+ template <class> struct Ambient_dimension { typedef Dim_ type; };
+
+ typedef Vec_ LA_vector;
+ typedef typename LA_vector::Vector Point;
+ typedef typename LA_vector::Vector Vector;
+ typedef typename LA_vector::Vector Vector_;
+ typedef typename LA_vector::Construct_vector Constructor;
+ typedef typename LA_vector::Vector_const_iterator Point_cartesian_const_iterator;
+ typedef typename LA_vector::Vector_const_iterator Vector_cartesian_const_iterator;
+
+ template<class, class=void> struct Type {};
+ template<class D> struct Type< Point_tag, D> { typedef Vector_ type; };
+ template<class D> struct Type<Vector_tag, D> { typedef Vector_ type; };
+ template<class D> struct Type< FT_tag, D> { typedef FT_ type; };
+ template<class D> struct Type< RT_tag, D> { typedef FT_ type; };
+
+ typedef typeset<Point_tag>
+ ::add<Vector_tag>::type
+ // FIXME: These have nothing to do here.
+ ::add<Segment_tag>::type
+ ::add<Hyperplane_tag>::type
+ ::add<Sphere_tag>::type
+ ::add<Weighted_point_tag>::type
+ Object_list;
+
+ typedef typeset< Point_cartesian_const_iterator_tag>::type
+ ::add<Vector_cartesian_const_iterator_tag>::type
+ Iterator_list;
+
+ template<class, class=void, class=boost::integral_constant<int,0> > struct Functor {
+ typedef Null_functor type;
+ };
+ template<class D> struct Functor<Construct_ttag<Vector_tag>,D> {
+ typedef CartesianDVectorBase::Construct_LA_vector<Self,Null_vector> type;
+ };
+ template<class D> struct Functor<Construct_ttag<Point_tag>,D> {
+ typedef CartesianDVectorBase::Construct_LA_vector<Self,Origin> type;
+ };
+ template<class D> struct Functor<Construct_ttag<Point_cartesian_const_iterator_tag>,D> {
+ typedef CartesianDVectorBase::Construct_cartesian_const_iterator<Self> type;
+ };
+ template<class D> struct Functor<Construct_ttag<Vector_cartesian_const_iterator_tag>,D> {
+ typedef CartesianDVectorBase::Construct_cartesian_const_iterator<Self> type;
+ };
+ template<class D> struct Functor<Sum_of_vectors_tag,D,
+ boost::integral_constant<int,!LA_vector::template Property<Has_vector_plus_minus_tag>::value> > {
+ typedef CartesianDVectorBase::Sum_of_vectors<Self> type;
+ };
+ template<class D> struct Functor<Difference_of_vectors_tag,D,
+ boost::integral_constant<int,!LA_vector::template Property<Has_vector_plus_minus_tag>::value> > {
+ typedef CartesianDVectorBase::Difference_of_vectors<Self> type;
+ };
+ template<class D> struct Functor<Opposite_vector_tag,D,
+ boost::integral_constant<int,!LA_vector::template Property<Has_vector_plus_minus_tag>::value> > {
+ typedef CartesianDVectorBase::Opposite_vector<Self> type;
+ };
+ template<class D> struct Functor<Midpoint_tag,D,
+ boost::integral_constant<int,
+ !LA_vector::template Property<Has_vector_plus_minus_tag>::value
+ || !LA_vector::template Property<Has_vector_scalar_ops_tag>::value> > {
+ typedef CartesianDVectorBase::Midpoint<Self> type;
+ };
+ template<class D> struct Functor<Compute_point_cartesian_coordinate_tag,D> {
+ typedef CartesianDVectorBase::Compute_cartesian_coordinate<Self> type;
+ };
+ template<class D> struct Functor<Compute_vector_cartesian_coordinate_tag,D> {
+ typedef CartesianDVectorBase::Compute_cartesian_coordinate<Self> type;
+ };
+ template<class D> struct Functor<Point_dimension_tag,D> {
+ typedef CartesianDVectorBase::PV_dimension<Self> type;
+ };
+ template<class D> struct Functor<Vector_dimension_tag,D> {
+ typedef CartesianDVectorBase::PV_dimension<Self> type;
+ };
+ template<class D> struct Functor<Orientation_of_vectors_tag,D,
+ boost::integral_constant<int,!LA_vector::template Property<Has_determinant_of_iterator_to_vectors_tag>::value> > {
+ typedef CartesianDVectorBase::Orientation_of_vectors<Self> type;
+ };
+ template<class D> struct Functor<Orientation_of_points_tag,D,
+ boost::integral_constant<int,!LA_vector::template Property<Has_determinant_of_iterator_to_points_tag>::value> > {
+ typedef CartesianDVectorBase::Orientation_of_points<Self> type;
+ };
+ template<class D> struct Functor<Scalar_product_tag,D,
+ boost::integral_constant<int,!LA_vector::template Property<Has_dot_product_tag>::value> > {
+ typedef CartesianDVectorBase::Scalar_product<Self> type;
+ };
+ template<class D> struct Functor<Squared_distance_to_origin_tag,D,
+ boost::integral_constant<int,!LA_vector::template Property<Stores_squared_norm_tag>::value> > {
+ typedef CartesianDVectorBase::Squared_distance_to_origin_stored<Self> type;
+ };
+ // Use integral_constant<int,2> in case of failure, to distinguish from the previous one.
+ template<class D> struct Functor<Squared_distance_to_origin_tag,D,
+ boost::integral_constant<int,
+ (LA_vector::template Property<Stores_squared_norm_tag>::value
+ || !LA_vector::template Property<Has_dot_product_tag>::value)*2> > {
+ typedef CartesianDVectorBase::Squared_distance_to_origin_via_dotprod<Self> type;
+ };
+ template<class D> struct Functor<Point_to_vector_tag,D> {
+ typedef CartesianDVectorBase::Identity_functor<Self> type;
+ };
+ template<class D> struct Functor<Vector_to_point_tag,D> {
+ typedef CartesianDVectorBase::Identity_functor<Self> type;
+ };
+
+ CGAL_CONSTEXPR Cartesian_LA_base_d(){}
+ CGAL_CONSTEXPR Cartesian_LA_base_d(int d):Dimension_base<Dim_>(d){}
+};
+
+} //namespace CGAL
+
+#endif // CGAL_KERNEL_D_CARTESIAN_LA_BASE_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_LA_functors.h b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_LA_functors.h
new file mode 100644
index 00000000..871c463a
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_LA_functors.h
@@ -0,0 +1,344 @@
+// 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_CARTESIAN_LA_FUNCTORS_H
+#define CGAL_CARTESIAN_LA_FUNCTORS_H
+
+#include <CGAL/NewKernel_d/utils.h>
+#include <CGAL/is_iterator.h>
+#include <CGAL/argument_swaps.h>
+#include <CGAL/Kernel/Return_base_tag.h>
+#include <CGAL/transforming_iterator.h>
+#include <CGAL/NewKernel_d/store_kernel.h>
+#include <CGAL/Dimension.h>
+
+namespace CGAL {
+namespace CartesianDVectorBase {
+#ifndef CGAL_CXX11
+namespace internal {
+template<class R_,class Dim_> struct Construct_LA_vector_ {
+ struct Never_use {};
+ void operator()(Never_use)const;
+};
+#define CGAL_CODE(Z,N,_) template<class R> struct Construct_LA_vector_<R,Dimension_tag<N> > { \
+ typedef typename R::Constructor Constructor; \
+ typedef typename Get_type<R, RT_tag>::type RT; \
+ typedef typename R::Vector_ result_type; \
+ result_type operator() \
+ (BOOST_PP_ENUM_PARAMS(N,RT const& t)) const { \
+ return typename Constructor::Values()(BOOST_PP_ENUM_PARAMS(N,t)); \
+ } \
+ result_type operator() \
+ (BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(N),RT const& t)) const { \
+ return typename Constructor::Values_divide()(t##N,BOOST_PP_ENUM_PARAMS(N,t)); \
+ } \
+ };
+BOOST_PP_REPEAT_FROM_TO(2, 11, CGAL_CODE, _ )
+#undef CGAL_CODE
+}
+#endif
+
+template<class R_,class Zero_> struct Construct_LA_vector
+: private Store_kernel<R_>
+#ifndef CGAL_CXX11
+, public internal::Construct_LA_vector_<R_,typename R_::Default_ambient_dimension>
+#endif
+{
+ //CGAL_FUNCTOR_INIT_IGNORE(Construct_LA_vector)
+ CGAL_FUNCTOR_INIT_STORE(Construct_LA_vector)
+ typedef R_ R;
+ typedef typename R::Constructor Constructor;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef typename R::Vector_ result_type;
+ typedef typename R_::Default_ambient_dimension Dimension;
+ result_type operator()(int d)const{
+ CGAL_assertion(check_dimension_eq(d,this->kernel().dimension()));
+ return typename Constructor::Dimension()(d);
+ }
+ result_type operator()()const{
+ return typename Constructor::Dimension()((std::max)(0,this->kernel().dimension()));
+ }
+ result_type operator()(int d, Zero_ const&)const{
+ CGAL_assertion(check_dimension_eq(d,this->kernel().dimension()));
+ return typename Constructor::Dimension()(d);
+ }
+ result_type operator()(Zero_ const&)const{
+ // Makes no sense for an unknown dimension.
+ return typename Constructor::Dimension()(this->kernel().dimension());
+ }
+ result_type operator()(result_type const& v)const{
+ return v;
+ }
+#ifdef CGAL_CXX11
+ result_type operator()(result_type&& v)const{
+ return std::move(v);
+ }
+#endif
+#ifdef CGAL_CXX11
+ template<class...U>
+ typename std::enable_if<Constructible_from_each<RT,U...>::value &&
+ boost::is_same<Dimension_tag<sizeof...(U)>, Dimension>::value,
+ result_type>::type
+ operator()(U&&...u)const{
+ return typename Constructor::Values()(std::forward<U>(u)...);
+ }
+ //template<class...U,class=typename std::enable_if<Constructible_from_each<RT,U...>::value>::type,class=typename std::enable_if<(sizeof...(U)==static_dim+1)>::type,class=void>
+ template<class...U>
+ typename std::enable_if<Constructible_from_each<RT,U...>::value &&
+ boost::is_same<Dimension_tag<sizeof...(U)-1>, Dimension>::value,
+ result_type>::type
+ operator()(U&&...u)const{
+ return Apply_to_last_then_rest()(typename Constructor::Values_divide(),std::forward<U>(u)...);
+ }
+#else
+ using internal::Construct_LA_vector_<R_,typename R::Default_ambient_dimension>::operator();
+#endif
+ template<class Iter> inline
+ typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
+ (Iter f,Iter g,Cartesian_tag t)const
+ {
+ return this->operator()((int)std::distance(f,g),f,g,t);
+ }
+ template<class Iter> inline
+ typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
+ (int d,Iter f,Iter g,Cartesian_tag)const
+ {
+ CGAL_assertion(d==std::distance(f,g));
+ CGAL_assertion(check_dimension_eq(d,this->kernel().dimension()));
+ return typename Constructor::Iterator()(d,f,g);
+ }
+ template<class Iter> inline
+ typename boost::enable_if<is_iterator_type<Iter,std::bidirectional_iterator_tag>,result_type>::type operator()
+ (Iter f,Iter g,Homogeneous_tag)const
+ {
+ --g;
+ return this->operator()((int)std::distance(f,g),f,g,*g);
+ }
+ template<class Iter> inline
+ typename boost::enable_if<is_iterator_type<Iter,std::bidirectional_iterator_tag>,result_type>::type operator()
+ (int d,Iter f,Iter g,Homogeneous_tag)const
+ {
+ --g;
+ return this->operator()(d,f,g,*g);
+ }
+ template<class Iter> inline
+ typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
+ (Iter f,Iter g)const
+ {
+ // Shouldn't it try comparing dist(f,g) to the dimension if it is known?
+ return this->operator()(f,g,typename R::Rep_tag());
+ }
+ template<class Iter> inline
+ typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
+ (int d,Iter f,Iter g)const
+ {
+ return this->operator()(d,f,g,typename R::Rep_tag());
+ }
+
+ // Last homogeneous coordinate given separately
+ template<class Iter,class NT> inline
+ typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
+ (int d,Iter f,Iter g,NT const&l)const
+ {
+ CGAL_assertion(d==std::distance(f,g));
+ CGAL_assertion(check_dimension_eq(d,this->kernel().dimension()));
+ // RT? better be safe for now
+ return typename Constructor::Iterator()(d,CGAL::make_transforming_iterator(f,Divide<FT,NT>(l)),CGAL::make_transforming_iterator(g,Divide<FT,NT>(l)));
+ }
+ template<class Iter,class NT> inline
+ typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
+ (Iter f,Iter g,NT const&l)const
+ {
+ return this->operator()((int)std::distance(f,g),f,g,l);
+ }
+};
+
+template<class R_> struct Compute_cartesian_coordinate {
+ CGAL_FUNCTOR_INIT_IGNORE(Compute_cartesian_coordinate)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename R::Vector_ first_argument_type;
+ typedef int second_argument_type;
+ typedef Tag_true Is_exact;
+#ifdef CGAL_CXX11
+ typedef decltype(std::declval<const first_argument_type>()[0]) result_type;
+#else
+ typedef RT const& result_type;
+ // RT const& doesn't work with some LA (Eigen2 for instance) so we
+ // should use plain RT or find a way to detect this.
+#endif
+
+ result_type operator()(first_argument_type const& v,int i)const{
+ return v[i];
+ }
+};
+
+template<class R_> struct Construct_cartesian_const_iterator {
+ CGAL_FUNCTOR_INIT_IGNORE(Construct_cartesian_const_iterator)
+ typedef R_ R;
+ typedef typename R::Vector_ argument_type;
+ typedef typename R::LA_vector S_;
+ typedef typename R::Point_cartesian_const_iterator result_type;
+ // same as Vector
+ typedef Tag_true Is_exact;
+
+ result_type operator()(argument_type const& v,Begin_tag)const{
+ return S_::vector_begin(v);
+ }
+ result_type operator()(argument_type const& v,End_tag)const{
+ return S_::vector_end(v);
+ }
+};
+
+template<class R_> struct Midpoint {
+ CGAL_FUNCTOR_INIT_IGNORE(Midpoint)
+ typedef R_ R;
+ typedef typename Get_type<R, Point_tag>::type first_argument_type;
+ typedef typename Get_type<R, Point_tag>::type second_argument_type;
+ typedef typename Get_type<R, Point_tag>::type result_type;
+
+ result_type operator()(result_type const& a, result_type const& b)const{
+ return (a+b)/2;
+ }
+};
+
+template<class R_> struct Sum_of_vectors {
+ CGAL_FUNCTOR_INIT_IGNORE(Sum_of_vectors)
+ typedef R_ R;
+ typedef typename Get_type<R, Vector_tag>::type first_argument_type;
+ typedef typename Get_type<R, Vector_tag>::type second_argument_type;
+ typedef typename Get_type<R, Vector_tag>::type result_type;
+
+ result_type operator()(result_type const& a, result_type const& b)const{
+ return a+b;
+ }
+};
+
+template<class R_> struct Difference_of_vectors {
+ CGAL_FUNCTOR_INIT_IGNORE(Difference_of_vectors)
+ typedef R_ R;
+ typedef typename Get_type<R, Vector_tag>::type first_argument_type;
+ typedef typename Get_type<R, Vector_tag>::type second_argument_type;
+ typedef typename Get_type<R, Vector_tag>::type result_type;
+
+ result_type operator()(result_type const& a, result_type const& b)const{
+ return a-b;
+ }
+};
+
+template<class R_> struct Opposite_vector {
+ CGAL_FUNCTOR_INIT_IGNORE(Opposite_vector)
+ typedef R_ R;
+ typedef typename Get_type<R, Vector_tag>::type result_type;
+ typedef typename Get_type<R, Vector_tag>::type argument_type;
+
+ result_type operator()(result_type const& v)const{
+ return -v;
+ }
+};
+
+template<class R_> struct Scalar_product {
+ CGAL_FUNCTOR_INIT_IGNORE(Scalar_product)
+ typedef R_ R;
+ typedef typename R::LA_vector LA;
+ typedef typename Get_type<R, RT_tag>::type result_type;
+ typedef typename Get_type<R, Vector_tag>::type first_argument_type;
+ typedef typename Get_type<R, Vector_tag>::type second_argument_type;
+
+ result_type operator()(first_argument_type const& a, second_argument_type const& b)const{
+ return LA::dot_product(a,b);
+ }
+};
+
+template<class R_> struct Squared_distance_to_origin_stored {
+ CGAL_FUNCTOR_INIT_IGNORE(Squared_distance_to_origin_stored)
+ typedef R_ R;
+ typedef typename R::LA_vector LA;
+ typedef typename Get_type<R, RT_tag>::type result_type;
+ typedef typename Get_type<R, Point_tag>::type argument_type;
+
+ result_type operator()(argument_type const& a)const{
+ return LA::squared_norm(a);
+ }
+};
+
+template<class R_> struct Squared_distance_to_origin_via_dotprod {
+ CGAL_FUNCTOR_INIT_IGNORE(Squared_distance_to_origin_via_dotprod)
+ typedef R_ R;
+ typedef typename R::LA_vector LA;
+ typedef typename Get_type<R, RT_tag>::type result_type;
+ typedef typename Get_type<R, Point_tag>::type argument_type;
+
+ result_type operator()(argument_type const& a)const{
+ return LA::dot_product(a,a);
+ }
+};
+
+template<class R_> struct Orientation_of_vectors {
+ CGAL_FUNCTOR_INIT_IGNORE(Orientation_of_vectors)
+ typedef R_ R;
+ typedef typename R::Vector_cartesian_const_iterator first_argument_type;
+ typedef typename R::Vector_cartesian_const_iterator second_argument_type;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ typedef typename R::LA_vector LA;
+
+ template<class Iter>
+ result_type operator()(Iter const& f, Iter const& e) const {
+ return LA::determinant_of_iterators_to_vectors(f,e);
+ }
+};
+
+template<class R_> struct Orientation_of_points {
+ CGAL_FUNCTOR_INIT_IGNORE(Orientation_of_points)
+ typedef R_ R;
+ typedef typename R::Point_cartesian_const_iterator first_argument_type;
+ typedef typename R::Point_cartesian_const_iterator second_argument_type;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ typedef typename R::LA_vector LA;
+
+ template<class Iter>
+ result_type operator()(Iter const& f, Iter const& e) const {
+ return LA::determinant_of_iterators_to_points(f,e);
+ }
+};
+
+template<class R_> struct PV_dimension {
+ CGAL_FUNCTOR_INIT_IGNORE(PV_dimension)
+ typedef R_ R;
+ typedef typename R::Vector_ argument_type;
+ typedef int result_type;
+ typedef typename R::LA_vector LA;
+ typedef Tag_true Is_exact;
+
+ template<class T>
+ result_type operator()(T const& v) const {
+ return LA::size_of_vector(v);
+ }
+};
+
+template<class R_> struct Identity_functor {
+ CGAL_FUNCTOR_INIT_IGNORE(Identity_functor)
+ template<class T>
+ T const& operator()(T const&t) const { return t; }
+};
+
+}
+} // namespace CGAL
+#endif // CGAL_CARTESIAN_LA_FUNCTORS_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_base.h b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_base.h
new file mode 100644
index 00000000..641bf8ae
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_base.h
@@ -0,0 +1,40 @@
+// 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_KERNEL_D_CARTESIAN_BASE_H
+#define CGAL_KERNEL_D_CARTESIAN_BASE_H
+
+#include <CGAL/basic.h>
+#include <CGAL/NewKernel_d/Cartesian_complete.h>
+#include <CGAL/NewKernel_d/Cartesian_LA_base.h>
+
+namespace CGAL {
+#define CGAL_BASE \
+ Cartesian_LA_base_d< FT_, Dim_ >
+template < typename FT_, typename Dim_, typename Derived_=Default>
+struct Cartesian_base_d : public CGAL_BASE
+{
+ CGAL_CONSTEXPR Cartesian_base_d(){}
+ CGAL_CONSTEXPR Cartesian_base_d(int d):CGAL_BASE(d){}
+};
+#undef CGAL_BASE
+
+} //namespace CGAL
+
+#endif // CGAL_KERNEL_D_CARTESIAN_BASE_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_change_FT.h b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_change_FT.h
new file mode 100644
index 00000000..e09c72d0
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_change_FT.h
@@ -0,0 +1,117 @@
+// 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_KERNEL_D_CARTESIAN_CHANGE_FT_H
+#define CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H
+
+#include <CGAL/basic.h>
+#include <CGAL/NT_converter.h>
+#include <CGAL/transforming_iterator.h>
+#include <CGAL/NewKernel_d/Cartesian_complete.h>
+
+namespace CGAL {
+
+template < typename Base_, typename FT_, typename LA_=CGAL::LA_eigen<FT_,typename Base_::Default_ambient_dimension> >
+struct Cartesian_change_FT_base : public
+ Base_
+{
+ CGAL_CONSTEXPR Cartesian_change_FT_base(){}
+ CGAL_CONSTEXPR Cartesian_change_FT_base(int d):Base_(d){}
+
+ typedef Cartesian_change_FT_base Self;
+ typedef Base_ Kernel_base;
+ typedef LA_ LA;
+
+ template <class T, class D=void> struct Type : Inherit_type<Base_, T> {};
+ template <class D> struct Type <FT_tag, D> { typedef FT_ type; };
+ template <class D> struct Type <RT_tag, D> { typedef FT_ type; };
+
+ typedef NT_converter<typename Get_type<Kernel_base, FT_tag>::type,FT_> FT_converter;
+ typedef transforming_iterator<FT_converter,typename Kernel_base::Point_cartesian_const_iterator> Point_cartesian_const_iterator;
+ typedef transforming_iterator<FT_converter,typename Kernel_base::Vector_cartesian_const_iterator> Vector_cartesian_const_iterator;
+ //FIXME: use Iterator_list!
+ /*
+ template<class T,bool=CGAL_BOOSTD is_same<typename iterator_tag_traits<T>::value_tag,FT_tag>::value>
+ struct Iterator : Get_type<Kernel_base,T> {};
+ template<class T> struct Iterator<T,true> {
+ typedef transforming_iterator<FT_converter,typename Get_type<Kernel_base,T>::type> type;
+ };
+ */
+
+ template<class Tag_,class Type_>
+ struct Construct_cartesian_const_iterator_ {
+ typedef typename Get_functor<Kernel_base, Tag_>::type Functor_base;
+ Construct_cartesian_const_iterator_(){}
+ Construct_cartesian_const_iterator_(Self const&r):f(r){}
+ Functor_base f;
+ typedef Type_ result_type;
+ template<class T>
+ result_type operator()(T const& v, Begin_tag)const{
+ return make_transforming_iterator(f(v,Begin_tag()),FT_converter());
+ }
+ template<class T>
+ result_type operator()(T const& v, End_tag)const{
+ return make_transforming_iterator(f(v,End_tag()),FT_converter());
+ }
+ };
+ typedef Construct_cartesian_const_iterator_<Construct_ttag<Point_cartesian_const_iterator_tag>,Point_cartesian_const_iterator> Construct_point_cartesian_const_iterator;
+ typedef Construct_cartesian_const_iterator_<Construct_ttag<Vector_cartesian_const_iterator_tag>,Vector_cartesian_const_iterator> Construct_vector_cartesian_const_iterator;
+
+ template<class Tag_>
+ struct Compute_cartesian_coordinate {
+ typedef typename Get_functor<Kernel_base, Tag_>::type Functor_base;
+ Compute_cartesian_coordinate(){}
+ Compute_cartesian_coordinate(Self const&r):f(r){}
+ Functor_base f;
+ typedef FT_ result_type;
+ template<class Obj_>
+ result_type operator()(Obj_ const& v,int i)const{
+ return FT_converter()(f(v,i));
+ }
+ };
+
+ template<class T,class U=void,class=typename Get_functor_category<Cartesian_change_FT_base,T>::type> struct Functor :
+ Inherit_functor<Kernel_base,T,U> { };
+ template<class T,class U> struct Functor<T,U,Compute_tag> { };
+ template<class T,class U> struct Functor<T,U,Predicate_tag> { };
+ template<class D> struct Functor<Compute_point_cartesian_coordinate_tag,D,Compute_tag> {
+ typedef Compute_cartesian_coordinate<Compute_point_cartesian_coordinate_tag> type;
+ };
+ template<class D> struct Functor<Compute_vector_cartesian_coordinate_tag,D,Compute_tag> {
+ typedef Compute_cartesian_coordinate<Compute_vector_cartesian_coordinate_tag> type;
+ };
+ template<class D> struct Functor<Construct_ttag<Point_cartesian_const_iterator_tag>,D,Construct_iterator_tag> {
+ typedef Construct_point_cartesian_const_iterator type;
+ };
+ template<class D> struct Functor<Construct_ttag<Vector_cartesian_const_iterator_tag>,D,Construct_iterator_tag> {
+ typedef Construct_vector_cartesian_const_iterator type;
+ };
+};
+
+template < typename Base_, typename FT_>
+struct Cartesian_change_FT : public
+ Cartesian_change_FT_base<Base_,FT_>
+{
+ CGAL_CONSTEXPR Cartesian_change_FT(){}
+ CGAL_CONSTEXPR Cartesian_change_FT(int d):Cartesian_change_FT_base<Base_,FT_>(d){}
+};
+
+} //namespace CGAL
+
+#endif // CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_complete.h b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_complete.h
new file mode 100644
index 00000000..ef8921db
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_complete.h
@@ -0,0 +1,33 @@
+// 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_KERNEL_D_CARTESIAN_COMPLETE_H
+#define CGAL_KERNEL_D_CARTESIAN_COMPLETE_H
+
+#include <CGAL/NewKernel_d/function_objects_cartesian.h>
+#include <CGAL/NewKernel_d/Cartesian_per_dimension.h>
+#include <CGAL/NewKernel_d/Types/Segment.h>
+#include <CGAL/NewKernel_d/Types/Sphere.h>
+#include <CGAL/NewKernel_d/Types/Hyperplane.h>
+#include <CGAL/NewKernel_d/Types/Aff_transformation.h>
+#include <CGAL/NewKernel_d/Types/Line.h>
+#include <CGAL/NewKernel_d/Types/Ray.h>
+#include <CGAL/NewKernel_d/Types/Iso_box.h>
+
+#endif // CGAL_KERNEL_D_CARTESIAN_COMPLETE_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_filter_K.h b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_filter_K.h
new file mode 100644
index 00000000..179e97bf
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_filter_K.h
@@ -0,0 +1,79 @@
+// 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_KERNEL_D_CARTESIAN_FILTER_K_H
+#define CGAL_KERNEL_D_CARTESIAN_FILTER_K_H
+
+#include <CGAL/basic.h>
+#include <CGAL/NewKernel_d/KernelD_converter.h>
+#include <CGAL/NewKernel_d/Filtered_predicate2.h>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
+
+namespace CGAL {
+
+template < typename Base_, typename AK_, typename EK_ >
+struct Cartesian_filter_K : public Base_,
+ private Store_kernel<AK_>, private Store_kernel2<EK_>
+{
+ CGAL_CONSTEXPR Cartesian_filter_K(){}
+ CGAL_CONSTEXPR Cartesian_filter_K(int d):Base_(d){}
+ //FIXME: or do we want an instance of AK and EK belonging to this kernel,
+ //instead of a reference to external ones?
+ CGAL_CONSTEXPR Cartesian_filter_K(AK_ const&a,EK_ const&b):Base_(),Store_kernel<AK_>(a),Store_kernel2<EK_>(b){}
+ CGAL_CONSTEXPR Cartesian_filter_K(int d,AK_ const&a,EK_ const&b):Base_(d),Store_kernel<AK_>(a),Store_kernel2<EK_>(b){}
+ typedef Base_ Kernel_base;
+ typedef AK_ AK;
+ typedef EK_ EK;
+ typedef typename Store_kernel<AK_>::reference_type AK_rt;
+ AK_rt approximate_kernel()const{return this->kernel();}
+ typedef typename Store_kernel2<EK_>::reference2_type EK_rt;
+ EK_rt exact_kernel()const{return this->kernel2();}
+
+ // MSVC is too dumb to perform the empty base optimization.
+ typedef boost::mpl::and_<
+ internal::Do_not_store_kernel<Kernel_base>,
+ internal::Do_not_store_kernel<AK>,
+ internal::Do_not_store_kernel<EK> > Do_not_store_kernel;
+
+ //TODO: C2A/C2E could be able to convert *this into this->kernel() or this->kernel2().
+ typedef KernelD_converter<Kernel_base,AK> C2A;
+ typedef KernelD_converter<Kernel_base,EK> C2E;
+
+ // fix the types
+ // TODO: only fix some types, based on some criterion?
+ 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 :
+ Inherit_functor<Kernel_base,T,D> {};
+ template<class T,class D> struct Functor<T,D,Predicate_tag> {
+ typedef typename Get_functor<AK, T>::type AP;
+ typedef typename Get_functor<EK, T>::type EP;
+ typedef Filtered_predicate2<EP,AP,C2E,C2A> type;
+ };
+// TODO:
+// template<class T> struct Functor<T,No_filter_tag,Predicate_tag> :
+// Kernel_base::template Functor<T,No_filter_tag> {};
+// TODO:
+// detect when Less_cartesian_coordinate doesn't need filtering
+};
+
+} //namespace CGAL
+
+#endif // CGAL_KERNEL_D_CARTESIAN_FILTER_K_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_filter_NT.h b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_filter_NT.h
new file mode 100644
index 00000000..c390a55c
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_filter_NT.h
@@ -0,0 +1,93 @@
+// 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_KERNEL_D_CARTESIAN_FILTER_NT_H
+#define CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H
+
+#include <CGAL/basic.h>
+#include <CGAL/NewKernel_d/Cartesian_change_FT.h>
+#include <CGAL/internal/Exact_type_selector.h>
+
+namespace CGAL {
+
+template < typename Base_ >
+struct Cartesian_filter_NT : public Base_
+{
+ CGAL_CONSTEXPR Cartesian_filter_NT(){}
+ CGAL_CONSTEXPR Cartesian_filter_NT(int d):Base_(d){}
+ typedef Base_ Kernel_base;
+ typedef Cartesian_change_FT<Kernel_base,Interval_nt_advanced> K1;
+ typedef typename internal::Exact_field_selector<typename Get_type<Kernel_base, FT_tag>::type>::Type Exact_nt;
+ typedef Cartesian_change_FT<Kernel_base,Exact_nt> K2;
+
+ template<class T,class D=void,class=typename Get_functor_category<Cartesian_filter_NT,T>::type> struct Functor :
+ Inherit_functor<Kernel_base,T,D> {};
+ template<class T,class D> struct Functor<T,D,Predicate_tag> {
+ struct type {
+ //TODO: use compression (derive from a compressed_pair?)
+ typedef typename Get_functor<K1, T>::type P1; P1 p1;
+ typedef typename Get_functor<K2, T>::type P2; P2 p2;
+ typedef typename P2::result_type result_type;
+ type(){}
+ type(Cartesian_filter_NT const&k):p1(reinterpret_cast<K1 const&>(k)),p2(reinterpret_cast<K2 const&>(k)){}
+ //FIXME: if predicate's constructor takes a kernel as argument, how do we translate that? reinterpret_cast is really ugly and possibly unsafe.
+
+#ifdef CGAL_CXX11
+ template<class...U> result_type operator()(U&&...u)const{
+ {
+ Protect_FPU_rounding<true> p;
+ try {
+ typename P1::result_type res=p1(u...); // don't forward as u may be reused
+ if(is_certain(res)) return get_certain(res);
+ } catch (Uncertain_conversion_exception) {}
+ }
+ return p2(std::forward<U>(u)...);
+ }
+#else
+ result_type operator()()const{ // does it make sense to have 0 argument?
+ {
+ Protect_FPU_rounding<true> p;
+ try {
+ typename P1::result_type res=p1();
+ if(is_certain(res)) return get_certain(res);
+ } catch (Uncertain_conversion_exception) {}
+ }
+ return p2();
+ }
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t))const{ \
+ { \
+ Protect_FPU_rounding<true> p; \
+ try { \
+ typename P1::result_type res=p1(BOOST_PP_ENUM_PARAMS(N,t)); \
+ if(is_certain(res)) return get_certain(res); \
+ } catch (Uncertain_conversion_exception) {} \
+ } \
+ return p2(BOOST_PP_ENUM_PARAMS(N,t)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+
+#endif
+ };
+ };
+};
+
+} //namespace CGAL
+
+#endif // CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_per_dimension.h b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_per_dimension.h
new file mode 100644
index 00000000..179f7319
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_per_dimension.h
@@ -0,0 +1,33 @@
+// 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_KD_CARTESIAN_PER_DIM_H
+#define CGAL_KD_CARTESIAN_PER_DIM_H
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/predicates/sign_of_determinant.h>
+
+// Should probably disappear.
+
+namespace CGAL {
+template <class Dim_, class R_, class Derived_>
+struct Cartesian_per_dimension : public R_ {};
+}
+
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_static_filters.h b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_static_filters.h
new file mode 100644
index 00000000..693e962a
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Cartesian_static_filters.h
@@ -0,0 +1,95 @@
+// 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_KD_CARTESIAN_STATIC_FILTERS_H
+#define CGAL_KD_CARTESIAN_STATIC_FILTERS_H
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/internal/Static_filters/tools.h> // bug, should be included by the next one
+#include <CGAL/internal/Static_filters/Orientation_2.h>
+#include <boost/mpl/if.hpp>
+
+namespace CGAL {
+namespace SFA { // static filter adapter
+// Note that this would be quite a bit simpler without stateful kernels
+template <class Base_,class R_> struct Orientation_of_points_2 : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Orientation_of_points_2)
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename Get_type<R_, Orientation_tag>::type result_type;
+ typedef typename Get_type<R_, FT_tag>::type FT;
+ typedef typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type CC;
+ typedef typename Get_functor<Base_, Orientation_of_points_tag>::type Orientation_base;
+ // TODO: Move this out for easy reuse
+ struct Adapter {
+ struct Point_2 {
+ R_ const&r; CC const&c; Point const& p;
+ Point_2(R_ const&r_, CC const&c_, Point const&p_):r(r_),c(c_),p(p_){}
+ // use result_of instead?
+ typename CC::result_type x()const{return c(p,0);}
+ typename CC::result_type y()const{return c(p,1);}
+ };
+ struct Vector_2 {};
+ struct Circle_2 {};
+ struct Orientation_2 {
+ typedef typename Orientation_of_points_2::result_type result_type;
+ result_type operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C)const{
+ Point const* t[3]={&A.p,&B.p,&C.p};
+ return Orientation_base(A.r)(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+3));
+ }
+ };
+ };
+ template<class Iter> result_type operator()(Iter f, Iter CGAL_assertion_code(e))const{
+ CC c(this->kernel());
+ Point const& A=*f;
+ Point const& B=*++f;
+ Point const& C=*++f;
+ CGAL_assertion(++f==e);
+ typedef typename Adapter::Point_2 P;
+ return typename internal::Static_filters_predicates::Orientation_2<Adapter>()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C));
+ }
+};
+}
+
+template <class Dim_ /* should be implicit */, class R_, class Derived_=Default>
+struct Cartesian_static_filters : public R_ {
+ CGAL_CONSTEXPR Cartesian_static_filters(){}
+ CGAL_CONSTEXPR Cartesian_static_filters(int d):R_(d){}
+};
+
+template <class R_, class Derived_>
+struct Cartesian_static_filters<Dimension_tag<2>, R_, Derived_> : public R_ {
+ CGAL_CONSTEXPR Cartesian_static_filters(){}
+ CGAL_CONSTEXPR Cartesian_static_filters(int d):R_(d){}
+ typedef Cartesian_static_filters<Dimension_tag<2>, R_, Derived_> Self;
+ typedef typename Default::Get<Derived_,Self>::type Derived;
+ template <class T, class=void> struct Functor : Inherit_functor<R_, T> {};
+ template <class D> struct Functor <Orientation_of_points_tag,D> {
+ typedef
+ //typename boost::mpl::if_ <
+ //boost::is_same<D,No_filter_tag>,
+ //typename Get_functor<R_, Orientation_of_points_tag>::type,
+ SFA::Orientation_of_points_2<R_,Derived>
+ // >::type
+ type;
+ };
+};
+
+}
+
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Coaffine.h b/include/gudhi_patches/CGAL/NewKernel_d/Coaffine.h
new file mode 100644
index 00000000..43015d24
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Coaffine.h
@@ -0,0 +1,330 @@
+// 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_KD_COAFFINE_H
+#define CGAL_KD_COAFFINE_H
+#include <vector>
+#include <algorithm>
+#include <iterator>
+#include <CGAL/Dimension.h>
+#include <CGAL/NewKernel_d/functor_tags.h>
+
+namespace CGAL {
+namespace CartesianDKernelFunctors {
+struct Flat_orientation {
+ std::vector<int> proj;
+ std::vector<int> rest;
+ bool reverse;
+};
+
+// For debugging purposes
+inline std::ostream& operator<< (std::ostream& o, Flat_orientation const& f) {
+ o << "Proj: ";
+ for(std::vector<int>::const_iterator i=f.proj.begin();
+ i!=f.proj.end(); ++i)
+ o << *i << ' ';
+ o << "\nRest: ";
+ for(std::vector<int>::const_iterator i=f.rest.begin();
+ i!=f.rest.end(); ++i)
+ o << *i << ' ';
+ o << "\nInv: " << f.reverse;
+ return o << '\n';
+}
+
+namespace internal {
+namespace coaffine {
+template<class Mat>
+inline void debug_matrix(std::ostream& o, Mat const&mat) {
+ for(int i=0;i<mat.rows();++i){
+ for(int j=0;j<mat.cols();++j){
+ o<<mat(i,j)<<' ';
+ }
+ o<<'\n';
+ }
+}
+}
+}
+
+template<class R_> struct Construct_flat_orientation : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Construct_flat_orientation)
+ typedef R_ R;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type Dplusone;
+ typedef typename R::LA::template Rebind_dimension<Dynamic_dimension_tag,Dplusone>::Other LA;
+ typedef typename LA::Square_matrix Matrix;
+ typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type CCC;
+ typedef typename Get_functor<R, Point_dimension_tag>::type PD;
+ typedef Flat_orientation result_type;
+
+ // This implementation is going to suck. Maybe we should push the
+ // functionality into LA. And we should check (in debug mode) that
+ // the points are affinely independent.
+ template<class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ Iter f_save = f;
+ PD pd (this->kernel());
+ CCC ccc (this->kernel());
+ int dim = pd(*f);
+ Matrix coord (dim+1, dim+1); // use distance(f,e)? This matrix doesn't need to be square.
+ int col = 0;
+ Flat_orientation o;
+ std::vector<int>& proj=o.proj;
+ std::vector<int>& rest=o.rest; rest.reserve(dim+1);
+ for(int i=0; i<dim+1; ++i) rest.push_back(i);
+ for( ; f != e ; ++col, ++f ) {
+ //std::cerr << "(*f)[0]=" << (*f)[0] << std::endl;
+ Point const&p=*f;
+ // use a coordinate iterator instead?
+ for(int i=0; i<dim; ++i) coord(col, i) = ccc(p, i);
+ coord(col,dim)=1;
+ int d = (int)proj.size()+1;
+ Matrix m (d, d);
+ // Fill the matrix with what we already have
+ for(int i=0; i<d; ++i)
+ for(int j=0; j<d-1; ++j)
+ m(i,j) = coord(i, proj[j]);
+ // Try to complete with any other coordinate
+ // TODO: iterate on rest by the end, or use a (forward_)list.
+ for(std::vector<int>::iterator it=rest.begin();;++it) {
+ CGAL_assertion(it!=rest.end());
+ for(int i=0; i<d; ++i) m(i,d-1) = coord(i, *it);
+ if(LA::sign_of_determinant(m)!=0) {
+ proj.push_back(*it);
+ rest.erase(it);
+ break;
+ }
+ }
+ }
+ std::sort(proj.begin(),proj.end());
+ typename Get_functor<R, In_flat_orientation_tag>::type ifo(this->kernel());
+ o.reverse = false;
+ o.reverse = ifo(o, f_save, e) != CGAL::POSITIVE;
+ return o;
+ }
+};
+
+template<class R_> struct Contained_in_affine_hull : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Contained_in_affine_hull)
+ typedef R_ R;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Bool_tag>::type result_type;
+ typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type CCC;
+ typedef typename Get_functor<R, Point_dimension_tag>::type PD;
+ //typedef typename Increment_dimension<typename R::Default_ambient_dimension>::type D1;
+ //typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type D2;
+ //typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
+ typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type Dplusone;
+ typedef typename R::LA::template Rebind_dimension<Dynamic_dimension_tag,Dplusone>::Other LA;
+ typedef typename LA::Square_matrix Matrix;
+
+ // mostly copied from Construct_flat_orientation. TODO: dedup this code or use LA.
+ template<class Iter>
+ result_type operator()(Iter f, Iter e, Point const&x) const {
+ // FIXME: are the points in (f,e) required to be affinely independent?
+ PD pd (this->kernel());
+ CCC ccc (this->kernel());
+ int dim=pd(*f);
+ Matrix coord (dim+1, dim+1); // use distance
+ int col = 0;
+ std::vector<int> proj;
+ std::vector<int> rest; rest.reserve(dim+1);
+ for(int i=0; i<dim+1; ++i) rest.push_back(i);
+ for( ; f != e ; ++col, ++f ) {
+ Point const&p=*f;
+ for(int i=0; i<dim; ++i) coord(col, i) = ccc(p, i);
+ coord(col,dim)=1;
+ int d = (int)proj.size()+1;
+ Matrix m (d, d);
+ for(int i=0; i<d; ++i)
+ for(int j=0; j<d-1; ++j)
+ m(i,j) = coord(i, proj[j]);
+ for(std::vector<int>::iterator it=rest.begin();it!=rest.end();++it) {
+ for(int i=0; i<d; ++i) m(i,d-1) = coord(i, *it);
+ if(LA::sign_of_determinant(m)!=0) {
+ proj.push_back(*it);
+ rest.erase(it);
+ break;
+ }
+ }
+ }
+ for(int i=0; i<dim; ++i) coord(col, i) = ccc(x, i);
+ coord(col,dim)=1;
+ int d = (int)proj.size()+1;
+ Matrix m (d, d);
+ for(int i=0; i<d; ++i)
+ for(int j=0; j<d-1; ++j)
+ m(i,j) = coord(i, proj[j]);
+ for(std::vector<int>::iterator it=rest.begin();it!=rest.end();++it) {
+ for(int i=0; i<d; ++i) m(i,d-1) = coord(i, *it);
+ if(LA::sign_of_determinant(m)!=0) return false;
+ }
+ return true;
+ }
+};
+
+template<class R_> struct In_flat_orientation : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(In_flat_orientation)
+ typedef R_ R;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ typedef typename Increment_dimension<typename R::Default_ambient_dimension>::type D1;
+ typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type D2;
+ typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
+ typedef typename LA::Square_matrix Matrix;
+
+ template<class Iter>
+ result_type operator()(Flat_orientation const&o, Iter f, Iter e) const {
+ // TODO: work in the projection instead of the ambient space.
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+ int d=pd(*f);
+ Matrix m(d+1,d+1);
+ int i=0;
+ for(;f!=e;++f,++i) {
+ Point const& p=*f;
+ m(i,0)=1;
+ for(int j=0;j<d;++j){
+ m(i,j+1)=c(p,j);
+ }
+ }
+ for(std::vector<int>::const_iterator it = o.rest.begin(); it != o.rest.end() /* i<d+1 */; ++i, ++it) {
+ m(i,0)=1;
+ for(int j=0;j<d;++j){
+ m(i,j+1)=0; // unneeded if the matrix is initialized to 0
+ }
+ if(*it != d) m(i,1+*it)=1;
+ }
+
+ result_type ret = LA::sign_of_determinant(CGAL_MOVE(m));
+ if(o.reverse) ret=-ret;
+ return ret;
+ }
+};
+
+template<class R_> struct In_flat_side_of_oriented_sphere : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(In_flat_side_of_oriented_sphere)
+ typedef R_ R;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ typedef typename Increment_dimension<typename R::Default_ambient_dimension,2>::type D1;
+ typedef typename Increment_dimension<typename R::Max_ambient_dimension,2>::type D2;
+ typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
+ typedef typename LA::Square_matrix Matrix;
+
+ template<class Iter>
+ result_type operator()(Flat_orientation const&o, Iter f, Iter e, Point const&x) const {
+ // TODO: can't work in the projection, but we should at least remove the row of 1s.
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+ int d=pd(*f);
+ Matrix m(d+2,d+2);
+ int i=0;
+ for(;f!=e;++f,++i) {
+ Point const& p=*f;
+ m(i,0)=1;
+ m(i,d+1)=0;
+ for(int j=0;j<d;++j){
+ m(i,j+1)=c(p,j);
+ m(i,d+1)+=CGAL_NTS square(m(i,j+1));
+ }
+ }
+ for(std::vector<int>::const_iterator it = o.rest.begin(); it != o.rest.end() /* i<d+1 */; ++i, ++it) {
+ m(i,0)=1;
+ for(int j=0;j<d;++j){
+ m(i,j+1)=0; // unneeded if the matrix is initialized to 0
+ }
+ if(*it != d) m(i,d+1)=m(i,1+*it)=1;
+ else m(i,d+1)=0;
+ }
+ m(d+1,0)=1;
+ m(d+1,d+1)=0;
+ for(int j=0;j<d;++j){
+ m(d+1,j+1)=c(x,j);
+ m(d+1,d+1)+=CGAL_NTS square(m(d+1,j+1));
+ }
+
+ result_type ret = -LA::sign_of_determinant(CGAL_MOVE(m));
+ if(o.reverse) ret=-ret;
+ return ret;
+ }
+};
+
+template<class R_> struct In_flat_power_side_of_power_sphere_raw : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(In_flat_power_side_of_power_sphere_raw)
+ typedef R_ R;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ typedef typename Increment_dimension<typename R::Default_ambient_dimension,2>::type D1;
+ typedef typename Increment_dimension<typename R::Max_ambient_dimension,2>::type D2;
+ typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
+ typedef typename LA::Square_matrix Matrix;
+
+ template<class Iter, class IterW, class Wt>
+ result_type operator()(Flat_orientation const&o, Iter f, Iter e, IterW fw, Point const&x, Wt const&w) const {
+ // TODO: can't work in the projection, but we should at least remove the row of 1s.
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+ int d=pd(*f);
+ Matrix m(d+2,d+2);
+ int i=0;
+ for(;f!=e;++f,++fw,++i) {
+ Point const& p=*f;
+ m(i,0)=1;
+ m(i,d+1)=-*fw;
+ for(int j=0;j<d;++j){
+ m(i,j+1)=c(p,j);
+ m(i,d+1)+=CGAL_NTS square(m(i,j+1));
+ }
+ }
+ for(std::vector<int>::const_iterator it = o.rest.begin(); it != o.rest.end() /* i<d+1 */; ++i, ++it) {
+ m(i,0)=1;
+ for(int j=0;j<d;++j){
+ m(i,j+1)=0; // unneeded if the matrix is initialized to 0
+ }
+ if(*it != d) m(i,d+1)=m(i,1+*it)=1;
+ else m(i,d+1)=0;
+ }
+ m(d+1,0)=1;
+ m(d+1,d+1)=-w;
+ for(int j=0;j<d;++j){
+ m(d+1,j+1)=c(x,j);
+ m(d+1,d+1)+=CGAL_NTS square(m(d+1,j+1));
+ }
+
+ result_type ret = -LA::sign_of_determinant(CGAL_MOVE(m));
+ if(o.reverse) ret=-ret;
+ return ret;
+ }
+};
+
+
+}
+CGAL_KD_DEFAULT_TYPE(Flat_orientation_tag,(CGAL::CartesianDKernelFunctors::Flat_orientation),(),());
+CGAL_KD_DEFAULT_FUNCTOR(In_flat_orientation_tag,(CartesianDKernelFunctors::In_flat_orientation<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
+CGAL_KD_DEFAULT_FUNCTOR(In_flat_side_of_oriented_sphere_tag,(CartesianDKernelFunctors::In_flat_side_of_oriented_sphere<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
+CGAL_KD_DEFAULT_FUNCTOR(In_flat_power_side_of_power_sphere_raw_tag,(CartesianDKernelFunctors::In_flat_power_side_of_power_sphere_raw<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
+CGAL_KD_DEFAULT_FUNCTOR(Construct_flat_orientation_tag,(CartesianDKernelFunctors::Construct_flat_orientation<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag,In_flat_orientation_tag));
+CGAL_KD_DEFAULT_FUNCTOR(Contained_in_affine_hull_tag,(CartesianDKernelFunctors::Contained_in_affine_hull<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Define_kernel_types.h b/include/gudhi_patches/CGAL/NewKernel_d/Define_kernel_types.h
new file mode 100644
index 00000000..6a40515b
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Define_kernel_types.h
@@ -0,0 +1,50 @@
+// 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_DEFINE_KERNEL_TYPES_H
+#define CGAL_DEFINE_KERNEL_TYPES_H
+#include <CGAL/config.h>
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/typeset.h>
+#ifdef CGAL_CXX11
+#include <type_traits>
+#else
+#include <boost/type_traits.hpp>
+#endif
+
+namespace CGAL {
+ namespace internal {
+ template<class K,class Tag_,bool=iterator_tag_traits<Tag_>::is_iterator>
+ struct Type_or_iter : K::template Type<Tag_> {};
+ template<class K,class Tag_>
+ struct Type_or_iter<K, Tag_, true> : K::template Iterator<Tag_> {};
+ }
+ template<class K, class Base=K, class List=typename typeset_union<typename K::Object_list,typename K::Iterator_list>::type> struct Define_kernel_types;
+ template<class K, class Base>
+ struct Define_kernel_types <K, Base, typeset<> > : Base {};
+ template<class K>
+ struct Define_kernel_types <K, void, typeset<> > {};
+ template<class K, class Base, class List>
+ struct Define_kernel_types :
+ Typedef_tag_type<typename List::head,
+ typename internal::Type_or_iter<K,typename List::head>::type,
+ Define_kernel_types<K, Base, typename List::tail>
+ > {};
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Dimension_base.h b/include/gudhi_patches/CGAL/NewKernel_d/Dimension_base.h
new file mode 100644
index 00000000..be875e63
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Dimension_base.h
@@ -0,0 +1,49 @@
+// 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_KD_DIMENSION_BASE_h
+#define CGAL_KD_DIMENSION_BASE_h
+#include <CGAL/Dimension.h>
+#include <CGAL/assertions.h>
+#include <CGAL/NewKernel_d/utils.h>
+namespace CGAL {
+struct Store_dimension_base {
+ //TODO: add some assertions
+ Store_dimension_base(int dim=UNKNOWN_DIMENSION):dim_(dim){}
+ int dimension()const{return dim_;}
+ void set_dimension(int dim){dim_=dim;}
+ private:
+ int dim_;
+};
+template<class=Dynamic_dimension_tag>
+struct Dimension_base {
+ Dimension_base(int = UNKNOWN_DIMENSION){}
+ int dimension() const { return UNKNOWN_DIMENSION; }
+ void set_dimension(int) {}
+};
+template<int dim_>
+struct Dimension_base<Dimension_tag<dim_> > {
+ Dimension_base(){}
+ Dimension_base(int CGAL_assertion_code(dim)){CGAL_assertion(dim_==dim);}
+ int dimension()const{return dim_;}
+ void set_dimension(int dim){CGAL_assertion(dim_==dim);}
+};
+}
+#endif
+
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Filtered_predicate2.h b/include/gudhi_patches/CGAL/NewKernel_d/Filtered_predicate2.h
new file mode 100644
index 00000000..1a6a67bc
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Filtered_predicate2.h
@@ -0,0 +1,137 @@
+// Copyright (c) 2001-2005 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 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) : Sylvain Pion
+
+#ifndef CGAL_FILTERED_PREDICATE2_H
+#define CGAL_FILTERED_PREDICATE2_H
+
+#include <string>
+#include <CGAL/config.h>
+#include <CGAL/Interval_nt.h>
+#include <CGAL/Uncertain.h>
+#include <CGAL/Profile_counter.h>
+#include <CGAL/NewKernel_d/store_kernel.h>
+#include <boost/preprocessor.hpp>
+
+namespace CGAL {
+
+// This template class is a wrapper that implements the filtering for any
+// predicate (dynamic filters with IA).
+
+// TODO :
+// - each predicate in the default kernel should define a tag that says if it
+// wants to be filtered or not (=> all homogeneous predicate define this
+// tag). We could even test-suite that automatically. It makes a strong
+// new requirement on the kernel though...
+// Could be done with a traits mechanism ?
+// A default template could use the current IA, but other tags or whatever
+// could specify no filtering at all, or static filtering...
+// - same thing for constructions => virtual operator() ?
+// - similarly, constructions should have a tag saying if they can throw or
+// not, or we let all this up to the compiler optimizer to figure out ?
+// - Some caching could be done at the Point_2 level.
+
+
+template <class EP, class AP, class C2E, class C2A, bool Protection = true>
+class Filtered_predicate2
+{
+//TODO: pack (at least use a tuple)
+//FIXME: is it better to store those, or just store enough to recreate them
+//(i.e. possibly references to the kernels)?
+ EP ep;
+ AP ap;
+ C2E c2e;
+ C2A c2a;
+
+ typedef typename AP::result_type Ares;
+
+public:
+
+ typedef AP Approximate_predicate;
+ typedef EP Exact_predicate;
+ typedef C2E To_exact_converter;
+ typedef C2A To_approximate_converter;
+
+ // FIXME: should use result_of, see emails by Nico
+ typedef typename EP::result_type result_type;
+ // AP::result_type must be convertible to EP::result_type.
+
+ Filtered_predicate2()
+ {}
+
+ template <class K>
+ Filtered_predicate2(const K& k)
+ : ep(k.exact_kernel()), ap(k.approximate_kernel()), c2e(k,k.exact_kernel()), c2a(k,k.approximate_kernel())
+ {}
+
+#ifdef CGAL_CXX11
+ template <typename... Args>
+ result_type
+ operator()(Args&&... args) const
+ {
+ CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
+ // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG
+ {
+ Protect_FPU_rounding<Protection> p;
+ try
+ {
+ // No forward here, the arguments may still be needed
+ Ares res = ap(c2a(args)...);
+ if (is_certain(res))
+ return get_certain(res);
+ }
+ catch (Uncertain_conversion_exception) {}
+ }
+ CGAL_BRANCH_PROFILER_BRANCH(tmp);
+ Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
+ return ep(c2e(std::forward<Args>(args))...);
+ }
+#else
+
+#define CGAL_VAR(Z,N,C) C(a##N)
+#define CGAL_CODE(Z,N,_) \
+ template <BOOST_PP_ENUM_PARAMS(N,class A)> \
+ result_type \
+ operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) const \
+ { \
+ CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); \
+ { \
+ Protect_FPU_rounding<Protection> p; \
+ try \
+ { \
+ Ares res = ap(BOOST_PP_ENUM(N,CGAL_VAR,c2a)); \
+ if (is_certain(res)) \
+ return get_certain(res); \
+ } \
+ catch (Uncertain_conversion_exception) {} \
+ } \
+ CGAL_BRANCH_PROFILER_BRANCH(tmp); \
+ Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); \
+ return ep(BOOST_PP_ENUM(N,CGAL_VAR,c2e)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1, 10, CGAL_CODE, _ )
+#undef CGAL_CODE
+#undef CGAL_VAR
+
+#endif
+};
+
+} //namespace CGAL
+
+#endif // CGAL_FILTERED_PREDICATE2_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/KernelD_converter.h b/include/gudhi_patches/CGAL/NewKernel_d/KernelD_converter.h
new file mode 100644
index 00000000..a8896976
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/KernelD_converter.h
@@ -0,0 +1,199 @@
+// 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_KERNEL_D_CARTESIAN_CONVERTER_H
+#define CGAL_KERNEL_D_CARTESIAN_CONVERTER_H
+
+#include <CGAL/basic.h>
+#include <CGAL/tuple.h>
+#include <CGAL/typeset.h>
+#include <CGAL/Object.h>
+#include <CGAL/Origin.h>
+#include <CGAL/NT_converter.h>
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Kernel/mpl.h>
+#include <CGAL/is_iterator.h>
+#include <CGAL/transforming_iterator.h>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/if.hpp>
+#include <CGAL/NewKernel_d/store_kernel.h>
+#include <CGAL/NewKernel_d/Kernel_object_converter.h>
+
+namespace CGAL {
+namespace internal {
+// Reverses order, but that shouldn't matter.
+template<class K,class T> struct Map_taglist_to_typelist :
+ Map_taglist_to_typelist<K,typename T::tail>::type
+ ::template add<typename Get_type<K, typename T::head>::type>
+{};
+template<class K> struct Map_taglist_to_typelist<K,typeset<> > : typeset<> {};
+}
+
+template<class List = typeset<> >
+struct Object_converter {
+ typedef Object result_type;
+ template<class F>
+ result_type operator()(Object const& o, F const& f) const {
+ typedef typename List::head H;
+ if (H const* ptr = object_cast<H>(&o))
+ return make_object(f(*ptr));
+ else
+ return Object_converter<typename List::tail>()(o,f);
+ }
+};
+template<>
+struct Object_converter <typeset<> > {
+ typedef Object result_type;
+ template<class F>
+ result_type operator()(Object const&,F const&)const {
+ CGAL_error_msg("Cartesiand_converter is unable to determine what is wrapped in the Object");
+ return Object();
+ }
+};
+
+
+ //TODO: special case when K1==K2 (or they are very close?)
+template<class Final_, class K1, class K2, class List>
+class KernelD_converter_
+: public KernelD_converter_<Final_,K1,K2,typename List::tail>
+{
+ typedef typename List::head Tag_;
+ typedef typename List::tail Rest;
+ typedef KernelD_converter_<Final_,K1,K2,Rest> Base;
+ typedef typename Get_type<K1,Tag_>::type K1_Obj;
+ typedef typename Get_type<K2,Tag_>::type K2_Obj;
+ typedef typename Get_functor<K1, Convert_ttag<Tag_> >::type K1_Conv;
+ typedef KO_converter<Tag_,K1,K2> KOC;
+ typedef CGAL_BOOSTD is_same<K1_Conv, Null_functor> no_converter;
+ typedef typename internal::Map_taglist_to_typelist<K1,Rest>::type::template contains<K1_Obj> duplicate;
+
+ // Disable the conversion in some cases:
+ struct Do_not_use{};
+
+ // Explicit calls to boost::mpl functions to avoid parenthesis
+ // warning on some versions of GCC
+ typedef typename boost::mpl::if_ <
+ // If Point==Vector, keep only one conversion
+ boost::mpl::or_<boost::mpl::bool_<duplicate::value>,
+ // For iterator objects, the default is make_transforming_iterator
+ boost::mpl::bool_<(iterator_tag_traits<Tag_>::is_iterator && no_converter::value)> >,
+ Do_not_use,K1_Obj>::type argument_type;
+ //typedef typename KOC::argument_type K1_Obj;
+ //typedef typename KOC::result_type K2_Obj;
+ public:
+ using Base::operator(); // don't use directly, just make it accessible to the next level
+ K2_Obj helper(K1_Obj const& o,CGAL_BOOSTD true_type)const{
+ return KOC()(this->myself().kernel(),this->myself().kernel2(),this->myself(),o);
+ }
+ K2_Obj helper(K1_Obj const& o,CGAL_BOOSTD false_type)const{
+ return K1_Conv(this->myself().kernel())(this->myself().kernel2(),this->myself(),o);
+ }
+ K2_Obj operator()(argument_type const& o)const{
+ return helper(o,no_converter());
+ }
+ template<class X,int=0> struct result:Base::template result<X>{};
+ template<int i> struct result<Final_(argument_type),i> {typedef K2_Obj type;};
+};
+
+template<class Final_, class K1, class K2>
+class KernelD_converter_<Final_,K1,K2,typeset<> > {
+ public:
+ struct Do_not_use2{};
+ void operator()(Do_not_use2)const{}
+ template<class T> struct result;
+ Final_& myself(){return *static_cast<Final_*>(this);}
+ Final_ const& myself()const{return *static_cast<Final_ const*>(this);}
+};
+
+
+// TODO: use the intersection of Kn::Object_list.
+template<class K1, class K2, class List_=
+typename typeset_intersection<typename K1::Object_list, typename K2::Object_list>::type
+//typeset<Point_tag>::add<Vector_tag>::type/*::add<Segment_tag>::type*/
+> class KernelD_converter
+ : public Store_kernel<K1>, public Store_kernel2<K2>,
+ public KernelD_converter_<KernelD_converter<K1,K2,List_>,K1,K2,List_>
+{
+ typedef KernelD_converter Self;
+ typedef Self Final_;
+ typedef KernelD_converter_<Self,K1,K2,List_> Base;
+ typedef typename Get_type<K1, FT_tag>::type FT1;
+ typedef typename Get_type<K2, FT_tag>::type FT2;
+ typedef NT_converter<FT1, FT2> NTc;
+ NTc c; // TODO: compressed storage as this is likely empty and the converter gets passed around (and stored in iterators)
+
+ public:
+ KernelD_converter(){}
+ KernelD_converter(K1 const&a,K2 const&b):Store_kernel<K1>(a),Store_kernel2<K2>(b){}
+
+ // For boost::result_of, used in transforming_iterator
+ template<class T,int i=is_iterator<T>::value?42:0> struct result:Base::template result<T>{};
+ template<class T> struct result<Final_(T),42> {
+ typedef transforming_iterator<Final_,T> type;
+ };
+ template<int i> struct result<Final_(K1),i>{typedef K2 type;};
+ template<int i> struct result<Final_(int),i>{typedef int type;};
+ // Ideally the next 2 would come with Point_tag and Vector_tag, but that's hard...
+ template<int i> struct result<Final_(Origin),i>{typedef Origin type;};
+ template<int i> struct result<Final_(Null_vector),i>{typedef Null_vector type;};
+ template<int i> struct result<Final_(Object),i>{typedef Object type;};
+ template<int i> struct result<Final_(FT1),i>{typedef FT2 type;};
+
+ using Base::operator();
+ typename Store_kernel2<K2>::reference2_type operator()(K1 const&)const{return this->kernel2();}
+ int operator()(int i)const{return i;}
+ Origin operator()(Origin const&o)const{return o;}
+ Null_vector operator()(Null_vector const&v)const{return v;}
+ FT2 operator()(FT1 const&x)const{return c(x);}
+ //RT2 operator()(typename First_if_different<RT1,FT1>::Type const&x)const{return cr(x);}
+
+ typename Get_type<K2, Flat_orientation_tag>::type const&
+ operator()(typename Get_type<K1, Flat_orientation_tag>::type const&o)const
+ { return o; } // Both kernels should have the same, returning a reference should warn if not.
+
+ template<class It>
+ transforming_iterator<Final_,typename boost::enable_if<is_iterator<It>,It>::type>
+ operator()(It const& it) const {
+ return make_transforming_iterator(it,*this);
+ }
+
+ template<class T>
+ //TODO: use decltype in C++11 instead of result
+ std::vector<typename result<Final_(T)>::type>
+ operator()(const std::vector<T>& v) const {
+ return std::vector<typename result<Final_(T)>::type>(operator()(v.begin()),operator()(v.begin()));
+ }
+
+ //TODO: convert std::list and other containers?
+
+ Object
+ operator()(const Object &obj) const
+ {
+ typedef typename internal::Map_taglist_to_typelist<K1,List_>::type Possibilities;
+ //TODO: add Empty, vector<Point>, etc to the list.
+ return Object_converter<Possibilities>()(obj,*this);
+ }
+
+ //TODO: convert boost::variant
+
+};
+
+} //namespace CGAL
+
+#endif // CGAL_KERNEL_D_CARTESIAN_CONVERTER_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Kernel_2_interface.h b/include/gudhi_patches/CGAL/NewKernel_d/Kernel_2_interface.h
new file mode 100644
index 00000000..fa30dff0
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Kernel_2_interface.h
@@ -0,0 +1,104 @@
+// 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_KD_KERNEL_2_INTERFACE_H
+#define CGAL_KD_KERNEL_2_INTERFACE_H
+
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/transforming_iterator.h>
+#include <CGAL/NewKernel_d/utils.h>
+#include <CGAL/tuple.h>
+
+
+namespace CGAL {
+template <class Base_> struct Kernel_2_interface : public Base_ {
+ typedef Base_ Base;
+ typedef Kernel_2_interface<Base> Kernel;
+ typedef typename Get_type<Base, RT_tag>::type RT;
+ typedef typename Get_type<Base, FT_tag>::type FT;
+ typedef typename Get_type<Base, Bool_tag>::type Boolean;
+ typedef typename Get_type<Base, Sign_tag>::type Sign;
+ typedef typename Get_type<Base, Comparison_result_tag>::type Comparison_result;
+ typedef typename Get_type<Base, Orientation_tag>::type Orientation;
+ typedef typename Get_type<Base, Oriented_side_tag>::type Oriented_side;
+ typedef typename Get_type<Base, Bounded_side_tag>::type Bounded_side;
+ typedef typename Get_type<Base, Angle_tag>::type Angle;
+ typedef typename Get_type<Base, Point_tag>::type Point_2;
+ typedef typename Get_type<Base, Vector_tag>::type Vector_2;
+ typedef typename Get_type<Base, Segment_tag>::type Segment_2;
+ typedef cpp0x::tuple<Point_2,Point_2,Point_2> Triangle_2; // triangulation insists...
+ template <class T,int i> struct Help_2p_i {
+ typedef typename Get_functor<Base, T>::type LT;
+ typedef typename LT::result_type result_type;
+ LT lt;
+ Help_2p_i(Kernel const&k):lt(k){}
+ result_type operator()(Point_2 const&a, Point_2 const&b) {
+ return lt(a,b,i);
+ }
+ };
+ typedef Help_2p_i<Less_point_cartesian_coordinate_tag,0> Less_x_2;
+ typedef Help_2p_i<Less_point_cartesian_coordinate_tag,1> Less_y_2;
+ typedef Help_2p_i<Compare_point_cartesian_coordinate_tag,0> Compare_x_2;
+ typedef Help_2p_i<Compare_point_cartesian_coordinate_tag,1> Compare_y_2;
+ struct Compare_distance_2 {
+ typedef typename Get_functor<Base, Compare_distance_tag>::type CD;
+ typedef typename CD::result_type result_type;
+ CD cd;
+ Compare_distance_2(Kernel const&k):cd(k){}
+ result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c) {
+ return cd(a,b,c);
+ }
+ result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c, Point_2 const&d) {
+ return cd(a,b,c,d);
+ }
+ };
+ struct Orientation_2 {
+ typedef typename Get_functor<Base, Orientation_of_points_tag>::type O;
+ typedef typename O::result_type result_type;
+ O o;
+ Orientation_2(Kernel const&k):o(k){}
+ result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c) {
+ //return o(a,b,c);
+ Point_2 const* t[3]={&a,&b,&c};
+ return o(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+3));
+
+ }
+ };
+ struct Side_of_oriented_circle_2 {
+ typedef typename Get_functor<Base, Side_of_oriented_sphere_tag>::type SOS;
+ typedef typename SOS::result_type result_type;
+ SOS sos;
+ Side_of_oriented_circle_2(Kernel const&k):sos(k){}
+ result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c, Point_2 const&d) {
+ //return sos(a,b,c,d);
+ Point_2 const* t[4]={&a,&b,&c,&d};
+ return sos(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+4));
+ }
+ };
+ Less_x_2 less_x_2_object()const{ return Less_x_2(*this); }
+ Less_y_2 less_y_2_object()const{ return Less_y_2(*this); }
+ Compare_x_2 compare_x_2_object()const{ return Compare_x_2(*this); }
+ Compare_y_2 compare_y_2_object()const{ return Compare_y_2(*this); }
+ Compare_distance_2 compare_distance_2_object()const{ return Compare_distance_2(*this); }
+ Orientation_2 orientation_2_object()const{ return Orientation_2(*this); }
+ Side_of_oriented_circle_2 side_of_oriented_circle_2_object()const{ return Side_of_oriented_circle_2(*this); }
+};
+}
+
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Kernel_3_interface.h b/include/gudhi_patches/CGAL/NewKernel_d/Kernel_3_interface.h
new file mode 100644
index 00000000..96076aa8
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Kernel_3_interface.h
@@ -0,0 +1,102 @@
+// 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_KD_KERNEL_3_INTERFACE_H
+#define CGAL_KD_KERNEL_3_INTERFACE_H
+
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/transforming_iterator.h>
+#include <CGAL/NewKernel_d/utils.h>
+#include <CGAL/tuple.h>
+
+
+namespace CGAL {
+template <class Base_> struct Kernel_3_interface : public Base_ {
+ typedef Base_ Base;
+ typedef Kernel_3_interface<Base> Kernel;
+ typedef typename Get_type<Base, RT_tag>::type RT;
+ typedef typename Get_type<Base, FT_tag>::type FT;
+ typedef typename Get_type<Base, Bool_tag>::type Boolean;
+ typedef typename Get_type<Base, Sign_tag>::type Sign;
+ typedef typename Get_type<Base, Comparison_result_tag>::type Comparison_result;
+ typedef typename Get_type<Base, Orientation_tag>::type Orientation;
+ typedef typename Get_type<Base, Oriented_side_tag>::type Oriented_side;
+ typedef typename Get_type<Base, Bounded_side_tag>::type Bounded_side;
+ typedef typename Get_type<Base, Angle_tag>::type Angle;
+ typedef typename Get_type<Base, Point_tag>::type Point_3;
+ typedef typename Get_type<Base, Vector_tag>::type Vector_3;
+ typedef typename Get_type<Base, Segment_tag>::type Segment_3;
+ typedef cpp0x::tuple<Point_3,Point_3,Point_3> Triangle_3; // placeholder
+ typedef cpp0x::tuple<Point_3,Point_3,Point_3,Point_3> Tetrahedron_3; // placeholder
+ struct Compare_xyz_3 {
+ typedef typename Get_functor<Base, Compare_lexicographically_tag>::type CL;
+ typedef typename CL::result_type result_type;
+ CL cl;
+ Compare_xyz_3(Kernel const&k):cl(k){}
+ result_type operator()(Point_3 const&a, Point_3 const&b) {
+ return cl(a,b);
+ }
+ };
+ struct Compare_distance_3 {
+ typedef typename Get_functor<Base, Compare_distance_tag>::type CD;
+ typedef typename CD::result_type result_type;
+ CD cd;
+ Compare_distance_3(Kernel const&k):cd(k){}
+ result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c) {
+ return cd(a,b,c);
+ }
+ result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d) {
+ return cd(a,b,c,d);
+ }
+ };
+ struct Orientation_3 {
+ typedef typename Get_functor<Base, Orientation_of_points_tag>::type O;
+ typedef typename O::result_type result_type;
+ O o;
+ Orientation_3(Kernel const&k):o(k){}
+ result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d) {
+ //return o(a,b,c,d);
+ Point_3 const* t[4]={&a,&b,&c,&d};
+ return o(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+4));
+
+ }
+ };
+ struct Side_of_oriented_sphere_3 {
+ typedef typename Get_functor<Base, Side_of_oriented_sphere_tag>::type SOS;
+ typedef typename SOS::result_type result_type;
+ SOS sos;
+ Side_of_oriented_sphere_3(Kernel const&k):sos(k){}
+ result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d, Point_3 const&e) {
+ //return sos(a,b,c,d);
+ Point_3 const* t[5]={&a,&b,&c,&d,&e};
+ return sos(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+5));
+ }
+ };
+
+ // I don't have the Coplanar predicates (yet)
+
+
+ Compare_xyz_3 compare_xyz_3_object()const{ return Compare_xyz_3(*this); }
+ Compare_distance_3 compare_distance_3_object()const{ return Compare_distance_3(*this); }
+ Orientation_3 orientation_3_object()const{ return Orientation_3(*this); }
+ Side_of_oriented_sphere_3 side_of_oriented_sphere_3_object()const{ return Side_of_oriented_sphere_3(*this); }
+};
+}
+
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Kernel_d_interface.h b/include/gudhi_patches/CGAL/NewKernel_d/Kernel_d_interface.h
new file mode 100644
index 00000000..dd888005
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Kernel_d_interface.h
@@ -0,0 +1,298 @@
+// 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_KD_KERNEL_D_INTERFACE_H
+#define CGAL_KD_KERNEL_D_INTERFACE_H
+
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/transforming_iterator.h>
+#include <CGAL/NewKernel_d/utils.h>
+#include <CGAL/tuple.h>
+
+
+namespace CGAL {
+template <class Base_> struct Kernel_d_interface : public Base_ {
+ CGAL_CONSTEXPR Kernel_d_interface(){}
+ CGAL_CONSTEXPR Kernel_d_interface(int d):Base_(d){}
+
+ typedef Base_ Base;
+ typedef Kernel_d_interface<Base> Kernel;
+ typedef Base_ R_; // for the macros
+ typedef typename Get_type<Base, RT_tag>::type RT;
+ typedef typename Get_type<Base, FT_tag>::type FT;
+ typedef typename Get_type<Base, Bool_tag>::type Boolean;
+ typedef typename Get_type<Base, Sign_tag>::type Sign;
+ typedef typename Get_type<Base, Comparison_result_tag>::type Comparison_result;
+ typedef typename Get_type<Base, Orientation_tag>::type Orientation;
+ typedef typename Get_type<Base, Oriented_side_tag>::type Oriented_side;
+ typedef typename Get_type<Base, Bounded_side_tag>::type Bounded_side;
+ typedef typename Get_type<Base, Angle_tag>::type Angle;
+ typedef typename Get_type<Base, Flat_orientation_tag>::type Flat_orientation_d;
+ typedef typename Get_type<Base, Point_tag>::type Point_d;
+ typedef typename Get_type<Base, Vector_tag>::type Vector_d;
+ typedef typename Get_type<Base, Segment_tag>::type Segment_d;
+ typedef typename Get_type<Base, Sphere_tag>::type Sphere_d;
+ typedef typename Get_type<Base, Hyperplane_tag>::type Hyperplane_d;
+ typedef Vector_d Direction_d;
+ typedef typename Get_type<Base, Line_tag>::type Line_d;
+ typedef typename Get_type<Base, Ray_tag>::type Ray_d;
+ typedef typename Get_type<Base, Iso_box_tag>::type Iso_box_d;
+ typedef typename Get_type<Base, Aff_transformation_tag>::type Aff_transformation_d;
+ typedef typename Get_type<Base, Weighted_point_tag>::type Weighted_point_d;
+ typedef typename Get_functor<Base, Compute_point_cartesian_coordinate_tag>::type Compute_coordinate_d;
+ typedef typename Get_functor<Base, Compare_lexicographically_tag>::type Compare_lexicographically_d;
+ typedef typename Get_functor<Base, Equal_points_tag>::type Equal_d;
+ typedef typename Get_functor<Base, Less_lexicographically_tag>::type Less_lexicographically_d;
+ typedef typename Get_functor<Base, Less_or_equal_lexicographically_tag>::type Less_or_equal_lexicographically_d;
+ // FIXME: and vectors?
+ typedef typename Get_functor<Base, Orientation_of_points_tag>::type Orientation_d;
+ typedef typename Get_functor<Base, Less_point_cartesian_coordinate_tag>::type Less_coordinate_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, Power_side_of_power_sphere_tag>::type Power_side_of_power_sphere_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, 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_side_of_oriented_sphere_tag>::type In_flat_side_of_oriented_sphere_d;
+ typedef typename Get_functor<Base, In_flat_power_side_of_power_sphere_tag>::type In_flat_power_side_of_power_sphere_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, Translated_point_tag>::type Translated_point_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_points_tag>::type Difference_of_points_d;
+ //typedef typename Get_functor<Base, Construct_ttag<Point_tag> >::type Construct_point_d;
+ struct Construct_point_d : private Store_kernel<Kernel> {
+ typedef Kernel R_; // for the macro
+ CGAL_FUNCTOR_INIT_STORE(Construct_point_d)
+ typedef typename Get_functor<Base, Construct_ttag<Point_tag> >::type CP;
+ typedef Point_d result_type;
+ Point_d operator()(Weighted_point_d const&wp)const{
+ return typename Get_functor<Base, Point_drop_weight_tag>::type(this->kernel())(wp);
+ }
+#ifdef CGAL_CXX11
+ Point_d operator()(Weighted_point_d &wp)const{
+ return typename Get_functor<Base, Point_drop_weight_tag>::type(this->kernel())(wp);
+ }
+ Point_d operator()(Weighted_point_d &&wp)const{
+ return typename Get_functor<Base, Point_drop_weight_tag>::type(this->kernel())(std::move(wp));
+ }
+ Point_d operator()(Weighted_point_d const&&wp)const{
+ return typename Get_functor<Base, Point_drop_weight_tag>::type(this->kernel())(std::move(wp));
+ }
+ template<class...T>
+# if __cplusplus >= 201402L
+ decltype(auto)
+# else
+ Point_d
+# endif
+ operator()(T&&...t)const{
+ return CP(this->kernel())(std::forward<T>(t)...);
+ //return CP(this->kernel())(t...);
+ }
+#else
+# define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Point_d operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t))const{ \
+ return CP(this->kernel())(BOOST_PP_ENUM_PARAMS(N,t)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+# undef CGAL_CODE
+ Point_d operator()()const{ \
+ return CP(this->kernel())(); \
+ }
+#endif
+ };
+ typedef typename Get_functor<Base, Construct_ttag<Vector_tag> >::type Construct_vector_d;
+ typedef typename Get_functor<Base, Construct_ttag<Segment_tag> >::type Construct_segment_d;
+ typedef typename Get_functor<Base, Construct_ttag<Sphere_tag> >::type Construct_sphere_d;
+ typedef typename Get_functor<Base, Construct_ttag<Hyperplane_tag> >::type Construct_hyperplane_d;
+ typedef Construct_vector_d Construct_direction_d;
+ typedef typename Get_functor<Base, Construct_ttag<Line_tag> >::type Construct_line_d;
+ typedef typename Get_functor<Base, Construct_ttag<Ray_tag> >::type Construct_ray_d;
+ typedef typename Get_functor<Base, Construct_ttag<Iso_box_tag> >::type Construct_iso_box_d;
+ typedef typename Get_functor<Base, Construct_ttag<Aff_transformation_tag> >::type Construct_aff_transformation_d;
+ typedef typename Get_functor<Base, Construct_ttag<Weighted_point_tag> >::type Construct_weighted_point_d;
+ typedef typename Get_functor<Base, Midpoint_tag>::type Midpoint_d;
+ struct Component_accessor_d : private Store_kernel<Kernel> {
+ typedef Kernel R_; // for the macro
+ CGAL_FUNCTOR_INIT_STORE(Component_accessor_d)
+ int dimension(Point_d const&p){
+ return this->kernel().point_dimension_d_object()(p);
+ }
+ FT cartesian(Point_d const&p, int i){
+ return this->kernel().compute_coordinate_d_object()(p,i);
+ }
+ RT homogeneous(Point_d const&p, int i){
+ if (i == dimension(p))
+ return 1;
+ return cartesian(p, i);
+ }
+ };
+ struct Construct_cartesian_const_iterator_d : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Construct_cartesian_const_iterator_d)
+ typedef typename Get_functor<Base, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CPI;
+ typedef typename Get_functor<Base, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CVI;
+ // FIXME: The following sometimes breaks compilation. The typedef below forces instantiation of this, which forces Point_d, which itself (in the wrapper) needs the derived kernel to tell it what the base kernel is, and that's a cycle. The exact circumstances are not clear, g++ and clang++ are ok in both C++03 and C++11, it is only clang in C++11 without CGAL_CXX11 that breaks. For now, rely on result_type.
+ //typedef typename CGAL::decay<typename boost::result_of<CPI(Point_d,CGAL::Begin_tag)>::type>::type result_type;
+ typedef typename CGAL::decay<typename CPI::result_type>::type result_type;
+ // Kernel_d requires a common iterator type for points and vectors
+ // TODO: provide this mixed functor in preKernel?
+ //CGAL_static_assertion((boost::is_same<typename CGAL::decay<typename boost::result_of<CVI(Vector_d,CGAL::Begin_tag)>::type>::type, result_type>::value));
+ CGAL_static_assertion((boost::is_same<typename CGAL::decay<typename CVI::result_type>::type, result_type>::value));
+ template <class Tag_>
+ result_type operator()(Point_d const&p, Tag_ t)const{
+ return CPI(this->kernel())(p,t);
+ }
+ template <class Tag_>
+ result_type operator()(typename First_if_different<Vector_d,Point_d>::Type const&v, Tag_ t)const{
+ return CVI(this->kernel())(v,t);
+ }
+
+ template <class Obj>
+ result_type operator()(Obj const&o)const{
+ return operator()(o, Begin_tag());
+ }
+ result_type operator()(Point_d const&p, int)const{
+ return operator()(p, End_tag());
+ }
+ result_type operator()(typename First_if_different<Vector_d,Point_d>::Type const&v, int)const{
+ return operator()(v, End_tag());
+ }
+ };
+ struct Compute_squared_radius_d : private Store_kernel<Kernel> {
+ typedef Kernel R_; // for the macro
+ CGAL_FUNCTOR_INIT_STORE(Compute_squared_radius_d)
+ typedef FT result_type;
+ template<class S> FT operator()(CGAL_FORWARDABLE(S) s)const{
+ return typename Get_functor<Base, Squared_radius_tag>::type(this->kernel())(CGAL_FORWARD(S,s));
+ }
+ template<class I> FT operator()(I b, I e)const{
+ return typename Get_functor<Base, Squared_circumradius_tag>::type(this->kernel())(b,e);
+ }
+ };
+ typedef typename Construct_cartesian_const_iterator_d::result_type Cartesian_const_iterator_d;
+ typedef typename Get_functor<Base, Squared_distance_tag>::type Squared_distance_d;
+ typedef typename Get_functor<Base, Squared_length_tag>::type Squared_length_d;
+ typedef typename Get_functor<Base, Scalar_product_tag>::type Scalar_product_d;
+ typedef typename Get_functor<Base, Affine_rank_tag>::type Affine_rank_d;
+ typedef typename Get_functor<Base, Affinely_independent_tag>::type Affinely_independent_d;
+ typedef typename Get_functor<Base, Contained_in_linear_hull_tag>::type Contained_in_linear_hull_d;
+ typedef typename Get_functor<Base, Contained_in_simplex_tag>::type Contained_in_simplex_d;
+ typedef typename Get_functor<Base, Has_on_positive_side_tag>::type Has_on_positive_side_d;
+ typedef typename Get_functor<Base, Linear_rank_tag>::type Linear_rank_d;
+ typedef typename Get_functor<Base, Linearly_independent_tag>::type Linearly_independent_d;
+ typedef typename Get_functor<Base, Oriented_side_tag>::type Oriented_side_d;
+ typedef typename Get_functor<Base, Side_of_bounded_circumsphere_tag>::type Side_of_bounded_sphere_d;
+
+ typedef typename Get_functor<Base, Center_of_sphere_tag>::type Center_of_sphere_d;
+ typedef Center_of_sphere_d Construct_center_d; // RangeSearchTraits
+ typedef typename Get_functor<Base, Construct_circumcenter_tag>::type Construct_circumcenter_d;
+ typedef typename Get_functor<Base, Value_at_tag>::type Value_at_d;
+ typedef typename Get_functor<Base, Point_of_sphere_tag>::type Point_of_sphere_d;
+ typedef typename Get_functor<Base, Orthogonal_vector_tag>::type Orthogonal_vector_d;
+ typedef typename Get_functor<Base, Linear_base_tag>::type Linear_base_d;
+ typedef typename Get_functor<Base, Construct_min_vertex_tag>::type Construct_min_vertex_d;
+ typedef typename Get_functor<Base, Construct_max_vertex_tag>::type Construct_max_vertex_d;
+
+ typedef typename Get_functor<Base, Point_weight_tag>::type Compute_weight_d;
+ typedef typename Get_functor<Base, Point_drop_weight_tag>::type Point_drop_weight_d;
+
+ //TODO:
+ //typedef ??? Intersect_d;
+
+
+ Compute_coordinate_d compute_coordinate_d_object()const{ return Compute_coordinate_d(*this); }
+ Has_on_positive_side_d has_on_positive_side_d_object()const{ return Has_on_positive_side_d(*this); }
+ Compare_lexicographically_d compare_lexicographically_d_object()const{ return Compare_lexicographically_d(*this); }
+ Equal_d equal_d_object()const{ return Equal_d(*this); }
+ Less_lexicographically_d less_lexicographically_d_object()const{ return Less_lexicographically_d(*this); }
+ Less_or_equal_lexicographically_d less_or_equal_lexicographically_d_object()const{ return Less_or_equal_lexicographically_d(*this); }
+ Less_coordinate_d less_coordinate_d_object()const{ return Less_coordinate_d(*this); }
+ Orientation_d orientation_d_object()const{ return Orientation_d(*this); }
+ Oriented_side_d oriented_side_d_object()const{ return Oriented_side_d(*this); }
+ Point_dimension_d point_dimension_d_object()const{ return Point_dimension_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); }
+ Power_side_of_power_sphere_d power_side_of_power_sphere_d_object()const{ return Power_side_of_power_sphere_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); }
+ 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_simplex_d contained_in_simplex_d_object()const{ return Contained_in_simplex_d(*this); }
+ Construct_flat_orientation_d construct_flat_orientation_d_object()const{ return Construct_flat_orientation_d(*this); }
+ In_flat_orientation_d in_flat_orientation_d_object()const{ return In_flat_orientation_d(*this); }
+ In_flat_side_of_oriented_sphere_d in_flat_side_of_oriented_sphere_d_object()const{ return In_flat_side_of_oriented_sphere_d(*this); }
+ In_flat_power_side_of_power_sphere_d in_flat_power_side_of_power_sphere_d_object()const{ return In_flat_power_side_of_power_sphere_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); }
+ 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); }
+ 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); }
+ Affine_rank_d affine_rank_d_object()const{ return Affine_rank_d(*this); }
+ Affinely_independent_d affinely_independent_d_object()const{ return Affinely_independent_d(*this); }
+ Linear_base_d linear_base_d_object()const{ return Linear_base_d(*this); }
+ Linear_rank_d linear_rank_d_object()const{ return Linear_rank_d(*this); }
+ Linearly_independent_d linearly_independent_d_object()const{ return Linearly_independent_d(*this); }
+ Midpoint_d midpoint_d_object()const{ return Midpoint_d(*this); }
+ Value_at_d value_at_d_object()const{ return Value_at_d(*this); }
+ /// Intersect_d intersect_d_object()const{ return Intersect_d(*this); }
+ Component_accessor_d component_accessor_d_object()const{ return Component_accessor_d(*this); }
+ Orthogonal_vector_d orthogonal_vector_d_object()const{ return Orthogonal_vector_d(*this); }
+ Construct_cartesian_const_iterator_d construct_cartesian_const_iterator_d_object()const{ return Construct_cartesian_const_iterator_d(*this); }
+ Construct_point_d construct_point_d_object()const{ return Construct_point_d(*this); }
+ Construct_vector_d construct_vector_d_object()const{ return Construct_vector_d(*this); }
+ Construct_segment_d construct_segment_d_object()const{ return Construct_segment_d(*this); }
+ Construct_sphere_d construct_sphere_d_object()const{ return Construct_sphere_d(*this); }
+ Construct_hyperplane_d construct_hyperplane_d_object()const{ return Construct_hyperplane_d(*this); }
+ Compute_squared_radius_d compute_squared_radius_d_object()const{ return Compute_squared_radius_d(*this); }
+ Squared_distance_d squared_distance_d_object()const{ return Squared_distance_d(*this); }
+ Squared_length_d squared_length_d_object()const{ return Squared_length_d(*this); }
+ Scalar_product_d scalar_product_d_object()const{ return Scalar_product_d(*this); }
+ Center_of_sphere_d center_of_sphere_d_object()const{ return Center_of_sphere_d(*this); }
+ Construct_circumcenter_d construct_circumcenter_d_object()const{ return Construct_circumcenter_d(*this); }
+ Construct_direction_d construct_direction_d_object()const{ return Construct_direction_d(*this); }
+ Construct_line_d construct_line_d_object()const{ return Construct_line_d(*this); }
+ Construct_ray_d construct_ray_d_object()const{ return Construct_ray_d(*this); }
+ Construct_iso_box_d construct_iso_box_d_object()const{ return Construct_iso_box_d(*this); }
+ Construct_aff_transformation_d construct_aff_transformation_d_object()const{ return Construct_aff_transformation_d(*this); }
+ Construct_min_vertex_d construct_min_vertex_d_object()const{ return Construct_min_vertex_d(*this); }
+ Construct_max_vertex_d construct_max_vertex_d_object()const{ return Construct_max_vertex_d(*this); }
+ Construct_weighted_point_d construct_weighted_point_d_object()const{ return Construct_weighted_point_d(*this); }
+
+ Compute_weight_d compute_weight_d_object()const{ return Compute_weight_d(*this); }
+ Point_drop_weight_d point_drop_weight_d_object()const{ return Point_drop_weight_d(*this); }
+
+ // Dummies for those required functors missing a concept.
+ typedef Null_functor Position_on_line_d;
+ Position_on_line_d position_on_line_d_object()const{return Null_functor();}
+ typedef Null_functor Barycentric_coordinates_d;
+ Barycentric_coordinates_d barycentric_coordinates_d_object()const{return Null_functor();}
+
+ /* Not provided because they don't make sense here:
+ Lift_to_paraboloid_d
+ Project_along_d_axis_d
+ */
+};
+}
+
+#endif // CGAL_KD_KERNEL_D_INTERFACE_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Kernel_object_converter.h b/include/gudhi_patches/CGAL/NewKernel_d/Kernel_object_converter.h
new file mode 100644
index 00000000..99918ed2
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Kernel_object_converter.h
@@ -0,0 +1,134 @@
+// 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_KD_KO_CONVERTER_H
+#define CGAL_KD_KO_CONVERTER_H
+#include <CGAL/NewKernel_d/utils.h>
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Kernel/mpl.h> // First_if_different
+#include <CGAL/Dimension.h>
+namespace CGAL {
+template <class Tag_, class K1, class K2> struct KO_converter;
+//TODO: It would probably be better if this was a Misc Functor in K1.
+// This way K1 could chose how it wants to present its points (sparse
+// iterator?) and derived classes would inherit it.
+
+namespace internal {
+template <class D /*=Dynamic_dimension_tag*/, class K1, class K2>
+struct Point_converter_help {
+ typedef typename Get_type<K1, Point_tag>::type argument_type;
+ typedef typename Get_type<K2, Point_tag>::type result_type;
+ template <class C>
+ result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const {
+ typename Get_functor<K1, Construct_ttag<Point_cartesian_const_iterator_tag> >::type i(k1);
+ typename Get_functor<K2, Construct_ttag<Point_tag> >::type cp(k2);
+ return cp(conv(i(p,Begin_tag())),conv(i(p,End_tag())));
+ }
+};
+#ifdef CGAL_CXX11
+// This doesn't seem so useful, the compiler should be able to handle
+// the iterators just as efficiently.
+template <int d, class K1, class K2>
+struct Point_converter_help<Dimension_tag<d>,K1,K2> {
+ typedef typename Get_type<K1, Point_tag>::type argument_type;
+ typedef typename Get_type<K2, Point_tag>::type result_type;
+ template <class C,int...I>
+ result_type help(Indices<I...>, K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const {
+ typename Get_functor<K1, Compute_point_cartesian_coordinate_tag>::type cc(k1);
+ typename Get_functor<K2, Construct_ttag<Point_tag> >::type cp(k2);
+ return cp(conv(cc(p,I))...);
+ }
+ template <class C>
+ result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const {
+ return help(typename N_increasing_indices<d>::type(),k1,k2,conv,p);
+ }
+};
+#endif
+}
+template <class K1, class K2> struct KO_converter<Point_tag,K1,K2>
+: internal::Point_converter_help<typename K1::Default_ambient_dimension,K1,K2>
+{};
+
+template <class K1, class K2> struct KO_converter<Vector_tag,K1,K2>{
+ typedef typename Get_type<K1, Vector_tag>::type K1_Vector;
+
+ // Disabling is now done in KernelD_converter
+ // // can't use vector without at least a placeholder point because of this
+ // typedef typename K1:: Point K1_Point;
+ // typedef typename First_if_different<K1_Vector,K1_Point>::Type argument_type;
+
+ typedef K1_Vector argument_type;
+ typedef typename Get_type<K2, Vector_tag>::type result_type;
+ template <class C>
+ result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& v) const {
+ typename Get_functor<K1, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type i(k1);
+ typename Get_functor<K2, Construct_ttag<Vector_tag> >::type cp(k2);
+ return cp(conv(i(v,Begin_tag())),conv(i(v,End_tag())));
+ }
+};
+
+template <class K1, class K2> struct KO_converter<Segment_tag,K1,K2>{
+ typedef typename Get_type<K1, Segment_tag>::type argument_type;
+ typedef typename Get_type<K2, Segment_tag>::type result_type;
+ template <class C>
+ result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& s) const {
+ typename Get_functor<K1, Segment_extremity_tag>::type f(k1);
+ typename Get_functor<K2, Construct_ttag<Segment_tag> >::type cs(k2);
+ return cs(conv(f(s,0)),conv(f(s,1)));
+ }
+};
+
+template <class K1, class K2> struct KO_converter<Hyperplane_tag,K1,K2>{
+ typedef typename Get_type<K1, Hyperplane_tag>::type argument_type;
+ typedef typename Get_type<K2, Hyperplane_tag>::type result_type;
+ template <class C>
+ result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& h) const {
+ typename Get_functor<K1, Orthogonal_vector_tag>::type ov(k1);
+ typename Get_functor<K1, Hyperplane_translation_tag>::type ht(k1);
+ typename Get_functor<K2, Construct_ttag<Hyperplane_tag> >::type ch(k2);
+ return ch(conv(ov(h)),conv(ht(h)));
+ }
+};
+
+template <class K1, class K2> struct KO_converter<Sphere_tag,K1,K2>{
+ typedef typename Get_type<K1, Sphere_tag>::type argument_type;
+ typedef typename Get_type<K2, Sphere_tag>::type result_type;
+ template <class C>
+ result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& s) const {
+ typename Get_functor<K1, Center_of_sphere_tag>::type cos(k1);
+ typename Get_functor<K1, Squared_radius_tag>::type sr(k1);
+ typename Get_functor<K2, Construct_ttag<Sphere_tag> >::type cs(k2);
+ return cs(conv(cos(s)),conv(sr(s)));
+ }
+};
+
+template <class K1, class K2> struct KO_converter<Weighted_point_tag,K1,K2>{
+ typedef typename Get_type<K1, Weighted_point_tag>::type argument_type;
+ typedef typename Get_type<K2, Weighted_point_tag>::type result_type;
+ template <class C>
+ result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& s) const {
+ typename Get_functor<K1, Point_drop_weight_tag>::type pdw(k1);
+ typename Get_functor<K1, Point_weight_tag>::type pw(k1);
+ typename Get_functor<K2, Construct_ttag<Weighted_point_tag> >::type cwp(k2);
+ return cwp(conv(pdw(s)),conv(pw(s)));
+ }
+};
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/LA_eigen/LA.h b/include/gudhi_patches/CGAL/NewKernel_d/LA_eigen/LA.h
new file mode 100644
index 00000000..ddbdc37b
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/LA_eigen/LA.h
@@ -0,0 +1,175 @@
+// 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_LA_EIGEN_H
+#define CGAL_LA_EIGEN_H
+#include <CGAL/config.h>
+#ifndef CGAL_EIGEN3_ENABLED
+#error Requires Eigen
+#endif
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <CGAL/Dimension.h>
+#include <Eigen/Dense>
+#include <CGAL/NewKernel_d/LA_eigen/constructors.h>
+#include <CGAL/iterator_from_indices.h>
+
+namespace CGAL {
+
+//FIXME: where could we use Matrix_base instead of Matrix?
+// Dim_ real dimension
+// Max_dim_ upper bound on the dimension
+template<class NT_,class Dim_,class Max_dim_=Dim_> struct LA_eigen {
+ typedef NT_ NT;
+ typedef Dim_ Dimension;
+ typedef Max_dim_ Max_dimension;
+ enum { dimension = Eigen_dimension<Dimension>::value };
+ enum { max_dimension = Eigen_dimension<Max_dimension>::value };
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef LA_eigen< NT, D2, D3 > Other;
+ };
+ template<class,class=void> struct Property : boost::false_type {};
+ template<class D> struct Property<Has_vector_plus_minus_tag,D> : boost::true_type {};
+ template<class D> struct Property<Has_vector_scalar_ops_tag,D> : boost::true_type {};
+ template<class D> struct Property<Has_dot_product_tag,D> : boost::true_type {};
+
+ typedef Eigen::Matrix<NT,Eigen_dimension<Dim_>::value,1,Eigen::ColMajor|Eigen::AutoAlign,Eigen_dimension<Max_dim_>::value,1> Vector;
+ typedef Eigen::Matrix<NT,Eigen::Dynamic,1> Dynamic_vector;
+ typedef Construct_eigen<Vector> Construct_vector;
+
+#if (EIGEN_WORLD_VERSION>=3)
+ typedef NT const* Vector_const_iterator;
+#else
+ typedef Iterator_from_indices<const type,const NT
+#ifndef CGAL_CXX11
+ ,NT
+#endif
+ > Vector_const_iterator;
+#endif
+
+ template<class Vec_>static Vector_const_iterator vector_begin(Vec_ const&a){
+#if (EIGEN_WORLD_VERSION>=3)
+ return &a[0];
+#else
+ return Vector_const_iterator(a,0);
+#endif
+ }
+
+ template<class Vec_>static Vector_const_iterator vector_end(Vec_ const&a){
+#if (EIGEN_WORLD_VERSION>=3)
+ // FIXME: Isn't that dangerous if a is an expression and not a concrete vector?
+ return &a[0]+a.size();
+#else
+ return Vector_const_iterator(a,a.size());
+#endif
+ }
+
+ typedef Eigen::Matrix<NT,dimension,dimension,Eigen::ColMajor|Eigen::AutoAlign,max_dimension,max_dimension> Square_matrix;
+ typedef Eigen::Matrix<NT,dimension,Eigen::Dynamic,Eigen::ColMajor|Eigen::AutoAlign,max_dimension,Eigen::Dynamic> Dynamic_matrix;
+ //TODO: don't pass on the values of Max_* for an expensive NT
+ // typedef ... Constructor
+ // typedef ... Accessor
+#if 0
+ private:
+ template <class T> class Canonicalize_vector {
+ typedef typename Dimension_eigen<T::SizeAtCompileTime>::type S1;
+ typedef typename Dimension_eigen<T::MaxSizeAtCompileTime>::type S2;
+ public:
+ typedef typename Vector<S1,S2>::type type;
+ };
+ public:
+#endif
+
+ template<class Vec_>static int size_of_vector(Vec_ const&v){
+ return (int)v.size();
+ }
+
+ template<class Vec_>static NT dot_product(Vec_ const&a,Vec_ const&b){
+ return a.dot(b);
+ }
+
+ template<class Vec_> static int rows(Vec_ const&v) {
+ return (int)v.rows();
+ }
+ template<class Vec_> static int columns(Vec_ const&v) {
+ return (int)v.cols();
+ }
+
+ template<class Mat_> static NT determinant(Mat_ const&m,bool=false){
+ return m.determinant();
+ }
+
+ template<class Mat_> static typename
+ Same_uncertainty_nt<CGAL::Sign, NT>::type
+ sign_of_determinant(Mat_ const&m,bool=false)
+ {
+ return CGAL::sign(m.determinant());
+ }
+
+ template<class Mat_> static int rank(Mat_ const&m){
+ // return m.rank();
+ // This one uses sqrt so cannot be used with Gmpq
+ // TODO: use different algo for different NT?
+ // Eigen::ColPivHouseholderQR<Mat_> decomp(m);
+ Eigen::FullPivLU<Mat_> decomp(m);
+ // decomp.setThreshold(0);
+ return static_cast<int>(decomp.rank());
+ }
+
+ // m*a==b
+ template<class DV, class DM, class V>
+ static void solve(DV&a, DM const&m, V const& b){
+ //a = m.colPivHouseholderQr().solve(b);
+ a = m.fullPivLu().solve(b);
+ }
+ template<class DV, class DM, class V>
+ static bool solve_and_check(DV&a, DM const&m, V const& b){
+ //a = m.colPivHouseholderQr().solve(b);
+ a = m.fullPivLu().solve(b);
+ return b.isApprox(m*a);
+ }
+
+ static Dynamic_matrix basis(Dynamic_matrix const&m){
+ return m.fullPivLu().image(m);
+ }
+
+ template<class Vec1,class Vec2> static Vector homogeneous_add(Vec1 const&a,Vec2 const&b){
+ //TODO: use compile-time size when available
+ int d=a.size();
+ Vector v(d);
+ v << b[d-1]*a.topRows(d-1)+a[d-1]*b.topRows(d-1), a[d-1]*b[d-1];
+ return v;
+ }
+
+ template<class Vec1,class Vec2> static Vector homogeneous_sub(Vec1 const&a,Vec2 const&b){
+ int d=a.size();
+ Vector v(d);
+ v << b[d-1]*a.topRows(d-1)-a[d-1]*b.topRows(d-1), a[d-1]*b[d-1];
+ return v;
+ }
+
+ template<class Vec1,class Vec2> static std::pair<NT,NT> homogeneous_dot_product(Vec1 const&a,Vec2 const&b){
+ int d=a.size();
+ return make_pair(a.topRows(d-1).dot(b.topRows(d-1)), a[d-1]*b[d-1]);
+ }
+
+};
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/LA_eigen/constructors.h b/include/gudhi_patches/CGAL/NewKernel_d/LA_eigen/constructors.h
new file mode 100644
index 00000000..3636996f
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/LA_eigen/constructors.h
@@ -0,0 +1,162 @@
+// 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_LA_EIGEN_CONSTRUCTORS_H
+#define CGAL_LA_EIGEN_CONSTRUCTORS_H
+#include <CGAL/config.h>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4003) // not enough actual parameters for macro 'BOOST_PP_EXPAND_I'
+ // http://lists.boost.org/boost-users/2014/11/83291.php
+#endif
+
+#ifndef CGAL_EIGEN3_ENABLED
+#error Requires Eigen
+#endif
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <CGAL/Dimension.h>
+#include <Eigen/Dense>
+#include <CGAL/iterator_from_indices.h>
+#include <CGAL/NewKernel_d/utils.h>
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+
+namespace CGAL {
+ template <class Vector_> struct Construct_eigen {
+ typedef Vector_ result_type;
+ typedef typename Vector_::Scalar NT;
+
+ private:
+ static void check_dim(int CGAL_assertion_code(d)){
+ CGAL_assertion_code(int m = result_type::MaxSizeAtCompileTime;)
+ CGAL_assertion((m == Eigen::Dynamic) || (d <= m));
+ }
+ public:
+
+ struct Dimension {
+ // Initialize with NaN if possible?
+ result_type operator()(int d) const {
+ check_dim(d);
+ return result_type(d);
+ }
+ };
+
+ struct Iterator {
+ template<typename Iter>
+ result_type operator()(int d,Iter const& f,Iter const& e) const {
+ check_dim(d);
+ CGAL_assertion(d==std::distance(f,e));
+ result_type a(d);
+ // TODO: check the right way to do this
+ std::copy(f,e,&a[0]);
+ return a;
+ }
+ };
+
+#if 0
+ struct Iterator_add_one {
+ template<typename Iter>
+ result_type operator()(int d,Iter const& f,Iter const& e) const {
+ check_dim(d);
+ CGAL_assertion(d==std::distance(f,e)+1);
+ result_type a(d);
+ std::copy(f,e,&a[0]);
+ a[d-1]=1;
+ return a;
+ }
+ };
+#endif
+
+ struct Iterator_and_last {
+ template<typename Iter,typename T>
+ result_type operator()(int d,Iter const& f,Iter const& e,CGAL_FORWARDABLE(T) t) const {
+ check_dim(d);
+ CGAL_assertion(d==std::distance(f,e)+1);
+ result_type a(d);
+ std::copy(f,e,&a[0]);
+ a[d-1]=CGAL_FORWARD(T,t);
+ return a;
+ }
+ };
+
+#ifdef CGAL_CXX11
+ struct Initializer_list {
+ // Fix T==NT?
+ template<class T>
+ result_type operator()(std::initializer_list<T> l) const {
+ return Iterator()(l.size(),l.begin(),l.end());
+ }
+ };
+#endif
+
+ struct Values {
+#ifdef CGAL_CXX11
+ // TODO avoid going through Initializer_list which may cause extra copies. Possibly use forward_as_tuple.
+ template<class...U>
+ result_type operator()(U&&...u) const {
+ check_dim(sizeof...(U)); // TODO: use static_assert
+ return Initializer_list()({forward_safe<NT,U>(u)...});
+ }
+#else
+
+#define CGAL_CODE(Z,N,_) result_type operator()(BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
+ check_dim(N); \
+ result_type a(N); \
+ a << BOOST_PP_ENUM_PARAMS(N,t); \
+ return a; \
+}
+BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ )
+#undef CGAL_CODE
+
+#endif
+ };
+
+ struct Values_divide {
+#ifdef CGAL_CXX11
+ template<class H,class...U>
+ result_type operator()(H const&h,U&&...u) const {
+ check_dim(sizeof...(U)); // TODO: use static_assert
+ return Initializer_list()({Rational_traits<NT>().make_rational(std::forward<U>(u),h)...});
+ }
+#else
+
+#define CGAL_VAR(Z,N,_) ( Rational_traits<NT>().make_rational( t##N ,h) )
+#define CGAL_CODE(Z,N,_) template <class H> result_type \
+ operator()(H const&h, BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
+ check_dim(N); \
+ result_type a(N); \
+ a << BOOST_PP_ENUM(N,CGAL_VAR,); \
+ return a; \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ )
+#undef CGAL_CODE
+#undef CGAL_VAR
+
+#endif
+ };
+ };
+}
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Lazy_cartesian.h b/include/gudhi_patches/CGAL/NewKernel_d/Lazy_cartesian.h
new file mode 100644
index 00000000..9ecc2b63
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Lazy_cartesian.h
@@ -0,0 +1,188 @@
+// 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_KERNEL_D_LAZY_CARTESIAN_H
+#define CGAL_KERNEL_D_LAZY_CARTESIAN_H
+
+#include <CGAL/basic.h>
+#include <CGAL/algorithm.h>
+#include <CGAL/Lazy.h>
+#include <CGAL/Default.h>
+#include <CGAL/NewKernel_d/Filtered_predicate2.h>
+#include <CGAL/iterator_from_indices.h>
+#include <CGAL/NewKernel_d/Define_kernel_types.h>
+
+namespace CGAL {
+
+template<class K,class T>
+struct Nth_iterator_element : private Store_kernel<K> {
+ Nth_iterator_element(){}
+ Nth_iterator_element(K const&k):Store_kernel<K>(k){}
+ typedef typename Get_type<K, typename iterator_tag_traits<T>::value_tag>::type result_type;
+ template<class U> result_type operator()(CGAL_FORWARDABLE(U) u, int i) const {
+ typename Get_functor<K, Construct_ttag<T> >::type ci(this->kernel());
+ return *cpp0x::next(ci(CGAL_FORWARD(U,u),Begin_tag()),i);
+ }
+};
+ //typedef typename Functor<typename iterator_tag_traits<T>::nth_element>::type nth_elem;
+template<class K, class T, bool = iterator_tag_traits<T>::has_nth_element>
+struct Select_nth_element_functor {
+ typedef Nth_iterator_element<K, T> type;
+};
+template<class K, class T>
+struct Select_nth_element_functor <K, T, true> :
+ Get_functor<K, typename iterator_tag_traits<T>::nth_element> {};
+
+namespace internal {
+ template<class A,class B,class C,bool/*is_NT=false*/>
+ struct Lazy_construction_maybe_nt {
+ typedef Lazy_construction<A,B,C> type;
+ };
+ template<class A,class B,class C>
+ struct Lazy_construction_maybe_nt<A,B,C,true> {
+ typedef Lazy_construction_nt<A,B,C> type;
+ };
+}
+
+template <class EK_, class AK_, class E2A_, class Kernel_>
+struct Lazy_cartesian_types
+{
+ typedef typename typeset_intersection<
+ typename AK_::Object_list,
+ typename EK_::Object_list
+ >::type Object_list;
+
+ typedef typename typeset_intersection<
+ typename AK_::Iterator_list,
+ typename EK_::Iterator_list
+ >::type Iterator_list;
+
+ template <class T,class=typename Get_type_category<Kernel_,T>::type> struct Type {};
+ template <class T> struct Type<T,Object_tag> {
+ typedef Lazy<
+ typename Get_type<AK_,T>::type,
+ typename Get_type<EK_,T>::type,
+ typename Get_type<EK_, FT_tag>::type,
+ E2A_> type;
+ };
+ template <class T> struct Type<T,Number_tag> {
+ typedef CGAL::Lazy_exact_nt<typename Get_type<EK_,T>::type> type;
+ };
+
+ template <class T> struct Iterator {
+ typedef typename iterator_tag_traits<T>::value_tag Vt;
+ typedef typename Type<Vt>::type V;
+ typedef typename Select_nth_element_functor<AK_,T>::type AF;
+ typedef typename Select_nth_element_functor<EK_,T>::type EF;
+
+ typedef typename internal::Lazy_construction_maybe_nt<
+ Kernel_, AF, EF, is_NT_tag<Vt>::value
+ >::type nth_elem;
+
+ typedef Iterator_from_indices<
+ const typename Type<typename iterator_tag_traits<T>::container>::type,
+ const V, V, nth_elem
+ > type;
+ };
+};
+
+template <class EK_, class AK_, class E2A_/*, class Kernel_=Default*/>
+struct Lazy_cartesian : Dimension_base<typename EK_::Default_ambient_dimension>,
+ Lazy_cartesian_types<EK_,AK_,E2A_,Lazy_cartesian<EK_,AK_,E2A_> >
+{
+ //CGAL_CONSTEXPR Lazy_cartesian(){}
+ //CGAL_CONSTEXPR Lazy_cartesian(int d):Base_(d){}
+
+ //TODO: Do we want to store an AK and an EK? Or just references?
+ //FIXME: references would be better I guess.
+ //TODO: In any case, make sure that we don't end up storing this kernel for
+ //nothing (it is not empty but references empty kernels or something)
+ AK_ ak; EK_ ek;
+ AK_ const& approximate_kernel()const{return ak;}
+ EK_ const& exact_kernel()const{return ek;}
+
+ typedef Lazy_cartesian Self;
+ typedef Lazy_cartesian_types<EK_,AK_,E2A_,Self> Base;
+ //typedef typename Default::Get<Kernel_,Self>::type Kernel;
+ typedef Self Kernel;
+ typedef AK_ Approximate_kernel;
+ typedef EK_ Exact_kernel;
+ typedef E2A_ E2A;
+ typedef Approx_converter<Kernel, Approximate_kernel> C2A;
+ typedef Exact_converter<Kernel, Exact_kernel> C2E;
+
+ typedef typename Exact_kernel::Rep_tag Rep_tag;
+ typedef typename Exact_kernel::Kernel_tag Kernel_tag;
+ typedef typename Exact_kernel::Default_ambient_dimension Default_ambient_dimension;
+ typedef typename Exact_kernel::Max_ambient_dimension Max_ambient_dimension;
+ //typedef typename Exact_kernel::Flat_orientation Flat_orientation;
+ // Check that Approximate_kernel agrees with all that...
+
+ template<class T,class D=void,class=typename Get_functor_category<Lazy_cartesian,T,D>::type> struct Functor {
+ typedef Null_functor type;
+ };
+ //FIXME: what do we do with D here?
+ template<class T,class D> struct Functor<T,D,Predicate_tag> {
+ typedef typename Get_functor<Approximate_kernel, T>::type FA;
+ typedef typename Get_functor<Exact_kernel, T>::type FE;
+ typedef Filtered_predicate2<FE,FA,C2E,C2A> type;
+ };
+ template<class T,class D> struct Functor<T,D,Compute_tag> {
+ typedef typename Get_functor<Approximate_kernel, T>::type FA;
+ typedef typename Get_functor<Exact_kernel, T>::type FE;
+ typedef Lazy_construction_nt<Kernel,FA,FE> type;
+ };
+ template<class T,class D> struct Functor<T,D,Construct_tag> {
+ typedef typename Get_functor<Approximate_kernel, T>::type FA;
+ typedef typename Get_functor<Exact_kernel, T>::type FE;
+ typedef Lazy_construction<Kernel,FA,FE> type;
+ };
+
+ //typedef typename Iterator<Point_cartesian_const_iterator_tag>::type Point_cartesian_const_iterator;
+ //typedef typename Iterator<Vector_cartesian_const_iterator_tag>::type Vector_cartesian_const_iterator;
+
+ template<class U>
+ struct Construct_iter : private Store_kernel<Kernel> {
+ Construct_iter(){}
+ Construct_iter(Kernel const&k):Store_kernel<Kernel>(k){}
+ //FIXME: pass the kernel to the functor in the iterator
+ typedef U result_type;
+ template<class T>
+ result_type operator()(T const& t,Begin_tag)const{
+ return result_type(t,0,this->kernel());
+ }
+ template<class T>
+ result_type operator()(T const& t,End_tag)const{
+ return result_type(t,Self().dimension(),this->kernel());
+ }
+ };
+ template<class T,class D> struct Functor<T,D,Construct_iterator_tag> {
+ typedef Construct_iter<typename Base::template Iterator<typename map_result_tag<T>::type>::type> type;
+ };
+
+
+ //TODO: what about other functors of the Misc category?
+ // for Point_dimension, we should apply it to the approximate point
+ // for printing, we should??? just not do printing this way?
+};
+
+
+} //namespace CGAL
+
+#endif // CGAL_KERNEL_D_LAZY_CARTESIAN_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Types/Aff_transformation.h b/include/gudhi_patches/CGAL/NewKernel_d/Types/Aff_transformation.h
new file mode 100644
index 00000000..6d9f070f
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Types/Aff_transformation.h
@@ -0,0 +1,59 @@
+// 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_KD_TYPE_AFF_TRANSFORMATION_H
+#define CGAL_KD_TYPE_AFF_TRANSFORMATION_H
+#include <CGAL/config.h>
+#include <CGAL/NewKernel_d/store_kernel.h>
+#include <boost/preprocessor/repetition.hpp>
+
+// Dummy, that's all the Kernel_d concept requires, so a useful class will wait.
+
+namespace CGAL {
+template<class R_>
+struct Aff_transformation {
+ typedef R_ R;
+};
+namespace CartesianDKernelFunctors {
+template<class R_> struct Construct_aff_transformation {
+ CGAL_FUNCTOR_INIT_IGNORE(Construct_aff_transformation)
+ typedef R_ R;
+ typedef typename Get_type<R, Aff_transformation_tag>::type result_type;
+#ifdef CGAL_CXX11
+ template<class...T>
+ result_type operator()(T&&...)const{return result_type();}
+#else
+ result_type operator()()const{
+ return result_type();
+ }
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> \
+ result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const& BOOST_PP_INTERCEPT))const{ \
+ return result_type(); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1, 9, CGAL_CODE, _ )
+#undef CGAL_CODE
+
+#endif
+};
+}
+CGAL_KD_DEFAULT_TYPE(Aff_transformation_tag,(CGAL::Aff_transformation<K>),(),());
+CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Aff_transformation_tag>,(CartesianDKernelFunctors::Construct_aff_transformation<K>),(Aff_transformation_tag),());
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Types/Hyperplane.h b/include/gudhi_patches/CGAL/NewKernel_d/Types/Hyperplane.h
new file mode 100644
index 00000000..14e35b01
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Types/Hyperplane.h
@@ -0,0 +1,159 @@
+// 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_KD_TYPE_HYPERPLANE_H
+#define CGAL_KD_TYPE_HYPERPLANE_H
+#include <CGAL/enum.h>
+#include <CGAL/number_utils.h>
+#include <CGAL/NewKernel_d/store_kernel.h>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+namespace CGAL {
+template <class R_> class Hyperplane {
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename Get_type<R_, Vector_tag>::type Vector_;
+ Vector_ v_;
+ FT_ s_;
+
+ public:
+ Hyperplane(Vector_ const&v, FT_ const&s): v_(v), s_(s) {}
+ // TODO: Add a piecewise constructor?
+
+ Vector_ const& orthogonal_vector()const{return v_;}
+ FT_ translation()const{return s_;}
+};
+namespace CartesianDKernelFunctors {
+template <class R_> struct Construct_hyperplane : Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Construct_hyperplane)
+ typedef typename Get_type<R_, Hyperplane_tag>::type result_type;
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename Get_type<R_, Vector_tag>::type Vector;
+ typedef typename Get_type<R_, FT_tag>::type FT;
+ private:
+ struct One {
+ typedef int result_type;
+ template<class T>int const& operator()(T const&)const{
+ static const int one = 1;
+ return one;
+ }
+ };
+ public:
+
+ result_type operator()(Vector const&a, FT const&b)const{
+ return result_type(a,b);
+ }
+ // Not really needed
+ result_type operator()()const{
+ typename Get_functor<R_, Construct_ttag<Vector_tag> >::type cv(this->kernel());
+ return result_type(cv(),0);
+ }
+
+ template <class Iter>
+ result_type through(Iter f, Iter e)const{
+ typedef typename R_::LA LA;
+ typedef typename R_::Default_ambient_dimension D1;
+ typedef typename R_::Max_ambient_dimension D2;
+ typedef typename Increment_dimension<D1>::type D1i;
+ typedef typename Increment_dimension<D2>::type D2i;
+
+ typedef Eigen::Matrix<FT, Eigen_dimension<D1>::value, Eigen_dimension<D1i>::value,
+ Eigen::ColMajor|Eigen::AutoAlign, Eigen_dimension<D2>::value, Eigen_dimension<D2i>::value> Matrix;
+ typedef Eigen::Matrix<FT, Eigen_dimension<D1i>::value, 1,
+ Eigen::ColMajor|Eigen::AutoAlign, Eigen_dimension<D2i>::value, 1> Vec;
+ typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R_, Construct_ttag<Vector_tag> >::type cv(this->kernel());
+ typename Get_functor<R_, Point_dimension_tag>::type pd(this->kernel());
+
+ Point const& p0=*f;
+ int d = pd(p0);
+ Matrix m(d,d+1);
+ for(int j=0;j<d;++j)
+ m(0,j)=c(p0,j);
+ // Write the point coordinates in lines.
+ int i;
+ for (i=1; ++f!=e; ++i) {
+ Point const& p=*f;
+ for(int j=0;j<d;++j)
+ m(i,j)=c(p,j);
+ }
+ CGAL_assertion (i == d);
+ for(i=0;i<d;++i)
+ m(i,d)=-1;
+ Eigen::FullPivLU<Matrix> lu(m);
+ Vec res = lu.kernel().col(0);
+ return this->operator()(cv(d,LA::vector_begin(res),LA::vector_end(res)-1),res(d));
+ }
+ template <class Iter>
+ result_type operator()(Iter f, Iter e, Point const&p, CGAL::Oriented_side s=ON_ORIENTED_BOUNDARY)const{
+ result_type ret = through(f, e);
+ // I don't really like using ON_ORIENTED_BOUNDARY to mean that we don't care, we might as well not pass 'p' at all.
+ if (s == ON_ORIENTED_BOUNDARY)
+ return ret;
+ typename Get_functor<R_, Oriented_side_tag>::type os(this->kernel());
+ CGAL::Oriented_side o = os(ret, p);
+ if (o == ON_ORIENTED_BOUNDARY || o == s)
+ return ret;
+ typename Get_functor<R_, Opposite_vector_tag>::type ov(this->kernel());
+ typename Get_functor<R_, Construct_ttag<Vector_tag> >::type cv(this->kernel());
+ return this->operator()(ov(ret.orthogonal_vector()), -ret.translation());
+ }
+};
+template <class R_> struct Orthogonal_vector {
+ CGAL_FUNCTOR_INIT_IGNORE(Orthogonal_vector)
+ typedef typename Get_type<R_, Hyperplane_tag>::type Hyperplane;
+ typedef typename Get_type<R_, Vector_tag>::type const& result_type;
+ result_type operator()(Hyperplane const&s)const{
+ return s.orthogonal_vector();
+ }
+};
+template <class R_> struct Hyperplane_translation {
+ CGAL_FUNCTOR_INIT_IGNORE(Hyperplane_translation)
+ typedef typename Get_type<R_, Hyperplane_tag>::type Hyperplane;
+ typedef typename Get_type<R_, FT_tag>::type result_type;
+ // TODO: Is_exact?
+ result_type operator()(Hyperplane const&s)const{
+ return s.translation();
+ }
+};
+template <class R_> struct Value_at : Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Value_at)
+ typedef typename Get_type<R_, Hyperplane_tag>::type Hyperplane;
+ typedef typename Get_type<R_, Vector_tag>::type Vector;
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename Get_type<R_, FT_tag>::type FT;
+ typedef FT result_type;
+ typedef typename Get_functor<R_, Scalar_product_tag>::type Dot;
+ typedef typename Get_functor<R_, Point_to_vector_tag>::type P2V;
+ result_type operator()(Hyperplane const&h, Point const&p)const{
+ Dot dot(this->kernel());
+ P2V p2v(this->kernel());
+ return dot(h.orthogonal_vector(),p2v(p));
+ // Use Orthogonal_vector to make it generic?
+ // Copy the code from Scalar_product to avoid p2v?
+ }
+};
+}
+//TODO: Add a condition that the hyperplane type is the one from this file.
+CGAL_KD_DEFAULT_TYPE(Hyperplane_tag,(CGAL::Hyperplane<K>),(Vector_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Hyperplane_tag>,(CartesianDKernelFunctors::Construct_hyperplane<K>),(Vector_tag,Hyperplane_tag),(Opposite_vector_tag,Oriented_side_tag));
+CGAL_KD_DEFAULT_FUNCTOR(Orthogonal_vector_tag,(CartesianDKernelFunctors::Orthogonal_vector<K>),(Vector_tag,Hyperplane_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Hyperplane_translation_tag,(CartesianDKernelFunctors::Hyperplane_translation<K>),(Hyperplane_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Value_at_tag,(CartesianDKernelFunctors::Value_at<K>),(Point_tag,Vector_tag,Hyperplane_tag),(Scalar_product_tag,Point_to_vector_tag));
+} // namespace CGAL
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Types/Iso_box.h b/include/gudhi_patches/CGAL/NewKernel_d/Types/Iso_box.h
new file mode 100644
index 00000000..d053f351
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Types/Iso_box.h
@@ -0,0 +1,88 @@
+// 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_KERNELD_TYPES_ISO_BOX_H
+#define CGAL_KERNELD_TYPES_ISO_BOX_H
+#include <utility>
+#include <CGAL/basic.h>
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Kernel/mpl.h>
+#include <CGAL/transforming_pair_iterator.h>
+namespace CGAL {
+template <class R_> class Iso_box {
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename Get_type<R_, Point_tag>::type Point_;
+ typedef std::pair<Point_,Point_> Data_;
+ Data_ data;
+ public:
+ Iso_box(){}
+ Iso_box(Point_ const&a, Point_ const&b): data(a,b) {}
+ Point_ min BOOST_PREVENT_MACRO_SUBSTITUTION ()const{
+ return data.first;
+ }
+ Point_ max BOOST_PREVENT_MACRO_SUBSTITUTION ()const{
+ return data.second;
+ }
+};
+namespace CartesianDKernelFunctors {
+ template <class R_> struct Construct_iso_box : Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Construct_iso_box)
+ typedef typename Get_type<R_, Iso_box_tag>::type result_type;
+ typedef typename Get_type<R_, RT_tag>::type RT;
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename Get_functor<R_, Construct_ttag<Point_tag> >::type Cp_;
+ typedef typename Get_functor<R_, Construct_ttag<Point_cartesian_const_iterator_tag> >::type Ci_;
+ result_type operator()(Point const&a, Point const&b)const{
+ Cp_ cp(this->kernel());
+ Ci_ ci(this->kernel());
+ return result_type(cp(
+ make_transforming_pair_iterator(ci(a,Begin_tag()), ci(b,Begin_tag()), Min<RT>()),
+ make_transforming_pair_iterator(ci(a,End_tag()), ci(b,End_tag()), Min<RT>())),
+ cp(
+ make_transforming_pair_iterator(ci(a,Begin_tag()), ci(b,Begin_tag()), Max<RT>()),
+ make_transforming_pair_iterator(ci(a,End_tag()), ci(b,End_tag()), Max<RT>())));
+ }
+ };
+
+ template <class R_> struct Construct_min_vertex {
+ CGAL_FUNCTOR_INIT_IGNORE(Construct_min_vertex)
+ typedef typename Get_type<R_, Iso_box_tag>::type argument_type;
+ //TODO: make result_type a reference
+ typedef typename Get_type<R_, Point_tag>::type result_type;
+ result_type operator()(argument_type const&b)const{
+ return b.min BOOST_PREVENT_MACRO_SUBSTITUTION ();
+ }
+ };
+ template <class R_> struct Construct_max_vertex {
+ CGAL_FUNCTOR_INIT_IGNORE(Construct_max_vertex)
+ typedef typename Get_type<R_, Iso_box_tag>::type argument_type;
+ typedef typename Get_type<R_, Point_tag>::type result_type;
+ result_type operator()(argument_type const&b)const{
+ return b.max BOOST_PREVENT_MACRO_SUBSTITUTION ();
+ }
+ };
+}
+//TODO (other types as well) only enable these functors if the Iso_box type is the one defined in this file...
+CGAL_KD_DEFAULT_TYPE(Iso_box_tag,(CGAL::Iso_box<K>),(Point_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Iso_box_tag>,(CartesianDKernelFunctors::Construct_iso_box<K>),(Iso_box_tag,Point_tag),(Construct_ttag<Point_cartesian_const_iterator_tag>,Construct_ttag<Point_tag>));
+CGAL_KD_DEFAULT_FUNCTOR(Construct_min_vertex_tag,(CartesianDKernelFunctors::Construct_min_vertex<K>),(Iso_box_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Construct_max_vertex_tag,(CartesianDKernelFunctors::Construct_max_vertex<K>),(Iso_box_tag),());
+} // namespace CGAL
+
+#endif // CGAL_KERNELD_TYPES_ISO_BOX_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Types/Line.h b/include/gudhi_patches/CGAL/NewKernel_d/Types/Line.h
new file mode 100644
index 00000000..6a09571c
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Types/Line.h
@@ -0,0 +1,66 @@
+// 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_KERNELD_TYPES_LINE_H
+#define CGAL_KERNELD_TYPES_LINE_H
+#include <utility>
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Kernel/mpl.h>
+namespace CGAL {
+template <class R_> class Line {
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename Get_type<R_, Point_tag>::type Point_;
+ typedef std::pair<Point_,Point_> Data_;
+ Data_ data;
+ public:
+ Line(){}
+ Line(Point_ const&a, Point_ const&b): data(a,b) {}
+ Point_ point(int i)const{
+ if(i==0) return data.first;
+ if(i==1) return data.second;
+ throw "not implemented";
+ }
+ Line opposite()const{
+ return Line(data.second,data.first);
+ }
+};
+namespace CartesianDKernelFunctors {
+ template <class R_> struct Construct_line : Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Construct_line)
+ typedef typename Get_type<R_, Line_tag>::type result_type;
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename Get_type<R_, Vector_tag>::type Vector;
+ typedef typename Get_functor<R_, Translated_point_tag>::type Tp_;
+ //typedef typename Get_functor<R_, Difference_of_points_tag>::type Dp_;
+ //typedef typename Get_functor<R_, Scaled_vector_tag>::type Sv_;
+ result_type operator()(Point const&a, Point const&b)const{
+ return result_type(a,b);
+ }
+ result_type operator()(Point const&a, typename First_if_different<Vector,Point>::Type const&b)const{
+ Tp_ tp(this->kernel());
+ return result_type(a,tp(a,b));
+ }
+ };
+}
+CGAL_KD_DEFAULT_TYPE(Line_tag,(CGAL::Line<K>),(Point_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Line_tag>,(CartesianDKernelFunctors::Construct_line<K>),(Line_tag,Point_tag,Vector_tag),(Translated_point_tag));
+
+} // namespace CGAL
+
+#endif // CGAL_KERNELD_TYPES_LINE_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Types/Ray.h b/include/gudhi_patches/CGAL/NewKernel_d/Types/Ray.h
new file mode 100644
index 00000000..be845e76
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Types/Ray.h
@@ -0,0 +1,66 @@
+// 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_KERNELD_TYPES_RAY_H
+#define CGAL_KERNELD_TYPES_RAY_H
+#include <utility>
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Kernel/mpl.h>
+namespace CGAL {
+template <class R_> class Ray {
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename Get_type<R_, Point_tag>::type Point_;
+ typedef typename Get_type<R_, Vector_tag>::type Vector_;
+ typedef std::pair<Point_,Vector_> Data_;
+ Data_ data;
+ public:
+ Ray(){}
+ Ray(Point_ const&a, Vector_ const&b): data(a,b) {}
+ Point_ source()const{
+ return data.first;
+ }
+ // FIXME: return a R_::Direction?
+ Vector_ direction()const{
+ return data.second;
+ }
+};
+namespace CartesianDKernelFunctors {
+ template <class R_> struct Construct_ray : Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Construct_ray)
+ typedef typename Get_type<R_, Ray_tag>::type result_type;
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename Get_type<R_, Vector_tag>::type Vector;
+ typedef typename Get_functor<R_, Difference_of_points_tag>::type Dp_;
+ //typedef typename Get_functor<R_, Translated_point_tag>::type Tp_;
+ //typedef typename Get_functor<R_, Scaled_vector_tag>::type Sv_;
+ result_type operator()(Point const&a, Vector const&b)const{
+ return result_type(a,b);
+ }
+ result_type operator()(Point const&a, typename First_if_different<Point,Vector>::Type const&b)const{
+ Dp_ dp(this->kernel());
+ return result_type(a,dp(b,a));
+ }
+ };
+}
+CGAL_KD_DEFAULT_TYPE(Ray_tag,(CGAL::Ray<K>),(Point_tag,Vector_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Ray_tag>,(CartesianDKernelFunctors::Construct_ray<K>),(Point_tag,Ray_tag,Vector_tag),(Difference_of_points_tag));
+
+} // namespace CGAL
+
+#endif // CGAL_KERNELD_TYPES_RAY_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Types/Segment.h b/include/gudhi_patches/CGAL/NewKernel_d/Types/Segment.h
new file mode 100644
index 00000000..38361c2b
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Types/Segment.h
@@ -0,0 +1,121 @@
+// 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_KERNELD_SEGMENTD_H
+#define CGAL_KERNELD_SEGMENTD_H
+#include <CGAL/config.h>
+#include <utility>
+#include <CGAL/NewKernel_d/functor_tags.h>
+namespace CGAL {
+template <class R_> class Segment {
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename Get_type<R_, Point_tag>::type Point_;
+ //typedef typename R_::Vector Vector_;
+ //typedef typename Get_functor<R_, Construct_ttag<Vector_tag> >::type Cv_;
+// typedef typename R_::Squared_distance Csd_;
+ typedef std::pair<Point_,Point_> Data_;
+ Data_ data;
+ public:
+ //typedef Segmentd<R_> Segment;
+#ifdef CGAL_CXX11
+ //FIXME: don't forward directly, piecewise_constuct should call the point construction functor (I guess? or is it unnecessary?)
+ template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Segment>>::value>::type>
+ Segment(U&&...u):data(std::forward<U>(u)...){}
+#else
+ Segment(){}
+ Segment(Point_ const&a, Point_ const&b): data(a,b) {}
+ //template<class A,class T1,class T2>
+ //Segment(A const&,T1 const&t1,T2 const&t2)
+#endif
+ Point_ source()const{return data.first;}
+ Point_ target()const{return data.second;}
+ Point_ operator[](int i)const{
+ if((i%2)==0)
+ return source();
+ else
+ return target();
+ }
+ Segment opposite()const{
+ return Segment(target(),source());
+ }
+ //Vector_ vector()const{
+ // return Cv_()(data.first,data.second);
+ //}
+// FT_ squared_length()const{
+// return Csd_()(data.first,data.second);
+// }
+};
+
+namespace CartesianDKernelFunctors {
+
+template<class R_> struct Construct_segment : Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Construct_segment)
+ typedef R_ R;
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename Get_type<R_, Segment_tag>::type Segment;
+ typedef typename Get_functor<R_, Construct_ttag<Point_tag> >::type CP;
+ typedef Segment result_type;
+ result_type operator()(Point const&a, Point const&b)const{
+ return result_type(a,b);
+ }
+ // Not really needed, especially since it forces us to store the kernel
+ result_type operator()()const{
+ Point p = typename Get_functor<R_, Construct_ttag<Point_tag> >::type (this->kernel()) ();
+ return result_type (p, p);
+ }
+ // T should only be std::piecewise_construct_t, but we shouldn't fail if it doesn't exist.
+ template<class T,class U,class V>
+ result_type operator()(CGAL_FORWARDABLE(T),CGAL_FORWARDABLE(U) u,CGAL_FORWARDABLE(V) v)const{
+ CP cp(this->kernel());
+ result_type r = {{
+ call_on_tuple_elements<Point>(cp, CGAL_FORWARD(U,u)),
+ call_on_tuple_elements<Point>(cp, CGAL_FORWARD(V,v)) }};
+ return r;
+ }
+};
+
+// This should be part of Construct_point, according to Kernel_23 conventions
+template<class R_> struct Segment_extremity {
+ CGAL_FUNCTOR_INIT_IGNORE(Segment_extremity)
+ typedef R_ R;
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename Get_type<R_, Segment_tag>::type Segment;
+ typedef Point result_type;
+ result_type operator()(Segment const&s, int i)const{
+ if(i==0) return s.source();
+ CGAL_assertion(i==1);
+ return s.target();
+ }
+#ifdef CGAL_CXX11
+ result_type operator()(Segment &&s, int i)const{
+ if(i==0) return std::move(s.source());
+ CGAL_assertion(i==1);
+ return std::move(s.target());
+ }
+#endif
+};
+} // CartesianDKernelFunctors
+
+CGAL_KD_DEFAULT_TYPE(Segment_tag,(CGAL::Segment<K>),(Point_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Segment_tag>,(CartesianDKernelFunctors::Construct_segment<K>),(Segment_tag,Point_tag),(Construct_ttag<Point_tag>));
+CGAL_KD_DEFAULT_FUNCTOR(Segment_extremity_tag,(CartesianDKernelFunctors::Segment_extremity<K>),(Segment_tag,Point_tag),());
+
+} // namespace CGAL
+
+#endif // CGAL_KERNELD_SEGMENTD_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Types/Sphere.h b/include/gudhi_patches/CGAL/NewKernel_d/Types/Sphere.h
new file mode 100644
index 00000000..114410b4
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Types/Sphere.h
@@ -0,0 +1,132 @@
+// 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_KD_TYPE_SPHERE_H
+#define CGAL_KD_TYPE_SPHERE_H
+#include <CGAL/NewKernel_d/store_kernel.h>
+#include <boost/iterator/counting_iterator.hpp>
+namespace CGAL {
+template <class R_> class Sphere {
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename Get_type<R_, Point_tag>::type Point_;
+ Point_ c_;
+ FT_ r2_;
+
+ public:
+ Sphere(Point_ const&p, FT_ const&r2): c_(p), r2_(r2) {}
+ // TODO: Add a piecewise constructor?
+
+ Point_ const& center()const{return c_;}
+ FT_ const& squared_radius()const{return r2_;}
+};
+
+namespace CartesianDKernelFunctors {
+template <class R_> struct Construct_sphere : Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Construct_sphere)
+ typedef typename Get_type<R_, Sphere_tag>::type result_type;
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename Get_type<R_, FT_tag>::type FT;
+ result_type operator()(Point const&a, FT const&b)const{
+ return result_type(a,b);
+ }
+ // Not really needed
+ result_type operator()()const{
+ typename Get_functor<R_, Construct_ttag<Point_tag> >::type cp(this->kernel());
+ return result_type(cp(),0);
+ }
+ template <class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ typename Get_functor<R_, Construct_circumcenter_tag>::type cc(this->kernel());
+ typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());
+
+ // It should be possible to avoid copying the center by moving this code to a constructor.
+ Point center = cc(f, e);
+ FT const& r2 = sd(center, *f);
+ return this->operator()(CGAL_MOVE(center), r2);
+ }
+};
+
+template <class R_> struct Center_of_sphere : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Center_of_sphere)
+ typedef typename Get_type<R_, Sphere_tag>::type Sphere;
+ // No reference because of the second overload
+ typedef typename Get_type<R_, Point_tag>::type result_type;
+
+ result_type const& operator()(Sphere const&s)const{
+ return s.center();
+ }
+
+ template<class Iter>
+ result_type operator()(Iter b, Iter e)const{
+ typename Get_functor<R_, Construct_ttag<Sphere_tag> >::type cs(this->kernel());
+ return operator()(cs(b,e)); // computes the radius needlessly
+ }
+};
+
+template <class R_> struct Squared_radius {
+ CGAL_FUNCTOR_INIT_IGNORE(Squared_radius)
+ typedef typename Get_type<R_, Sphere_tag>::type Sphere;
+ typedef typename Get_type<R_, FT_tag>::type const& result_type;
+ // TODO: Is_exact?
+ result_type operator()(Sphere const&s)const{
+ return s.squared_radius();
+ }
+};
+
+// FIXME: Move it to the generic functors, using the two above and conditional to the existence of sqrt(FT)
+template<class R_> struct Point_of_sphere : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Point_of_sphere)
+ typedef R_ R;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Sphere_tag>::type Sphere;
+ typedef typename Get_functor<R, Construct_ttag<Point_tag> >::type CP;
+ typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
+ typedef typename Get_functor<R, Point_dimension_tag>::type PD;
+ typedef Point result_type;
+ typedef Sphere first_argument_type;
+ typedef int second_argument_type;
+ struct Trans : std::binary_function<FT,int,FT> {
+ FT const& r_; int idx; bool sgn;
+ Trans (int n, FT const& r, bool b) : r_(r), idx(n), sgn(b) {}
+ FT operator()(FT const&x, int i)const{
+ return (i == idx) ? sgn ? x + r_ : x - r_ : x;
+ }
+ };
+ result_type operator()(Sphere const&s, int i)const{
+ CI ci(this->kernel());
+ PD pd(this->kernel());
+ typedef boost::counting_iterator<int,std::random_access_iterator_tag> Count;
+ Point const&c = s.center();
+ int d=pd(c);
+ bool last = (i == d);
+ FT r = sqrt(s.squared_radius());
+ Trans t(last ? 0 : i, r, !last);
+ return CP(this->kernel())(make_transforming_pair_iterator(ci(c,Begin_tag()),Count(0),t),make_transforming_pair_iterator(ci(c,End_tag()),Count(d),t));
+ }
+};
+}
+CGAL_KD_DEFAULT_TYPE(Sphere_tag,(CGAL::Sphere<K>),(Point_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Sphere_tag>,(CartesianDKernelFunctors::Construct_sphere<K>),(Sphere_tag,Point_tag),(Construct_ttag<Point_tag>,Compute_point_cartesian_coordinate_tag,Squared_distance_tag,Squared_distance_to_origin_tag,Point_dimension_tag));
+CGAL_KD_DEFAULT_FUNCTOR(Center_of_sphere_tag,(CartesianDKernelFunctors::Center_of_sphere<K>),(Sphere_tag,Point_tag),(Construct_ttag<Sphere_tag>));
+CGAL_KD_DEFAULT_FUNCTOR(Squared_radius_tag,(CartesianDKernelFunctors::Squared_radius<K>),(Sphere_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Point_of_sphere_tag,(CartesianDKernelFunctors::Point_of_sphere<K>),(Sphere_tag,Point_tag),(Construct_ttag<Point_tag>, Construct_ttag<Point_cartesian_const_iterator_tag>));
+} // namespace CGAL
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Types/Weighted_point.h b/include/gudhi_patches/CGAL/NewKernel_d/Types/Weighted_point.h
new file mode 100644
index 00000000..1caf8701
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Types/Weighted_point.h
@@ -0,0 +1,205 @@
+// 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_KD_TYPE_WP_H
+#define CGAL_KD_TYPE_WP_H
+#include <CGAL/NewKernel_d/store_kernel.h>
+#include <boost/iterator/counting_iterator.hpp>
+namespace CGAL {
+namespace KerD {
+template <class R_> class Weighted_point {
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename Get_type<R_, Point_tag>::type Point_;
+ Point_ c_;
+ FT_ w_;
+
+ public:
+ Weighted_point(Point_ const&p, FT_ const&w): c_(p), w_(w) {}
+ // TODO: Add a piecewise constructor?
+
+ Point_ const& point()const{return c_;}
+ FT_ const& weight()const{return w_;}
+};
+}
+
+namespace CartesianDKernelFunctors {
+template <class R_> struct Construct_weighted_point : Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Construct_weighted_point)
+ typedef typename Get_type<R_, Weighted_point_tag>::type result_type;
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename Get_type<R_, FT_tag>::type FT;
+ result_type operator()(Point const&a, FT const&b)const{
+ return result_type(a,b);
+ }
+ // Not really needed
+ result_type operator()()const{
+ typename Get_functor<R_, Construct_ttag<Point_tag> >::type cp(this->kernel());
+ return result_type(cp(),0);
+ }
+};
+
+template <class R_> struct Point_drop_weight {
+ CGAL_FUNCTOR_INIT_IGNORE(Point_drop_weight)
+ typedef typename Get_type<R_, Weighted_point_tag>::type argument_type;
+ typedef typename Get_type<R_, Point_tag>::type const& result_type;
+ // Returning a reference is fragile
+
+ result_type operator()(argument_type const&s)const{
+ return s.point();
+ }
+};
+
+template <class R_> struct Point_weight {
+ CGAL_FUNCTOR_INIT_IGNORE(Point_weight)
+ typedef typename Get_type<R_, Weighted_point_tag>::type argument_type;
+ typedef typename Get_type<R_, FT_tag>::type result_type;
+
+ result_type operator()(argument_type const&s)const{
+ return s.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_side_of_power_sphere : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Power_side_of_power_sphere)
+ typedef R_ R;
+ typedef typename Get_type<R, Oriented_side_tag>::type result_type;
+
+ template<class Iter, class Pt>
+ result_type operator()(Iter const& f, Iter const& e, Pt const& p0) const {
+ typename Get_functor<R, Power_side_of_power_sphere_raw_tag>::type ptr(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());
+ return ptr (
+ make_transforming_iterator (f, pdw),
+ make_transforming_iterator (e, pdw),
+ make_transforming_iterator (f, pw),
+ pdw (p0),
+ pw (p0));
+ }
+};
+
+template<class R_> struct In_flat_power_side_of_power_sphere : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(In_flat_power_side_of_power_sphere)
+ typedef R_ R;
+ typedef typename Get_type<R, Oriented_side_tag>::type result_type;
+
+ template<class Fo, class Iter, class Pt>
+ result_type operator()(Fo const& fo, Iter const& f, Iter const& e, Pt const& p0) const {
+ typename Get_functor<R, In_flat_power_side_of_power_sphere_raw_tag>::type ptr(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());
+ return ptr (
+ fo,
+ make_transforming_iterator (f, pdw),
+ make_transforming_iterator (e, pdw),
+ make_transforming_iterator (f, pw),
+ pdw (p0),
+ pw (p0));
+ }
+};
+
+// 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_FUNCTOR(Construct_ttag<Weighted_point_tag>,(CartesianDKernelFunctors::Construct_weighted_point<K>),(Weighted_point_tag,Point_tag),());
+CGAL_KD_DEFAULT_FUNCTOR(Point_drop_weight_tag,(CartesianDKernelFunctors::Point_drop_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_side_of_power_sphere_tag,(CartesianDKernelFunctors::Power_side_of_power_sphere<K>),(Weighted_point_tag),(Power_side_of_power_sphere_raw_tag,Point_drop_weight_tag,Point_weight_tag));
+CGAL_KD_DEFAULT_FUNCTOR(In_flat_power_side_of_power_sphere_tag,(CartesianDKernelFunctors::In_flat_power_side_of_power_sphere<K>),(Weighted_point_tag),(In_flat_power_side_of_power_sphere_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
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/array.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/array.h
new file mode 100644
index 00000000..0ad9bb36
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/array.h
@@ -0,0 +1,165 @@
+// 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_VECTOR_ARRAY_H
+#define CGAL_VECTOR_ARRAY_H
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <CGAL/Dimension.h>
+#include <CGAL/NewKernel_d/utils.h>
+#include <CGAL/array.h>
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+
+#include <CGAL/NewKernel_d/Vector/determinant_of_points_from_vectors.h>
+#include <CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim.h>
+#include <CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h>
+#include <CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_points.h>
+#include <CGAL/NewKernel_d/Vector/determinant_of_iterator_to_vectors_from_vectors.h>
+
+
+
+namespace CGAL {
+
+// May not be safe to use with dim!=max_dim.
+// In that case, we should store the real dim next to the array.
+template<class NT_,class Dim_,class Max_dim_=Dim_> struct Array_vector {
+ typedef NT_ NT;
+ typedef Dim_ Dimension;
+ typedef Max_dim_ Max_dimension;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef Array_vector< NT, D2, D3 > Other;
+ };
+ template<class> struct Property : boost::false_type {};
+
+ static const unsigned d_=Max_dim_::value;
+ CGAL_static_assertion(d_ != (unsigned)UNKNOWN_DIMENSION);
+
+ typedef cpp0x::array<NT,d_> Vector;
+ struct Construct_vector {
+ struct Dimension {
+ // Initialize with NaN if possible?
+ Vector operator()(unsigned CGAL_assertion_code(d)) const {
+ CGAL_assertion(d<=d_);
+ return Vector();
+ }
+ };
+
+ struct Iterator {
+ template<typename Iter>
+ Vector operator()(unsigned CGAL_assertion_code(d),Iter const& f,Iter const& e) const {
+ CGAL_assertion(d==(unsigned) std::distance(f,e));
+ CGAL_assertion(d<=d_);
+ //TODO: optimize for forward iterators
+ Vector a;
+ std::copy(f,e,a.begin());
+ return a;
+ }
+ };
+
+#if 0
+ struct Iterator_add_one {
+ template<typename Iter>
+ Vector operator()(unsigned d,Iter const& f,Iter const& e) const {
+ CGAL_assertion(d==std::distance(f,e)+1);
+ CGAL_assertion(d<=d_);
+ //TODO: optimize
+ Vector a;
+ std::copy(f,e,a.begin());
+ a.back()=1;
+ return a;
+ }
+ };
+#endif
+
+ struct Iterator_and_last {
+ template<typename Iter,typename T>
+ Vector operator()(unsigned CGAL_assertion_code(d),Iter const& f,Iter const& e,CGAL_FORWARDABLE(T) t) const {
+ CGAL_assertion(d==std::distance(f,e)+1);
+ CGAL_assertion(d<=d_);
+ //TODO: optimize for forward iterators
+ Vector a;
+ std::copy(f,e,a.begin());
+ a.back()=CGAL_FORWARD(T,t);
+ return a;
+ }
+ };
+
+ struct Values {
+#ifdef CGAL_CXX11
+ template<class...U>
+ Vector operator()(U&&...u) const {
+ static_assert(sizeof...(U)<=d_,"too many arguments");
+ Vector a={{forward_safe<NT,U>(u)...}};
+ return a;
+ }
+#else
+
+#define CGAL_CODE(Z,N,_) Vector operator()(BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
+ CGAL_assertion(N<=d_); \
+ Vector a={{BOOST_PP_ENUM_PARAMS(N,t)}}; \
+ return a; \
+}
+BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ )
+#undef CGAL_CODE
+
+#endif
+ };
+
+ struct Values_divide {
+#ifdef CGAL_CXX11
+ template<class H,class...U>
+ Vector operator()(H const& h,U&&...u) const {
+ static_assert(sizeof...(U)<=d_,"too many arguments");
+ Vector a={{Rational_traits<NT>().make_rational(std::forward<U>(u),h)...}};
+ return a;
+ }
+#else
+
+#define CGAL_VAR(Z,N,_) Rational_traits<NT>().make_rational( t##N , h)
+#define CGAL_CODE(Z,N,_) template <class H> Vector \
+ operator()(H const&h, BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
+ CGAL_assertion(N<=d_); \
+ Vector a={{BOOST_PP_ENUM(N,CGAL_VAR,_)}}; \
+ return a; \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ )
+#undef CGAL_CODE
+#undef CGAL_VAR
+
+#endif
+ };
+ };
+
+ typedef NT const* Vector_const_iterator;
+ static Vector_const_iterator vector_begin(Vector const&a){
+ return &a[0];
+ }
+ static Vector_const_iterator vector_end(Vector const&a){
+ return &a[0]+d_; // Don't know the real size
+ }
+ static unsigned size_of_vector(Vector const&){
+ return d_; // Don't know the real size
+ }
+
+};
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/avx4.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/avx4.h
new file mode 100644
index 00000000..954a3c1b
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/avx4.h
@@ -0,0 +1,213 @@
+// 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_VECTOR_AVX4_H
+#define CGAL_VECTOR_AVX4_H
+
+#if !defined __AVX__ || (__GNUC__ * 100 + __GNUC_MINOR__ < 408)
+#error Requires AVX and gcc 4.8+
+#endif
+#include <x86intrin.h>
+
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/enum.h> // CGAL::Sign
+#include <CGAL/number_utils.h> // CGAL::sign
+
+
+
+namespace CGAL {
+
+ struct Avx_vector_4 {
+ typedef double NT;
+ typedef Dimension_tag<4> Dimension;
+ typedef Dimension_tag<4> Max_dimension;
+ // No Rebind_dimension, this is a building block
+ template<class,bool=true> struct Property : boost::false_type {};
+ template<bool b> struct Property<Has_vector_plus_minus_tag,b>
+ : boost::true_type {};
+ /* MAYBE?
+ template<bool b> struct Property<Has_vector_scalar_ops_tag,b>
+ : boost::true_type {};
+ */
+ template<bool b> struct Property<Has_determinant_of_vectors_tag,b>
+ : boost::true_type {};
+ template<bool b> struct Property<Has_dot_product_tag,b>
+ : boost::true_type {};
+ template<bool b> struct Property<Has_determinant_of_vectors_omit_last_tag,b>
+ : boost::true_type {};
+
+ typedef __m256d Vector;
+ struct Construct_vector {
+ struct Dimension {
+ // Initialize with NaN?
+ Vector operator()(unsigned d) const {
+ CGAL_assertion(d==4);
+ return Vector();
+ }
+ };
+
+ struct Iterator {
+ template<typename Iter>
+ Vector operator()(unsigned d,Iter const& f,Iter const& e) const {
+ CGAL_assertion(d==4);
+ double x0 = *f;
+ double x1 = *++f;
+ double x2 = *++f;
+ double x3 = *++f;
+ CGAL_assertion(++f==e);
+ Vector a = { x0, x1, x2, x3 };
+ return a;
+ }
+ };
+
+ struct Iterator_and_last {
+ template<typename Iter,typename T>
+ Vector operator()(unsigned d,Iter const& f,Iter const& e,double t) const {
+ CGAL_assertion(d==4);
+ double x0 = *f;
+ double x1 = *++f;
+ double x2 = *++f;
+ CGAL_assertion(++f==e);
+ Vector a = { x0, x1, x2, t };
+ return a;
+ }
+ };
+
+ struct Values {
+ Vector operator()(double a,double b,double c,double d) const {
+ Vector r = { a, b, c, d };
+ return r;
+ }
+ };
+
+ struct Values_divide {
+ Vector operator()(double h,double a,double b,double c,double d) const {
+ // {a,b,c,d}/{h,h,h,h} should be roughly the same
+ Vector r = { a/h, b/h, c/h, d/h };
+ return r;
+ }
+ };
+ };
+
+ public:
+ typedef double const* Vector_const_iterator;
+ static inline Vector_const_iterator vector_begin(Vector const&a){
+ return (Vector_const_iterator)(&a);
+ }
+ static inline Vector_const_iterator vector_end(Vector const&a){
+ return (Vector_const_iterator)(&a)+4;
+ }
+ static inline unsigned size_of_vector(Vector){
+ return 4;
+ }
+ static inline double dot_product(__m256d x, __m256d y){
+ __m256d p=x*y;
+ __m256d z=_mm256_hadd_pd(p,p);
+ return z[0]+z[2];
+ }
+ private:
+ static inline __m256d avx_sym(__m256d x){
+#if 0
+ return __builtin_shuffle(x,(__m256i){2,3,0,1});
+#else
+ return _mm256_permute2f128_pd(x,x,1);
+#endif
+ }
+ static inline __m256d avx_left(__m256d x){
+#if 0
+ return __builtin_shuffle(x,(__m256i){1,2,3,0});
+#else
+#ifdef __AVX2__
+ return _mm256_permute4x64_pd(x,1+2*4+3*16+0*64);
+#else
+ __m256d s = _mm256_permute2f128_pd(x,x,1);
+ return _mm256_shuffle_pd(x,s,5);
+#endif
+#endif
+ }
+ static inline __m256d avx_right(__m256d x){
+#if 0
+ return __builtin_shuffle(x,(__m256i){3,0,1,2});
+#else
+#ifdef __AVX2__
+ return _mm256_permute4x64_pd(x,3+0*4+1*16+2*64);
+#else
+ __m256d s = _mm256_permute2f128_pd(x,x,1);
+ return _mm256_shuffle_pd(s,x,5);
+#endif
+#endif
+ }
+ static inline double avx_altprod(__m256d x, __m256d y){
+ __m256d p=x*y;
+ __m256d z=_mm256_hsub_pd(p,p);
+ return z[0]+z[2];
+ }
+ public:
+ static double
+ determinant_of_vectors(Vector a, Vector b, Vector c, Vector d) {
+ __m256d x=a*avx_left(b)-avx_left(a)*b;
+ __m256d yy=a*avx_sym(b);
+ __m256d y=yy-avx_sym(yy);
+ __m256d z0=x*avx_sym(c);
+ __m256d z1=avx_left(x)*c;
+ __m256d z2=y*avx_left(c);
+ __m256d z=z0+z1-z2;
+ return avx_altprod(z,avx_right(d));
+ }
+ static CGAL::Sign
+ sign_of_determinant_of_vectors(Vector a, Vector b, Vector c, Vector d) {
+ return CGAL::sign(determinant_of_vectors(a,b,c,d));
+ }
+
+ private:
+ static inline __m256d avx3_right(__m256d x){
+#if 0
+ return __builtin_shuffle(x,(__m256i){2,0,1,3}); // can replace 3 with anything
+#else
+#ifdef __AVX2__
+ return _mm256_permute4x64_pd(x,2+0*4+1*16+3*64);
+#else
+ __m256d s = _mm256_permute2f128_pd(x,x,1);
+ return _mm256_shuffle_pd(s,x,12);
+#endif
+#endif
+ }
+ public:
+ static inline double dot_product_omit_last(__m256d x, __m256d y){
+ __m256d p=x*y;
+ __m128d q=_mm256_extractf128_pd(p,0);
+ double z=_mm_hadd_pd(q,q)[0];
+ return z+p[2];
+ }
+ // Note: without AVX2, is it faster than the scalar computation?
+ static double
+ determinant_of_vectors_omit_last(Vector a, Vector b, Vector c) {
+ __m256d x=a*avx3_right(b)-avx3_right(a)*b;
+ return dot_product_omit_last(c,avx3_right(x));
+ }
+ static CGAL::Sign
+ sign_of_determinant_of_vectors_omit_last(Vector a, Vector b, Vector c) {
+ return CGAL::sign(determinant_of_vectors_omit_last(a,b,c));
+ }
+
+ };
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h
new file mode 100644
index 00000000..b8efbe28
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h
@@ -0,0 +1,76 @@
+// 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_VECTOR_DET_ITER_PTS_ITER_VEC_H
+#define CGAL_VECTOR_DET_ITER_PTS_ITER_VEC_H
+#include <functional>
+#include <CGAL/transforming_iterator.h>
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Dimension.h>
+
+namespace CGAL {
+
+template <class LA, class Dim_=typename LA::Dimension,
+ class Max_dim_=typename LA::Max_dimension,
+ bool = LA::template Property<Has_determinant_of_iterator_to_points_tag>::value,
+ bool = LA::template Property<Has_determinant_of_iterator_to_vectors_tag>::value>
+struct Add_determinant_of_iterator_to_points_from_iterator_to_vectors : LA {
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_points_from_iterator_to_vectors<LA2> Other;
+ };
+};
+
+template <class LA, class Dim_,class Max_dim_>
+struct Add_determinant_of_iterator_to_points_from_iterator_to_vectors
+<LA, Dim_, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_points_from_iterator_to_vectors<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
+ boost::true_type {};
+
+ // TODO: use std::minus, boost::bind, etc
+ template<class T> struct Minus_fixed {
+ T const& a;
+ Minus_fixed(T const&a_):a(a_){}
+ T operator()(T const&b)const{return b-a;}
+ };
+ template<class Iter>
+ static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Minus_fixed<Vector> f(a);
+ return LA::determinant_of_iterator_to_vectors(make_transforming_iterator(first,f),make_transforming_iterator(end,f));
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Minus_fixed<Vector> f(a);
+ return LA::sign_of_determinant_of_iterator_to_vectors(make_transforming_iterator(first,f),make_transforming_iterator(end,f));
+ }
+};
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_points.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_points.h
new file mode 100644
index 00000000..71a31d81
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_points.h
@@ -0,0 +1,211 @@
+// 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_VECTOR_DET_ITER_PTS_PTS_H
+#define CGAL_VECTOR_DET_ITER_PTS_PTS_H
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Dimension.h>
+
+namespace CGAL {
+
+template <class LA, class Dim_=typename LA::Dimension,
+ class Max_dim_=typename LA::Max_dimension,
+ bool = LA::template Property<Has_determinant_of_iterator_to_points_tag>::value,
+ bool = LA::template Property<Has_determinant_of_points_tag>::value>
+struct Add_determinant_of_iterator_to_points_from_points : LA {
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
+ };
+};
+
+//FIXME: Use variadics and boost so it works in any dimension.
+template <class LA, class Max_dim_>
+struct Add_determinant_of_iterator_to_points_from_points
+<LA, Dimension_tag<2>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
+ boost::true_type {};
+
+ template<class Iter>
+ static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; CGAL_assertion(++first==end);
+ return LA::determinant_of_points(a,b,c);
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; CGAL_assertion(++first==end);
+ return LA::sign_of_determinant_of_points(a,b,c);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_iterator_to_points_from_points
+<LA, Dimension_tag<3>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
+ boost::true_type {};
+
+ template<class Iter>
+ static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; CGAL_assertion(++first==end);
+ return LA::determinant_of_points(a,b,c,d);
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; CGAL_assertion(++first==end);
+ return LA::sign_of_determinant_of_points(a,b,c,d);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_iterator_to_points_from_points
+<LA, Dimension_tag<4>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
+ boost::true_type {};
+
+ template<class Iter>
+ static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; ++first;
+ Vector const&e=*first; CGAL_assertion(++first==end);
+ return LA::determinant_of_points(a,b,c,d,e);
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; ++first;
+ Vector const&e=*first; CGAL_assertion(++first==end);
+ return LA::sign_of_determinant_of_points(a,b,c,d,e);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_iterator_to_points_from_points
+<LA, Dimension_tag<5>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
+ boost::true_type {};
+
+ template<class Iter>
+ static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; ++first;
+ Vector const&e=*first; ++first;
+ Vector const&f=*first; CGAL_assertion(++first==end);
+ return LA::determinant_of_points(a,b,c,d,e,f);
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; ++first;
+ Vector const&e=*first; ++first;
+ Vector const&f=*first; CGAL_assertion(++first==end);
+ return LA::sign_of_determinant_of_points(a,b,c,d,e,f);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_iterator_to_points_from_points
+<LA, Dimension_tag<6>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
+ boost::true_type {};
+
+ template<class Iter>
+ static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; ++first;
+ Vector const&e=*first; ++first;
+ Vector const&f=*first; ++first;
+ Vector const&g=*first; CGAL_assertion(++first==end);
+ return LA::determinant_of_points(a,b,c,d,e,f,g);
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; ++first;
+ Vector const&e=*first; ++first;
+ Vector const&f=*first; ++first;
+ Vector const&g=*first; CGAL_assertion(++first==end);
+ return LA::sign_of_determinant_of_points(a,b,c,d,e,f,g);
+ }
+};
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_vectors_from_vectors.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_vectors_from_vectors.h
new file mode 100644
index 00000000..f096d6c7
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_vectors_from_vectors.h
@@ -0,0 +1,201 @@
+// 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_VECTOR_DET_ITER_VEC_VEC_H
+#define CGAL_VECTOR_DET_ITER_VEC_VEC_H
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Dimension.h>
+
+namespace CGAL {
+
+template <class LA, class Dim_=typename LA::Dimension,
+ class Max_dim_=typename LA::Max_dimension,
+ bool = LA::template Property<Has_determinant_of_iterator_to_vectors_tag>::value,
+ bool = LA::template Property<Has_determinant_of_vectors_tag>::value>
+struct Add_determinant_of_iterator_to_vectors_from_vectors : LA {
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
+ };
+};
+
+//FIXME: Use variadics and boost so it works in any dimension.
+template <class LA, class Max_dim_>
+struct Add_determinant_of_iterator_to_vectors_from_vectors
+<LA, Dimension_tag<2>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_vectors_tag, D> :
+ boost::true_type {};
+
+ template<class Iter>
+ static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; CGAL_assertion(++first==end);
+ return LA::determinant_of_vectors(a,b);
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; CGAL_assertion(++first==end);
+ return LA::sign_of_determinant_of_vectors(a,b);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_iterator_to_vectors_from_vectors
+<LA, Dimension_tag<3>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_vectors_tag, D> :
+ boost::true_type {};
+
+ template<class Iter>
+ static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; CGAL_assertion(++first==end);
+ return LA::determinant_of_vectors(a,b,c);
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; CGAL_assertion(++first==end);
+ return LA::sign_of_determinant_of_vectors(a,b,c);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_iterator_to_vectors_from_vectors
+<LA, Dimension_tag<4>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_vectors_tag, D> :
+ boost::true_type {};
+
+ template<class Iter>
+ static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; CGAL_assertion(++first==end);
+ return LA::determinant_of_vectors(a,b,c,d);
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; CGAL_assertion(++first==end);
+ return LA::sign_of_determinant_of_vectors(a,b,c,d);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_iterator_to_vectors_from_vectors
+<LA, Dimension_tag<5>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_vectors_tag, D> :
+ boost::true_type {};
+
+ template<class Iter>
+ static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; ++first;
+ Vector const&e=*first; CGAL_assertion(++first==end);
+ return LA::determinant_of_vectors(a,b,c,d,e);
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; ++first;
+ Vector const&e=*first; CGAL_assertion(++first==end);
+ return LA::sign_of_determinant_of_vectors(a,b,c,d,e);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_iterator_to_vectors_from_vectors
+<LA, Dimension_tag<6>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_iterator_to_vectors_tag, D> :
+ boost::true_type {};
+
+ template<class Iter>
+ static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; ++first;
+ Vector const&e=*first; ++first;
+ Vector const&f=*first; CGAL_assertion(++first==end);
+ return LA::determinant_of_vectors(a,b,c,d,e,f);
+ }
+ template<class Iter>
+ static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
+ Vector const&a=*first; ++first;
+ Vector const&b=*first; ++first;
+ Vector const&c=*first; ++first;
+ Vector const&d=*first; ++first;
+ Vector const&e=*first; ++first;
+ Vector const&f=*first; CGAL_assertion(++first==end);
+ return LA::sign_of_determinant_of_vectors(a,b,c,d,e,f);
+ }
+};
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_points_from_vectors.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_points_from_vectors.h
new file mode 100644
index 00000000..7ddb73c3
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_points_from_vectors.h
@@ -0,0 +1,164 @@
+// 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_VECTOR_DETPTS_H
+#define CGAL_VECTOR_DETPTS_H
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Dimension.h>
+
+namespace CGAL {
+
+template <class LA, class Dim_=typename LA::Dimension,
+ class Max_dim_=typename LA::Max_dimension,
+ bool = LA::template Property<Has_determinant_of_points_tag>::value,
+ bool = LA::template Property<Has_determinant_of_vectors_tag>::value
+ && LA::template Property<Has_vector_plus_minus_tag>::value>
+struct Add_determinant_of_points_from_vectors_and_minus : LA {
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
+ };
+};
+
+//FIXME: Use variadics and boost so it works in any dimension.
+template <class LA, class Max_dim_>
+struct Add_determinant_of_points_from_vectors_and_minus
+<LA, Dimension_tag<2>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_points_tag, D> :
+ boost::true_type {};
+
+ static NT determinant_of_points(Vector const&a, Vector const&b,
+ Vector const&c){
+ return LA::determinant_of_vectors(b-a,c-a);
+ }
+ static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b,
+ Vector const&c){
+ return LA::sign_of_determinant_of_vectors(b-a,c-a);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_points_from_vectors_and_minus
+<LA, Dimension_tag<3>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_points_tag, D> :
+ boost::true_type {};
+
+ static NT determinant_of_points(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d){
+ return LA::determinant_of_vectors(b-a,c-a,d-a);
+ }
+ static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d){
+ return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_points_from_vectors_and_minus
+<LA, Dimension_tag<4>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_points_tag, D> :
+ boost::true_type {};
+
+ static NT determinant_of_points(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e){
+ return LA::determinant_of_vectors(b-a,c-a,d-a,e-a);
+ }
+ static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e){
+ return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a,e-a);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_points_from_vectors_and_minus
+<LA, Dimension_tag<5>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_points_tag, D> :
+ boost::true_type {};
+
+ static NT determinant_of_points(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e, Vector const&f){
+ return LA::determinant_of_vectors(b-a,c-a,d-a,e-a,f-a);
+ }
+ static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e, Vector const&f){
+ return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a,e-a,f-a);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct Add_determinant_of_points_from_vectors_and_minus
+<LA, Dimension_tag<6>, Max_dim_, false, true> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<Has_determinant_of_points_tag, D> :
+ boost::true_type {};
+
+ static NT determinant_of_points(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e, Vector const&f,
+ Vector const&g){
+ return LA::determinant_of_vectors(b-a,c-a,d-a,e-a,f-a,g-a);
+ }
+ static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e, Vector const&f,
+ Vector const&g){
+ return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a,e-a,f-a,g-a);
+ }
+};
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim.h
new file mode 100644
index 00000000..64eafe69
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim.h
@@ -0,0 +1,58 @@
+// 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_VECTOR_DETVEC_SMALL_H
+#define CGAL_VECTOR_DETVEC_SMALL_H
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/determinant_of_vectors.h>
+
+#define CGAL_ALLOWED_INCLUSION 1
+
+#define CGAL_CLASS Add_determinant_of_vectors_small_dim
+#define CGAL_TAG Has_determinant_of_vectors_tag
+#define CGAL_FUNC determinant_of_vectors
+#define CGAL_SIGN_FUNC sign_of_determinant_of_vectors
+#define CGAL_SHIFT 0
+
+#include <CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h>
+
+#undef CGAL_CLASS
+#undef CGAL_TAG
+#undef CGAL_FUNC
+#undef CGAL_SIGN_FUNC
+#undef CGAL_SHIFT
+
+#define CGAL_CLASS Add_determinant_of_vectors_omit_last_small_dim
+#define CGAL_TAG Has_determinant_of_vectors_omit_last_tag
+#define CGAL_FUNC determinant_of_vectors_omit_last
+#define CGAL_SIGN_FUNC sign_of_determinant_of_vectors_omit_last
+#define CGAL_SHIFT 1
+
+#include <CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h>
+
+#undef CGAL_CLASS
+#undef CGAL_TAG
+#undef CGAL_FUNC
+#undef CGAL_SIGN_FUNC
+#undef CGAL_SHIFT
+
+#undef CGAL_ALLOWED_INCLUSION
+
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h
new file mode 100644
index 00000000..b4856742
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h
@@ -0,0 +1,164 @@
+// 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_ALLOWED_INCLUSION
+#error Must not include this header directly
+#endif
+#if !defined(CGAL_TAG) \
+ || ! defined(CGAL_CLASS) \
+ || ! defined(CGAL_FUNC) \
+ || ! defined(CGAL_SIGN_FUNC) \
+ || ! defined(CGAL_SHIFT)
+
+#error Forgot one macro
+#endif
+
+namespace CGAL {
+
+template <class LA, class Dim_=typename LA::Dimension,
+ class Max_dim_=typename LA::Max_dimension,
+ bool=LA::template Property<CGAL_TAG>::value>
+struct CGAL_CLASS : LA {
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef CGAL_CLASS<LA2> Other;
+ };
+};
+
+template <class LA, class Max_dim_>
+struct CGAL_CLASS
+<LA, Dimension_tag<2+CGAL_SHIFT>, Max_dim_, false> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef CGAL_CLASS<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<CGAL_TAG, D> :
+ boost::true_type {};
+
+ static NT CGAL_FUNC(Vector const&a, Vector const&b){
+ return CGAL::determinant_of_vectors<NT>(a,b);
+ }
+ template <class V1, class V2>
+ static Sign CGAL_SIGN_FUNC(V1 const&a, V2 const&b){
+ return CGAL::sign_of_determinant_of_vectors<NT>(a,b);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct CGAL_CLASS
+<LA, Dimension_tag<3+CGAL_SHIFT>, Max_dim_, false> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef CGAL_CLASS<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<CGAL_TAG, D> :
+ boost::true_type {};
+
+ static NT CGAL_FUNC(Vector const&a, Vector const&b,
+ Vector const&c){
+ return CGAL::determinant_of_vectors<NT>(a,b,c);
+ }
+ static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b,
+ Vector const&c){
+ return CGAL::sign_of_determinant_of_vectors<NT>(a,b,c);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct CGAL_CLASS
+<LA, Dimension_tag<4+CGAL_SHIFT>, Max_dim_, false> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef CGAL_CLASS<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<CGAL_TAG, D> :
+ boost::true_type {};
+
+ static NT CGAL_FUNC(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d){
+ return CGAL::determinant_of_vectors<NT>(a,b,c,d);
+ }
+ static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d){
+ return CGAL::sign_of_determinant_of_vectors<NT>(a,b,c,d);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct CGAL_CLASS
+<LA, Dimension_tag<5+CGAL_SHIFT>, Max_dim_, false> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef CGAL_CLASS<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<CGAL_TAG, D> :
+ boost::true_type {};
+
+ static NT CGAL_FUNC(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e){
+ return CGAL::determinant_of_vectors<NT>(a,b,c,d,e);
+ }
+ static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e){
+ return CGAL::sign_of_determinant_of_vectors<NT>(a,b,c,d,e);
+ }
+};
+
+template <class LA, class Max_dim_>
+struct CGAL_CLASS
+<LA, Dimension_tag<6+CGAL_SHIFT>, Max_dim_, false> : LA {
+ typedef typename LA::NT NT;
+ typedef typename LA::Vector Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef typename LA::template Rebind_dimension<D2,D3> LA2;
+ typedef CGAL_CLASS<LA2> Other;
+ };
+ template<class P,class=void> struct Property : LA::template Property<P> {};
+ template<class D> struct Property<CGAL_TAG, D> :
+ boost::true_type {};
+
+ static NT CGAL_FUNC(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e, Vector const&f){
+ return CGAL::determinant_of_vectors<NT>(a,b,c,d,e,f);
+ }
+ static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e, Vector const&f){
+ return CGAL::sign_of_determinant_of_vectors<NT>(a,b,c,d,e,f);
+ }
+};
+
+}
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/mix.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/mix.h
new file mode 100644
index 00000000..d4cfeeb1
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/mix.h
@@ -0,0 +1,46 @@
+// 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_KD_MIX_VECTOR_H
+#define CGAL_KD_MIX_VECTOR_H
+#include <CGAL/Dimension.h>
+namespace CGAL {
+
+template <class Static_, class Dynamic_, class NT_ ,class Dim_, class Max_dim_ = Dim_>
+struct Mix_vector
+: Dynamic_::template Rebind_dimension<Dim_, Max_dim_>::Other
+{
+ template <class D2, class D3 = D2>
+ struct Rebind_dimension {
+ typedef Mix_vector<Static_, Dynamic_, NT_, D2, D3> Other;
+ };
+};
+
+template <class Static_, class Dynamic_, class NT_, int d, class Max_dim_>
+struct Mix_vector<Static_, Dynamic_, NT_, Dimension_tag<d>, Max_dim_>
+: Static_::template Rebind_dimension<Dimension_tag<d>, Max_dim_>::Other
+{
+ template <class D2, class D3 = D2>
+ struct Rebind_dimension {
+ typedef Mix_vector<Static_, Dynamic_, NT_, D2, D3> Other;
+ };
+};
+}
+#endif
+
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/sse2.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/sse2.h
new file mode 100644
index 00000000..2a75385c
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/sse2.h
@@ -0,0 +1,145 @@
+// 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_VECTOR_SSE2_H
+#define CGAL_VECTOR_SSE2_H
+
+// Check what needs adapting for clang, intel and microsoft
+#if !defined __SSE2__ || (__GNUC__ * 100 + __GNUC_MINOR__ < 408)
+#error Requires SSE2 and gcc 4.8+
+#endif
+#include <x86intrin.h> // FIXME: other platforms call it differently
+
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/enum.h> // CGAL::Sign
+#include <CGAL/number_utils.h> // CGAL::sign
+
+
+
+namespace CGAL {
+
+ struct Sse_vector_2 {
+ typedef double NT;
+ typedef Dimension_tag<2> Dimension;
+ typedef Dimension_tag<2> Max_dimension;
+ // No Rebind_dimension, this is a building block
+ template<class,bool=true> struct Property : boost::false_type {};
+ template<bool b> struct Property<Has_vector_plus_minus_tag,b>
+ : boost::true_type {};
+ /* MAYBE?
+ template<bool b> struct Property<Has_vector_scalar_ops_tag,b>
+ : boost::true_type {};
+ */
+ template<bool b> struct Property<Has_determinant_of_vectors_tag,b>
+ : boost::true_type {};
+ template<bool b> struct Property<Has_dot_product_tag,b>
+ : boost::true_type {};
+
+ typedef __m128d Vector;
+ struct Construct_vector {
+ struct Dimension {
+ // Initialize with NaN?
+ Vector operator()(unsigned d) const {
+ CGAL_assertion(d==2);
+ return Vector();
+ }
+ };
+
+ struct Iterator {
+ template<typename Iter>
+ Vector operator()(unsigned d,Iter const& f,Iter const& e) const {
+ CGAL_assertion(d==2);
+ double x0 = *f;
+ double x1 = *++f;
+ CGAL_assertion(++f==e);
+ Vector a = { x0, x1 };
+ return a;
+ }
+ };
+
+ struct Iterator_and_last {
+ template<typename Iter,typename T>
+ Vector operator()(unsigned d,Iter const& f,Iter const& e,double t) const {
+ CGAL_assertion(d==2);
+ Vector a = { *f, t };
+ CGAL_assertion(++f==e);
+ return a;
+ }
+ };
+
+ struct Values {
+ Vector operator()(double a,double b) const {
+ Vector r = { a, b };
+ return r;
+ }
+ };
+
+ struct Values_divide {
+ Vector operator()(double h,double a,double b) const {
+ // {a,b}/{h,h} is probably slower
+ Vector r = { a/h, b/h };
+ return r;
+ }
+ };
+ };
+
+ typedef double const* Vector_const_iterator;
+ static inline Vector_const_iterator vector_begin(Vector const&a){
+ return (Vector_const_iterator)(&a);
+ }
+ static inline Vector_const_iterator vector_end(Vector const&a){
+ return (Vector_const_iterator)(&a)+2;
+ }
+ static inline unsigned size_of_vector(Vector){
+ return 2;
+ }
+ public:
+
+ static double determinant_of_vectors(Vector a, Vector b) {
+ __m128d c = _mm_shuffle_pd (b, b, 1); // b1, b0
+ __m128d d = a * c; // a0*b1, a1*b0
+#ifdef __SSE3__
+ __m128d e = _mm_hsub_pd (d, d);
+ return e[0];
+#else
+ return d[0]-d[1];
+#endif
+ }
+ static CGAL::Sign sign_of_determinant_of_vectors(Vector a, Vector b) {
+ return CGAL::sign(determinant_of_vectors(a,b));
+ }
+
+ static double dot_product(Vector a,Vector b){
+#ifdef __SSE4_1__
+ return _mm_dp_pd (a, b, 1+16+32)[0];
+#else
+ __m128d p = a * b;
+#if defined __SSE3__
+ __m128d s = _mm_hadd_pd (p, p);
+ return s[0];
+#else
+ return p[0]+p[1];
+#endif
+#endif
+ };
+ };
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/v2int.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/v2int.h
new file mode 100644
index 00000000..b85a3734
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/v2int.h
@@ -0,0 +1,181 @@
+// 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_VECTOR_2INT_H
+#define CGAL_VECTOR_2INT_H
+
+#include <stdint.h>
+#include <cmath>
+#include <CGAL/array.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/enum.h>
+#include <CGAL/number_utils.h>
+#include <CGAL/NT_converter.h>
+#include <CGAL/transforming_iterator.h>
+#include <CGAL/determinant_of_vectors.h>
+#include <CGAL/NewKernel_d/functor_tags.h>
+
+
+// What are the pros and cons of having NT be int vs double?
+
+namespace CGAL {
+ struct Vector_2_int_prop1 {
+ typedef double NT; // try lying a bit
+ typedef int32_t NT1; // what is really stored
+ typedef int32_t NT1b; // slightly longer
+ typedef int_fast64_t NT2; // longer type for computations
+ typedef int_fast64_t NT2b; // slightly longer
+ bool check_limits(int32_t x){return std::abs(x)<(1<<30);}
+ // TODO: find nice bounds
+ };
+#ifdef __SIZEOF_INT128__
+ struct Vector_2_int_prop2 {
+ typedef double NT;
+ typedef int32_t NT1;
+ typedef int_fast64_t NT1b;
+ typedef int_fast64_t NT2;
+ typedef __int128 NT2b;
+ bool check_limits(int32_t){return true;}
+ // take a template/int64_t input and still check the limits?
+ };
+ struct Vector_2_int_prop3 {
+ typedef long double NT;
+ typedef int64_t NT1;
+ typedef int64_t NT1b;
+ typedef __int128 NT2;
+ typedef __int128 NT2b;
+ enum { has_limit=true };
+ bool check_limits(int32_t x){return std::abs(x)<(1L<<62);}
+ // TODO: find nice bounds
+ };
+#endif
+
+ template<class Prop=Vector_2_int_prop1>
+ struct Vector_2_int : Prop {
+ using typename Prop::NT;
+ using typename Prop::NT1;
+ using typename Prop::NT1b;
+ using typename Prop::NT2;
+ using typename Prop::NT2b;
+ using Prop::check_limits;
+
+ typedef Dimension_tag<2> Dimension;
+ typedef Dimension_tag<2> Max_dimension;
+ // No Rebind_dimension, this is a building block
+ template<class,bool=true> struct Property : boost::false_type {};
+ //template<bool b> struct Property<Has_vector_plus_minus_tag,b>
+ // : boost::true_type {};
+ template<bool b> struct Property<Has_determinant_of_vectors_tag,b>
+ : boost::true_type {};
+ //template<bool b> struct Property<Has_determinant_of_points_tag,b>
+ // : boost::true_type {};
+ // Advertise somehow that the sign_of_determinant* are exact?
+
+ typedef cpp0x::array<NT1,2> Vector;
+ struct Construct_vector {
+ struct Dimension {
+ Vector operator()(unsigned d) const {
+ CGAL_assertion(d==2);
+ return Vector();
+ }
+ };
+
+ // TODO (for all constructors): check that input fits in NT1...
+ struct Iterator {
+ template<typename Iter>
+ Vector operator()(unsigned d,Iter const& f,Iter const& e) const {
+ CGAL_assertion(d==2);
+ NT1 x0 = *f;
+ NT1 x1 = *++f;
+ CGAL_assertion (++f == e);
+ CGAL_assertion (check_limits(x0) && check_limits(x1));
+ Vector a = { x0, x1 };
+ return a;
+ }
+ };
+
+ struct Iterator_and_last {
+ template<typename Iter,typename T>
+ Vector operator()(unsigned d,Iter const& f,Iter const& e,double t) const {
+ CGAL_assertion(d==2);
+ NT1 x = *f;
+ CGAL_assertion (++f == e);
+ CGAL_assertion (check_limits(x) && check_limits(t));
+ Vector a = { x, t };
+ return a;
+ }
+ };
+
+ struct Values {
+ Vector operator()(NT1 a,NT1 b) const {
+ CGAL_assertion (check_limits(a) && check_limits(b));
+ Vector r = { a, b };
+ return r;
+ }
+ };
+
+ /*
+ // Maybe safer not to provide it
+ struct Values_divide {
+ Vector operator()(double h,double a,double b) const {
+ Vector r = { a/h, b/h };
+ return r;
+ }
+ };
+ */
+ };
+
+ // Since we lie about NT, be consistent about it
+ typedef transforming_iterator<NT_converter<NT1,NT>,NT1 const*> Vector_const_iterator;
+ static inline Vector_const_iterator vector_begin(Vector const&a){
+ return Vector_const_iterator(a.begin());
+ }
+ static inline Vector_const_iterator vector_end(Vector const&a){
+ return Vector_const_iterator(a.end());
+ }
+ static inline unsigned size_of_vector(Vector){
+ return 2;
+ }
+
+ // for unsigned NT1, check what changes to do.
+ // return NT or NT2?
+ static NT determinant_of_vectors(Vector a, Vector b) {
+ return CGAL::determinant_of_vectors<NT2>(a,b);
+ }
+ static CGAL::Sign sign_of_determinant_of_vectors(Vector a, Vector b) {
+ return CGAL::sign_of_determinant_of_vectors<NT2>(a,b);
+ }
+
+ static NT determinant_of_points(Vector a, Vector b, Vector c) {
+ // could be faster to convert to NT directly
+ NT1b a0=a[0]; NT1b a1=a[1];
+ NT1b x0=b[0]-a0; NT1b x1=b[1]-a1;
+ NT1b y0=c[0]-a0; NT1b y1=c[1]-a1;
+ return CGAL::determinant<NT>(x0,x1,y0,y1);
+ }
+ static CGAL::Sign sign_of_determinant_of_points(Vector a, Vector b, Vector c) {
+ NT1b a0=a[0]; NT1b a1=a[1];
+ NT1b x0=b[0]-a0; NT1b x1=b[1]-a1;
+ NT2b y0=c[0]-a0; NT2b y1=c[1]-a1;
+ return CGAL::compare(x0*y1,x1*y0);
+ }
+ };
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Vector/vector.h b/include/gudhi_patches/CGAL/NewKernel_d/Vector/vector.h
new file mode 100644
index 00000000..f9cc4e3c
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Vector/vector.h
@@ -0,0 +1,167 @@
+// 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_VECTOR_VECTOR_H
+#define CGAL_VECTOR_VECTOR_H
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <CGAL/Dimension.h>
+#include <CGAL/NewKernel_d/utils.h>
+#include <vector>
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+namespace CGAL {
+
+//Derive from a class that doesn't depend on Dim, or still use Dim for checking?
+template<class NT_,class Dim_,class Max_dim_=Dim_> struct Vector_vector {
+ typedef NT_ NT;
+ typedef Dim_ Dimension;
+ typedef Max_dim_ Max_dimension;
+ typedef std::vector<NT> Vector;
+ template< class D2, class D3=D2 >
+ struct Rebind_dimension {
+ typedef Vector_vector< NT, D2, D3 > Other;
+ };
+ template<class> struct Property : boost::false_type {};
+
+ struct Construct_vector {
+ struct Dimension {
+ Vector operator()(int d) const {
+ return Vector(d);
+ }
+ };
+
+ struct Iterator {
+ template<typename Iter>
+ Vector operator()(int CGAL_assertion_code(d),Iter const& f,Iter const& e) const {
+ CGAL_assertion(d==std::distance(f,e));
+ return Vector(f,e);
+ }
+ };
+
+ // unneeded thanks to Iterator_and_last?
+#if 0
+ struct Iterator_add_one {
+ template<typename Iter>
+ Vector operator()(int CGAL_assertion_code(d),Iter const& f,Iter const& e) const {
+ CGAL_assertion(d==std::distance(f,e)+1);
+ Vector a;
+ a.reserve(d+1);
+ a.insert(a.end(),f,e);
+ a.push_back(1);
+ return a;
+ }
+ };
+#endif
+
+ struct Iterator_and_last {
+ template<typename Iter,typename T>
+ Vector operator()(int d,Iter const& f,Iter const& e,CGAL_FORWARDABLE(T) t) const {
+ CGAL_assertion(d==std::distance(f,e)+1);
+ Vector a;
+ a.reserve(d+1);
+ a.insert(a.end(),f,e);
+ a.push_back(CGAL_FORWARD(T,t));
+ return a;
+ }
+ };
+
+ // useless, use a transform_iterator?
+#if 0
+ struct Iterator_and_last_divide {
+ template<typename Iter,typename T>
+ Vector operator()(int d,Iter f,Iter const& e,T const&t) const {
+ CGAL_assertion(d==std::distance(f,e)+1);
+ Vector a;
+ a.reserve(d+1);
+ for(;f!=e;++f){
+ a.push_back(*f/t);
+ }
+ return a;
+ }
+ };
+#endif
+
+ struct Values {
+#ifdef CGAL_CXX11
+ template<class...U>
+ Vector operator()(U&&...u) const {
+ //TODO: check the right number of {}, g++ accepts one and two
+ Vector a={forward_safe<NT,U>(u)...};
+ return a;
+ }
+#else
+
+#define CGAL_VAR(Z,N,_) a.push_back(t##N);
+#define CGAL_CODE(Z,N,_) Vector operator()(BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
+ Vector a; \
+ a.reserve(N); \
+ BOOST_PP_REPEAT(N,CGAL_VAR,) \
+ return a; \
+}
+BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ )
+#undef CGAL_CODE
+#undef CGAL_VAR
+
+#endif
+ };
+
+ struct Values_divide {
+#ifdef CGAL_CXX11
+ template<class H,class...U>
+ Vector operator()(H const&h,U&&...u) const {
+ //TODO: do we want to cast at some point?
+ //e.g. to avoid 1/2 in integers
+ // ==> use Rational_traits<NT>().make_rational(x,y) ?
+ Vector a={Rational_traits<NT>().make_rational(std::forward<U>(u),h)...};
+ return a;
+ }
+#else
+
+#define CGAL_VAR(Z,N,_) a.push_back(Rational_traits<NT>().make_rational( t##N ,h));
+#define CGAL_CODE(Z,N,_) template<class H> Vector \
+ operator()(H const&h, BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
+ Vector a; \
+ a.reserve(N); \
+ BOOST_PP_REPEAT(N,CGAL_VAR,) \
+ return a; \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ )
+#undef CGAL_CODE
+#undef CGAL_VAR
+
+#endif
+ };
+ };
+ typedef typename Vector::const_iterator Vector_const_iterator;
+ static Vector_const_iterator vector_begin(Vector const&a){
+ return a.begin();
+ }
+ static Vector_const_iterator vector_end(Vector const&a){
+ return a.end();
+ }
+ static int size_of_vector(Vector const&a){
+ return (int)a.size();
+ }
+};
+
+
+}
+#endif
+
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h
new file mode 100644
index 00000000..44e9aa96
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h
@@ -0,0 +1,305 @@
+// 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_KERNEL_D_CARTESIAN_WRAP_H
+#define CGAL_KERNEL_D_CARTESIAN_WRAP_H
+
+#include <CGAL/basic.h>
+#include <CGAL/is_iterator.h>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4003) // not enough actual parameters for macro 'BOOST_PP_EXPAND_I'
+ // http://lists.boost.org/boost-users/2014/11/83291.php
+#endif
+#include <CGAL/NewKernel_d/Wrapper/Point_d.h>
+#include <CGAL/NewKernel_d/Wrapper/Vector_d.h>
+#include <CGAL/NewKernel_d/Wrapper/Segment_d.h>
+#include <CGAL/NewKernel_d/Wrapper/Sphere_d.h>
+#include <CGAL/NewKernel_d/Wrapper/Hyperplane_d.h>
+#include <CGAL/NewKernel_d/Wrapper/Weighted_point_d.h>
+
+#include <CGAL/NewKernel_d/Wrapper/Ref_count_obj.h>
+
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/contains.hpp>
+#include <boost/mpl/vector.hpp>
+
+//TODO: do we want to store the kernel ref in the Object wrappers? It would allow for additions and operator[] and things like that to work, but objects would still need to be created by functors.
+
+namespace CGAL {
+namespace internal {
+BOOST_MPL_HAS_XXX_TRAIT_DEF(Is_wrapper)
+template<class T,bool=has_Is_wrapper<T>::value> struct Is_wrapper {
+ enum { value=false };
+ typedef Tag_false type;
+};
+template<class T> struct Is_wrapper<T,true> {
+ typedef typename T::Is_wrapper type;
+ enum { value=type::value };
+};
+
+template<class T,bool=is_iterator_type<T,std::input_iterator_tag>::value> struct Is_wrapper_iterator {
+ enum { value=false };
+ typedef Tag_false type;
+};
+template<class T> struct Is_wrapper_iterator<T,true> :
+ Is_wrapper<typename std::iterator_traits<typename CGAL::decay<T>::type>::value_type>
+{ };
+
+struct Forward_rep {
+//TODO: make a good C++0X version with perfect forwarding
+//#ifdef CGAL_CXX11
+//template <class T,class=typename std::enable_if<!Is_wrapper<typename std::decay<T>::type>::value&&!Is_wrapper_iterator<typename std::decay<T>::type>::value>::type>
+//T&& operator()(typename std::remove_reference<T>::type&& t) const {return static_cast<T&&>(t);};
+//template <class T,class=typename std::enable_if<!Is_wrapper<typename std::decay<T>::type>::value&&!Is_wrapper_iterator<typename std::decay<T>::type>::value>::type>
+//T&& operator()(typename std::remove_reference<T>::type& t) const {return static_cast<T&&>(t);};
+//
+//template <class T,class=typename std::enable_if<Is_wrapper<typename std::decay<T>::type>::value>::type>
+//typename Type_copy_cvref<T,typename std::decay<T>::type::Rep>::type&&
+//operator()(T&& t) const {
+// return static_cast<typename Type_copy_cvref<T,typename std::decay<T>::type::Rep>::type&&>(t.rep());
+//};
+//
+//template <class T,class=typename std::enable_if<Is_wrapper_iterator<typename std::decay<T>::type>::value>::type>
+//transforming_iterator<Forward_rep,typename std::decay<T>::type>
+//operator()(T&& t) const {
+// return make_transforming_iterator(std::forward<T>(t),Forward_rep());
+//};
+//#else
+template <class T,bool=Is_wrapper<T>::value,bool=Is_wrapper_iterator<T>::value> struct result_;
+template <class T> struct result_<T,false,false>{typedef T const& type;};
+template <class T> struct result_<T,true,false>{typedef typename decay<T>::type::Rep const& type;};
+template <class T> struct result_<T,false,true>{typedef transforming_iterator<Forward_rep,typename decay<T>::type> type;};
+template<class> struct result;
+template<class T> struct result<Forward_rep(T)> : result_<T> {};
+
+template <class T> typename boost::disable_if<boost::mpl::or_<Is_wrapper<T>,Is_wrapper_iterator<T> >,T>::type const& operator()(T const& t) const {return t;}
+template <class T> typename boost::disable_if<boost::mpl::or_<Is_wrapper<T>,Is_wrapper_iterator<T> >,T>::type& operator()(T& t) const {return t;}
+
+template <class T> typename T::Rep const& operator()(T const& t, typename boost::enable_if<Is_wrapper<T> >::type* = 0) const {return t.rep();}
+
+template <class T> transforming_iterator<Forward_rep,typename boost::enable_if<Is_wrapper_iterator<T>,T>::type> operator()(T const& t) const {return make_transforming_iterator(t,Forward_rep());}
+//#endif
+};
+}
+
+template <class B, class K, class T, bool = Provides_type<B, T>::value>
+struct Map_wrapping_type : Get_type<B, T> {};
+#define CGAL_REGISTER_OBJECT_WRAPPER(X) \
+ template <class B, class K> \
+ struct Map_wrapping_type <B, K, X##_tag, true> { \
+ typedef Wrap::X##_d<K> type; \
+ }
+CGAL_REGISTER_OBJECT_WRAPPER(Point);
+CGAL_REGISTER_OBJECT_WRAPPER(Vector);
+CGAL_REGISTER_OBJECT_WRAPPER(Segment);
+CGAL_REGISTER_OBJECT_WRAPPER(Sphere);
+CGAL_REGISTER_OBJECT_WRAPPER(Hyperplane);
+CGAL_REGISTER_OBJECT_WRAPPER(Weighted_point);
+#undef CGAL_REGISTER_OBJECT_WRAPPER
+
+// Note: this tends to be an all or nothing thing currently, wrapping
+// only some types breaks, probably because we don't check whether the
+// return type is indeed wrapped.
+template < typename Base_ , typename Derived_ = Default >
+struct Cartesian_wrap : public Base_
+{
+ CGAL_CONSTEXPR Cartesian_wrap(){}
+ CGAL_CONSTEXPR Cartesian_wrap(int d):Base_(d){}
+ typedef Base_ Kernel_base;
+ typedef Cartesian_wrap Self;
+ // TODO: pass the 2 types Self and Derived to the wrappers, they can use Self for most purposes and Derived only for Kernel_traits' typedef R.
+ typedef typename Default::Get<Derived_, Self>::type Derived;
+ // FIXME: The list doesn't belong here.
+ typedef boost::mpl::vector<Point_tag,Segment_tag,Sphere_tag,Vector_tag,Hyperplane_tag> Wrapped_list;
+
+ template <class T>
+ struct Type : Map_wrapping_type<Base_, Derived, T> {};
+
+ //Translate the arguments
+ template <class T, class D = void,
+ class=typename Get_functor_category<Derived,T>::type,
+ bool=Provides_functor<Kernel_base, T>::value,
+ bool=boost::mpl::contains<Wrapped_list,typename map_result_tag<T>::type>::type::value>
+ struct Functor {
+ typedef typename Get_functor<Kernel_base, T>::type B;
+ struct type {
+ B b;
+ type(){}
+ type(Self const&k):b(k){}
+ typedef typename B::result_type result_type;
+#ifdef CGAL_CXX11
+ template<class...U> result_type operator()(U&&...u)const{
+ return b(internal::Forward_rep()(u)...);
+ }
+#else
+#define CGAL_VAR(Z,N,_) internal::Forward_rep()(u##N)
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> result_type \
+ operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \
+ return b(BOOST_PP_ENUM(N,CGAL_VAR,)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+#undef CGAL_VAR
+// In case the last argument needs to be non-const. Fragile...
+#define CGAL_VAR(Z,N,_) internal::Forward_rep()(u##N)
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U),class V> result_type \
+ operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u),V&v)const{ \
+ return b(BOOST_PP_ENUM(N,CGAL_VAR,),internal::Forward_rep()(v)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1,8,CGAL_CODE,_)
+#undef CGAL_CODE
+#undef CGAL_VAR
+#endif
+ };
+ };
+
+ // Preserve the difference between Null_functor and nothing.
+ template <class T, class D, class C, bool b>
+ struct Functor <T, D, C, false, b>
+ : Get_functor <Kernel_base, T> {};
+
+ //Translate both the arguments and the result
+ //TODO: Check Is_wrapper instead of relying on map_result_tag?
+ template<class T,class D> struct Functor<T,D,Construct_tag,true,true> {
+ typedef typename Get_functor<Kernel_base, T>::type B;
+ struct type {
+ B b;
+ type(){}
+ type(Self const&k):b(k){}
+ typedef typename map_result_tag<T>::type result_tag;
+ // FIXME: Self or Derived?
+ typedef typename Get_type<Self,result_tag>::type result_type;
+#ifdef CGAL_CXX11
+ template<class...U> result_type operator()(U&&...u)const{
+ return result_type(Eval_functor(),b,internal::Forward_rep()(u)...);
+ }
+#else
+#define CGAL_VAR(Z,N,_) internal::Forward_rep()(u##N)
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> result_type \
+ operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \
+ return result_type(Eval_functor(),b,BOOST_PP_ENUM(N,CGAL_VAR,)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+#undef CGAL_VAR
+#endif
+ };
+ };
+
+};
+
+template < typename Base_ >
+struct Cartesian_refcount : public Base_
+{
+ CGAL_CONSTEXPR Cartesian_refcount(){}
+ CGAL_CONSTEXPR Cartesian_refcount(int d):Base_(d){}
+ typedef Base_ Kernel_base;
+ typedef Cartesian_refcount Self;
+
+ // FIXME: Use object_list, or a list passed as argument, or anything
+ // automatic.
+ template <class T, class=void> struct Type : Get_type<Base_, T> {};
+#define CGAL_Kernel_obj(X,Y) \
+ template <class D> struct Type<X##_tag, D> { typedef Ref_count_obj<Cartesian_refcount, X##_tag> type; };
+
+ CGAL_Kernel_obj(Point,point)
+ CGAL_Kernel_obj(Vector,vector)
+#undef CGAL_Kernel_obj
+
+ template<class T> struct Dispatch {
+ //typedef typename map_functor_type<T>::type f_t;
+ typedef typename map_result_tag<T>::type r_t;
+ enum {
+ is_nul = boost::is_same<typename Get_functor<Kernel_base, T>::type,Null_functor>::value,
+ ret_rcobj = boost::is_same<r_t,Point_tag>::value || boost::is_same<r_t,Vector_tag>::value
+ };
+ };
+
+ //Translate the arguments
+ template<class T,class D=void,bool=Dispatch<T>::is_nul,bool=Dispatch<T>::ret_rcobj> struct Functor {
+ typedef typename Get_functor<Kernel_base, T>::type B;
+ struct type {
+ B b;
+ type(){}
+ type(Self const&k):b(k){}
+ typedef typename B::result_type result_type;
+#ifdef CGAL_CXX11
+ template<class...U> result_type operator()(U&&...u)const{
+ return b(internal::Forward_rep()(u)...);
+ }
+#else
+ result_type operator()()const{
+ return b();
+ }
+#define CGAL_VAR(Z,N,_) internal::Forward_rep()(u##N)
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> result_type \
+ operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \
+ return b(BOOST_PP_ENUM(N,CGAL_VAR,)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+#undef CGAL_VAR
+#endif
+ };
+ };
+
+ //Translate both the arguments and the result
+ template<class T,class D,bool b> struct Functor<T,D,true,b> {
+ typedef Null_functor type;
+ };
+
+ template<class T,class D> struct Functor<T,D,false,true> {
+ typedef typename Get_functor<Kernel_base, T>::type B;
+ struct type {
+ B b;
+ type(){}
+ type(Self const&k):b(k){}
+ typedef typename map_result_tag<T>::type result_tag;
+ typedef typename Get_type<Self,result_tag>::type result_type;
+#ifdef CGAL_CXX11
+ template<class...U> result_type operator()(U&&...u)const{
+ return result_type(Eval_functor(),b,internal::Forward_rep()(u)...);
+ }
+#else
+ result_type operator()()const{
+ return result_type(Eval_functor(),b);
+ }
+#define CGAL_VAR(Z,N,_) internal::Forward_rep()(u##N)
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> result_type \
+ operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \
+ return result_type(Eval_functor(),b,BOOST_PP_ENUM(N,CGAL_VAR,)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+#undef CGAL_VAR
+#endif
+ };
+ };
+
+};
+
+} //namespace CGAL
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif // CGAL_KERNEL_D_CARTESIAN_WRAP_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Hyperplane_d.h b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Hyperplane_d.h
new file mode 100644
index 00000000..54fd50bd
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Hyperplane_d.h
@@ -0,0 +1,131 @@
+// 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_WRAPPER_HYPERPLANE_D_H
+#define CGAL_WRAPPER_HYPERPLANE_D_H
+
+#include <CGAL/representation_tags.h>
+#include <CGAL/assertions.h>
+#include <boost/type_traits.hpp>
+#include <CGAL/Kernel/Return_base_tag.h>
+#include <CGAL/Dimension.h>
+#ifndef CGAL_CXX11
+#include <boost/preprocessor/repetition.hpp>
+#endif
+#include <boost/utility/result_of.hpp>
+
+namespace CGAL {
+namespace Wrap {
+
+template <class R_>
+class Hyperplane_d : public Get_type<typename R_::Kernel_base, Hyperplane_tag>::type
+{
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename R_::Kernel_base Kbase;
+ typedef typename Get_type<R_, Vector_tag>::type Vector_;
+ typedef typename Get_functor<Kbase, Construct_ttag<Hyperplane_tag> >::type CHBase;
+ typedef typename Get_functor<Kbase, Orthogonal_vector_tag>::type OVBase;
+ typedef typename Get_functor<Kbase, Hyperplane_translation_tag>::type HTBase;
+
+ typedef Hyperplane_d Self;
+ CGAL_static_assertion((boost::is_same<Self, typename Get_type<R_, Hyperplane_tag>::type>::value));
+
+public:
+
+ typedef Tag_true Is_wrapper;
+ typedef typename R_::Default_ambient_dimension Ambient_dimension;
+ typedef typename Increment_dimension<Ambient_dimension,-1>::type Feature_dimension;
+
+ typedef typename Get_type<Kbase, Hyperplane_tag>::type Rep;
+
+ const Rep& rep() const
+ {
+ return *this;
+ }
+
+ Rep& rep()
+ {
+ return *this;
+ }
+
+ typedef R_ R;
+
+#ifdef CGAL_CXX11
+ template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Hyperplane_d> >::value>::type> explicit Hyperplane_d(U&&...u)
+ : Rep(CHBase()(std::forward<U>(u)...)){}
+
+// // called from Construct_point_d
+// template<class...U> explicit Point_d(Eval_functor&&,U&&...u)
+// : Rep(Eval_functor(), std::forward<U>(u)...){}
+ template<class F,class...U> explicit Hyperplane_d(Eval_functor&&,F&&f,U&&...u)
+ : Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
+
+#if 0
+ // the new standard may make this necessary
+ Point_d(Point_d const&)=default;
+ Point_d(Point_d &);//=default;
+ Point_d(Point_d &&)=default;
+#endif
+
+ // try not to use these
+ Hyperplane_d(Rep const& v) : Rep(v) {}
+ Hyperplane_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
+ Hyperplane_d(Rep&& v) : Rep(std::move(v)) {}
+
+#else
+
+ Hyperplane_d() : Rep(CHBase()()) {}
+
+ Hyperplane_d(Rep const& v) : Rep(v) {} // try not to use it
+
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ explicit Hyperplane_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(CHBase()( \
+ BOOST_PP_ENUM_PARAMS(N,t))) {} \
+ \
+ template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Hyperplane_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
+ /*
+ template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
+ */
+
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+
+#endif
+
+ //TODO: if OVBase returns a reference to a base vector, cast it to a
+ //reference to a wrapper vector. Ugly but should be safe.
+ Vector_ orthogonal_vector()const{
+ return Vector_(Eval_functor(),OVBase(),rep());
+ }
+ FT_ translation()const{
+ return HTBase()(rep());
+ }
+
+
+};
+
+} //namespace Wrap
+} //namespace CGAL
+
+#endif // CGAL_WRAPPER_SPHERE_D_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Point_d.h b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Point_d.h
new file mode 100644
index 00000000..0718c947
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Point_d.h
@@ -0,0 +1,284 @@
+// 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_WRAPPER_POINT_D_H
+#define CGAL_WRAPPER_POINT_D_H
+
+#include <ostream>
+#include <CGAL/Origin.h>
+#include <CGAL/Kernel/mpl.h>
+#include <CGAL/representation_tags.h>
+#include <CGAL/assertions.h>
+#include <boost/type_traits.hpp>
+#include <CGAL/Kernel/Return_base_tag.h>
+#include <CGAL/Dimension.h>
+#ifndef CGAL_CXX11
+#include <boost/preprocessor/repetition.hpp>
+#endif
+#include <boost/utility/result_of.hpp>
+
+namespace CGAL {
+namespace Wrap {
+
+template <class R_>
+class Point_d : public Get_type<typename R_::Kernel_base, Point_tag>::type
+ // Deriving won't work if the point is just a __m256d.
+ // Test boost/std::is_class for instance
+{
+ typedef typename Get_type<R_, RT_tag>::type RT_;
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename R_::Kernel_base Kbase;
+ typedef typename Get_type<R_, Vector_tag>::type Vector_;
+ typedef typename Get_functor<Kbase, Construct_ttag<Point_tag> >::type CPBase;
+ typedef typename Get_functor<Kbase, Compute_point_cartesian_coordinate_tag>::type CCBase;
+ typedef typename Get_functor<Kbase, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CPI;
+
+
+ typedef Point_d Self;
+ CGAL_static_assertion((boost::is_same<Self, typename Get_type<R_, Point_tag>::type>::value));
+
+public:
+
+ typedef Tag_true Is_wrapper;
+ typedef typename R_::Default_ambient_dimension Ambient_dimension;
+ typedef Dimension_tag<0> Feature_dimension;
+
+ typedef typename Get_type<Kbase, Point_tag>::type Rep;
+ //typedef typename CGAL::decay<typename boost::result_of<CPI(Rep,Begin_tag)>::type>::type Cartesian_const_iterator;
+
+ const Rep& rep() const
+ {
+ return *this;
+ }
+
+ Rep& rep()
+ {
+ return *this;
+ }
+
+ typedef R_ R;
+
+#ifdef CGAL_CXX11
+ template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Point_d> >::value>::type> explicit Point_d(U&&...u)
+ : Rep(CPBase()(std::forward<U>(u)...)){}
+
+// // called from Construct_point_d
+// template<class...U> explicit Point_d(Eval_functor&&,U&&...u)
+// : Rep(Eval_functor(), std::forward<U>(u)...){}
+ template<class F,class...U> explicit Point_d(Eval_functor&&,F&&f,U&&...u)
+ : Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
+
+#if 0
+ // the new standard may make this necessary
+ Point_d(Point_d const&)=default;
+ Point_d(Point_d &);//=default;
+ Point_d(Point_d &&)=default;
+#endif
+
+ // try not to use these
+ Point_d(Rep const& v) : Rep(v) {}
+ Point_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
+ Point_d(Rep&& v) : Rep(std::move(v)) {}
+
+ // this one should be implicit
+ Point_d(Origin const& v)
+ : Rep(CPBase()(v)) {}
+ Point_d(Origin& v)
+ : Rep(CPBase()(v)) {}
+ Point_d(Origin&& v)
+ : Rep(CPBase()(std::move(v))) {}
+
+#else
+
+ Point_d() : Rep(CPBase()()) {}
+
+ Point_d(Rep const& v) : Rep(v) {} // try not to use it
+
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ explicit Point_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(CPBase()( \
+ BOOST_PP_ENUM_PARAMS(N,t))) {} \
+ \
+ template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Point_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
+ /*
+ template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
+ */
+
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+
+ // this one should be implicit
+ Point_d(Origin const& o)
+ : Rep(CPBase()(o)) {}
+
+#endif
+
+ typename boost::result_of<CCBase(Rep,int)>::type cartesian(int i)const{
+ return CCBase()(rep(),i);
+ }
+ typename boost::result_of<CCBase(Rep,int)>::type operator[](int i)const{
+ return CCBase()(rep(),i);
+ }
+
+ typename boost::result_of<CPI(Rep,Begin_tag)>::type cartesian_begin()const{
+ return CPI()(rep(),Begin_tag());
+ }
+
+ typename boost::result_of<CPI(Rep,End_tag)>::type cartesian_end()const{
+ return CPI()(rep(),End_tag());
+ }
+
+ int dimension() const {
+ typedef typename Get_functor<Kbase, Point_dimension_tag>::type PDBase;
+ return PDBase()(rep());
+ }
+
+ /*
+ Direction_d direction() const
+ {
+ return R().construct_direction_d_object()(*this);
+ }
+
+ Vector_d transform(const Aff_transformation_d &t) const
+ {
+ return t.transform(*this);
+ }
+
+ Vector_d operator/(const RT& c) const
+ {
+ return R().construct_divided_vector_d_object()(*this,c);
+ }
+
+ Vector_d operator/(const typename First_if_different<FT_,RT>::Type & c) const
+ {
+ return R().construct_divided_vector_d_object()(*this,c);
+ }
+
+ typename Qualified_result_of<typename R::Compute_x_3, Vector_3>::type
+ x() const
+ {
+ return R().compute_x_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_y_3, Vector_3>::type
+ y() const
+ {
+ return R().compute_y_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_z_3, Vector_3>::type
+ z() const
+ {
+ return R().compute_z_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_hx_3, Vector_3>::type
+ hx() const
+ {
+ return R().compute_hx_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_hy_3, Vector_3>::type
+ hy() const
+ {
+ return R().compute_hy_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_hz_3, Vector_3>::type
+ hz() const
+ {
+ return R().compute_hz_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_hw_3, Vector_3>::type
+ hw() const
+ {
+ return R().compute_hw_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_x_3, Vector_3>::type
+ cartesian(int i) const
+ {
+ CGAL_kernel_precondition( (i == 0) || (i == 1) || (i == 2) );
+ if (i==0) return x();
+ if (i==1) return y();
+ return z();
+ }
+
+ typename Qualified_result_of<typename R::Compute_hw_3, Vector_3>::type
+ homogeneous(int i) const
+ {
+ CGAL_kernel_precondition( (i >= 0) || (i <= 3) );
+ if (i==0) return hx();
+ if (i==1) return hy();
+ if (i==2) return hz();
+ return hw();
+ }
+
+ typename Qualified_result_of<typename R::Compute_squared_length_3, Vector_3>::type
+ squared_length() const
+ {
+ return R().compute_squared_length_3_object()(*this);
+ }
+*/
+};
+#if 0
+template <class R_> Point_d<R_>::Point_d(Point_d &)=default;
+#endif
+
+//TODO: IO
+
+template <class R_>
+std::ostream& operator <<(std::ostream& os, const Point_d<R_>& p)
+{
+ typedef typename R_::Kernel_base Kbase;
+ typedef typename Get_functor<Kbase, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CPI;
+ // Should just be "auto"...
+ typename CGAL::decay<typename boost::result_of<
+ CPI(typename Point_d<R_>::Rep,Begin_tag)
+ >::type>::type
+ b = p.cartesian_begin(),
+ e = p.cartesian_end();
+ os << p.dimension();
+ for(; b != e; ++b){
+ os << " " << *b;
+ }
+ return os;
+}
+
+//template <class R_>
+//Vector_d<R_> operator+(const Vector_d<R_>& v,const Vector_d<R_>& w) const
+//{
+// return typename R::template Construct<Sum_of_vectors_tag>::type()(v,w);
+//}
+//
+//template <class R_>
+//Vector_d<R_> operator-(const Vector_d<R_>& v,const Vector_d<R_>& w) const
+//{
+// return typename R::template Construct<Difference_of_vectors_tag>::type()(v,w);
+//}
+
+} //namespace Wrap
+} //namespace CGAL
+
+#endif // CGAL_WRAPPER_POINT_D_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Ref_count_obj.h b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Ref_count_obj.h
new file mode 100644
index 00000000..f33e14c0
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Ref_count_obj.h
@@ -0,0 +1,120 @@
+// 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_WRAPPER_REF_COUNT_OBJ_H
+#define CGAL_WRAPPER_REF_COUNT_OBJ_H
+
+#include <CGAL/Origin.h>
+#include <CGAL/Handle_for.h>
+#include <CGAL/Kernel/mpl.h>
+#include <CGAL/representation_tags.h>
+#include <CGAL/assertions.h>
+#include <boost/type_traits.hpp>
+#include <CGAL/Kernel/Return_base_tag.h>
+#include <CGAL/Dimension.h>
+#ifndef CGAL_CXX11
+#include <boost/preprocessor/repetition.hpp>
+#endif
+#include <boost/utility/result_of.hpp>
+
+// no need for a fancy interface here, people can use the Point_d wrapper on
+// top.
+
+namespace CGAL {
+
+template <class R_, class Tag_>
+class Ref_count_obj
+{
+ typedef typename R_::Kernel_base Kbase;
+ typedef typename Get_functor<Kbase, Construct_ttag<Tag_> >::type CBase;
+
+ typedef Ref_count_obj Self;
+ CGAL_static_assertion((boost::is_same<Self, typename Get_type<R_, Tag_>::type>::value));
+
+public:
+ typedef R_ R;
+
+ typedef Tag_true Is_wrapper;
+ typedef typename R_::Default_ambient_dimension Ambient_dimension;
+ //typedef Dimension_tag<0> Feature_dimension;
+
+ typedef typename Get_type<Kbase, Tag_>::type Rep;
+ typedef Handle_for<Rep> Data;
+
+private:
+ Data data;
+public:
+
+ const Rep& rep() const
+ {
+ return CGAL::get_pointee_or_identity(data);
+ }
+
+#ifdef CGAL_CXX11
+ template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Ref_count_obj> >::value>::type> explicit Ref_count_obj(U&&...u)
+ : data(Eval_functor(),CBase(),std::forward<U>(u)...){}
+
+ template<class F,class...U> explicit Ref_count_obj(Eval_functor&&,F&&f,U&&...u)
+ : data(Eval_functor(),std::forward<F>(f),std::forward<U>(u)...){}
+
+ // try not to use these
+ Ref_count_obj(Rep const& v) : data(v) {}
+ Ref_count_obj(Rep& v) : data(static_cast<Rep const&>(v)) {}
+ Ref_count_obj(Rep&& v) : data(std::move(v)) {}
+
+ // Do we really need this for point?
+// // this one should be implicit
+// Ref_count_obj(Origin const& v)
+// : data(Eval_functor(),CBase(),v) {}
+// Ref_count_obj(Origin& v)
+// : data(Eval_functor(),CBase(),v) {}
+// Ref_count_obj(Origin&& v)
+// : data(Eval_functor(),CBase(),std::move(v)) {}
+
+#else
+
+ Ref_count_obj() : data(Eval_functor(),CBase()) {}
+
+ Ref_count_obj(Rep const& v) : data(v) {} // try not to use it
+
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ explicit Ref_count_obj(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : data(Eval_functor(),CBase(),BOOST_PP_ENUM_PARAMS(N,t)) {} \
+ \
+ template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Ref_count_obj(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : data(Eval_functor(),f,BOOST_PP_ENUM_PARAMS(N,t)) {}
+
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+ template<class F>
+ Ref_count_obj(Eval_functor,F const& f)
+ : data(Eval_functor(),f) {}
+
+// // this one should be implicit
+// Ref_count_obj(Origin const& o)
+// : data(Eval_functor(),CBase(),o) {}
+
+#endif
+
+};
+
+} //namespace CGAL
+
+#endif
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Segment_d.h b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Segment_d.h
new file mode 100644
index 00000000..bfb20a77
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Segment_d.h
@@ -0,0 +1,133 @@
+// 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_WRAPPER_SEGMENT_D_H
+#define CGAL_WRAPPER_SEGMENT_D_H
+
+#include <CGAL/Origin.h>
+#include <CGAL/Kernel/mpl.h>
+#include <CGAL/representation_tags.h>
+#include <CGAL/assertions.h>
+#include <boost/type_traits.hpp>
+#include <CGAL/Kernel/Return_base_tag.h>
+#include <CGAL/Dimension.h>
+#ifndef CGAL_CXX11
+#include <boost/preprocessor/repetition.hpp>
+#endif
+#include <boost/utility/result_of.hpp>
+
+namespace CGAL {
+namespace Wrap {
+
+template <class R_>
+class Segment_d : public Get_type<typename R_::Kernel_base, Segment_tag>::type
+{
+ typedef typename Get_type<R_, RT_tag>::type RT_;
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename R_::Kernel_base Kbase;
+ typedef typename Get_type<R_, Point_tag>::type Point_;
+ typedef typename Get_functor<Kbase, Construct_ttag<Point_tag> >::type CPBase;
+ typedef typename Get_functor<Kbase, Construct_ttag<Segment_tag> >::type CSBase;
+ typedef typename Get_functor<Kbase, Segment_extremity_tag>::type CSEBase;
+
+ typedef Segment_d Self;
+ CGAL_static_assertion((boost::is_same<Self, typename Get_type<R_, Segment_tag>::type>::value));
+
+public:
+
+ typedef Tag_true Is_wrapper;
+ typedef typename R_::Default_ambient_dimension Ambient_dimension;
+ typedef Dimension_tag<1> Feature_dimension;
+
+ typedef typename Get_type<Kbase, Segment_tag>::type Rep;
+
+ const Rep& rep() const
+ {
+ return *this;
+ }
+
+ Rep& rep()
+ {
+ return *this;
+ }
+
+ typedef R_ R;
+
+#ifdef CGAL_CXX11
+ template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Segment_d> >::value>::type> explicit Segment_d(U&&...u)
+ : Rep(CSBase()(std::forward<U>(u)...)){}
+
+// // called from Construct_point_d
+// template<class...U> explicit Point_d(Eval_functor&&,U&&...u)
+// : Rep(Eval_functor(), std::forward<U>(u)...){}
+ template<class F,class...U> explicit Segment_d(Eval_functor&&,F&&f,U&&...u)
+ : Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
+
+#if 0
+ // the new standard may make this necessary
+ Point_d(Point_d const&)=default;
+ Point_d(Point_d &);//=default;
+ Point_d(Point_d &&)=default;
+#endif
+
+ // try not to use these
+ Segment_d(Rep const& v) : Rep(v) {}
+ Segment_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
+ Segment_d(Rep&& v) : Rep(std::move(v)) {}
+
+#else
+
+ Segment_d() : Rep(CSBase()()) {}
+
+ Segment_d(Rep const& v) : Rep(v) {} // try not to use it
+
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ explicit Segment_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(CSBase()( \
+ BOOST_PP_ENUM_PARAMS(N,t))) {} \
+ \
+ template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Segment_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
+ /*
+ template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
+ */
+
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+
+#endif
+
+ //TODO: if CSEBase returns a reference to a base point, cast it to a
+ //reference to a wrapper point. Ugly but should be safe.
+ Point_ source()const{
+ return Point_(Eval_functor(),CSEBase(),rep(),0);
+ }
+ Point_ target()const{
+ return Point_(Eval_functor(),CSEBase(),rep(),1);
+ }
+
+};
+
+} //namespace Wrap
+} //namespace CGAL
+
+#endif // CGAL_WRAPPER_SEGMENT_D_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Sphere_d.h b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Sphere_d.h
new file mode 100644
index 00000000..87f0c66e
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Sphere_d.h
@@ -0,0 +1,130 @@
+// 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_WRAPPER_SPHERE_D_H
+#define CGAL_WRAPPER_SPHERE_D_H
+
+#include <CGAL/representation_tags.h>
+#include <CGAL/assertions.h>
+#include <boost/type_traits.hpp>
+#include <CGAL/Kernel/Return_base_tag.h>
+#include <CGAL/Dimension.h>
+#ifndef CGAL_CXX11
+#include <boost/preprocessor/repetition.hpp>
+#endif
+#include <boost/utility/result_of.hpp>
+
+namespace CGAL {
+namespace Wrap {
+
+template <class R_>
+class Sphere_d : public Get_type<typename R_::Kernel_base, Sphere_tag>::type
+{
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename R_::Kernel_base Kbase;
+ typedef typename Get_type<R_, Point_tag>::type Point_;
+ typedef typename Get_functor<Kbase, Construct_ttag<Sphere_tag> >::type CSBase;
+ typedef typename Get_functor<Kbase, Center_of_sphere_tag>::type COSBase;
+ typedef typename Get_functor<Kbase, Squared_radius_tag>::type SRBase;
+
+ typedef Sphere_d Self;
+ CGAL_static_assertion((boost::is_same<Self, typename Get_type<R_, Sphere_tag>::type>::value));
+
+public:
+
+ typedef Tag_true Is_wrapper;
+ typedef typename R_::Default_ambient_dimension Ambient_dimension;
+ typedef typename Increment_dimension<Ambient_dimension,-1>::type Feature_dimension;
+
+ typedef typename Get_type<Kbase, Sphere_tag>::type Rep;
+
+ const Rep& rep() const
+ {
+ return *this;
+ }
+
+ Rep& rep()
+ {
+ return *this;
+ }
+
+ typedef R_ R;
+
+#ifdef CGAL_CXX11
+ template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Sphere_d> >::value>::type> explicit Sphere_d(U&&...u)
+ : Rep(CSBase()(std::forward<U>(u)...)){}
+
+// // called from Construct_point_d
+// template<class...U> explicit Point_d(Eval_functor&&,U&&...u)
+// : Rep(Eval_functor(), std::forward<U>(u)...){}
+ template<class F,class...U> explicit Sphere_d(Eval_functor&&,F&&f,U&&...u)
+ : Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
+
+#if 0
+ // the new standard may make this necessary
+ Point_d(Point_d const&)=default;
+ Point_d(Point_d &);//=default;
+ Point_d(Point_d &&)=default;
+#endif
+
+ // try not to use these
+ Sphere_d(Rep const& v) : Rep(v) {}
+ Sphere_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
+ Sphere_d(Rep&& v) : Rep(std::move(v)) {}
+
+#else
+
+ Sphere_d() : Rep(CSBase()()) {}
+
+ Sphere_d(Rep const& v) : Rep(v) {} // try not to use it
+
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ explicit Sphere_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(CSBase()( \
+ BOOST_PP_ENUM_PARAMS(N,t))) {} \
+ \
+ template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Sphere_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
+ /*
+ template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
+ */
+
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+
+#endif
+
+ //TODO: if COSBase returns a reference to a base point, cast it to a
+ //reference to a wrapper point. Ugly but should be safe.
+ Point_ center()const{
+ return Point_(Eval_functor(),COSBase(),rep());
+ }
+ FT_ squared_radius()const{
+ return SRBase()(rep());
+ }
+
+};
+
+} //namespace Wrap
+} //namespace CGAL
+
+#endif // CGAL_WRAPPER_SPHERE_D_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Vector_d.h b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Vector_d.h
new file mode 100644
index 00000000..b7d1f0d0
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Vector_d.h
@@ -0,0 +1,266 @@
+// 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_WRAPPER_VECTOR_D_H
+#define CGAL_WRAPPER_VECTOR_D_H
+
+#include <CGAL/Origin.h>
+#include <CGAL/Kernel/mpl.h>
+#include <CGAL/representation_tags.h>
+#include <CGAL/assertions.h>
+#include <boost/type_traits.hpp>
+#include <CGAL/Kernel/Return_base_tag.h>
+#include <CGAL/Dimension.h>
+#ifndef CGAL_CXX11
+#include <boost/preprocessor/repetition.hpp>
+#endif
+#include <boost/utility/result_of.hpp>
+
+namespace CGAL {
+namespace Wrap {
+
+template <class R_>
+class Vector_d : public Get_type<typename R_::Kernel_base, Vector_tag>::type
+{
+ typedef typename Get_type<R_, RT_tag>::type RT_;
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename R_::Kernel_base Kbase;
+ typedef typename Get_type<R_, Point_tag>::type Point_;
+ typedef typename Get_functor<Kbase, Construct_ttag<Vector_tag> >::type CVBase;
+ typedef typename Get_functor<Kbase, Compute_vector_cartesian_coordinate_tag>::type CCBase;
+ typedef typename Get_functor<Kbase, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CVI;
+ typedef typename Get_functor<Kbase, Squared_length_tag>::type SLBase;
+
+ typedef Vector_d Self;
+ CGAL_static_assertion((boost::is_same<Self, typename Get_type<R_, Vector_tag>::type>::value));
+
+public:
+
+ typedef Tag_true Is_wrapper;
+ typedef typename R_::Default_ambient_dimension Ambient_dimension;
+ typedef Dimension_tag<0> Feature_dimension;
+
+ //typedef typename R_::Vector_cartesian_const_iterator Cartesian_const_iterator;
+ typedef typename Get_type<Kbase, Vector_tag>::type Rep;
+
+ const Rep& rep() const
+ {
+ return *this;
+ }
+
+ Rep& rep()
+ {
+ return *this;
+ }
+
+ typedef R_ R;
+
+#ifdef CGAL_CXX11
+ template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Vector_d> >::value>::type> explicit Vector_d(U&&...u)
+ : Rep(CVBase()(std::forward<U>(u)...)){}
+
+// // called from Construct_vector_d
+// template<class...U> explicit Vector_d(Eval_functor&&,U&&...u)
+// : Rep(Eval_functor(), std::forward<U>(u)...){}
+ template<class F,class...U> explicit Vector_d(Eval_functor&&,F&&f,U&&...u)
+ : Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
+
+#if 0
+ // the new standard may make this necessary
+ Vector_d(Vector_d const&)=default;
+ Vector_d(Vector_d &);//=default;
+ Vector_d(Vector_d &&)=default;
+#endif
+
+ // try not to use these
+ Vector_d(Rep const& v) : Rep(v) {}
+ Vector_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
+ Vector_d(Rep&& v) : Rep(std::move(v)) {}
+
+ // this one should be implicit
+ Vector_d(Null_vector const& v)
+ : Rep(CVBase()(v)) {}
+ Vector_d(Null_vector& v)
+ : Rep(CVBase()(v)) {}
+ Vector_d(Null_vector&& v)
+ : Rep(CVBase()(std::move(v))) {}
+
+#else
+
+ Vector_d() : Rep(CVBase()()) {}
+
+ Vector_d(Rep const& v) : Rep(v) {} // try not to use it
+
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ explicit Vector_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(CVBase()( \
+ BOOST_PP_ENUM_PARAMS(N,t))) {} \
+ \
+ template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Vector_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
+ /*
+ template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Vector_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
+ */
+
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+
+ // this one should be implicit
+ Vector_d(Null_vector const& v)
+ : Rep(CVBase()(v)) {}
+
+#endif
+
+ typename boost::result_of<CCBase(Rep,int)>::type cartesian(int i)const{
+ return CCBase()(rep(),i);
+ }
+
+ typename boost::result_of<CCBase(Rep,int)>::type operator[](int i)const{
+ return CCBase()(rep(),i);
+ }
+
+ typename boost::result_of<CVI(Rep,Begin_tag)>::type cartesian_begin()const{
+ return CVI()(rep(),Begin_tag());
+ }
+
+ typename boost::result_of<CVI(Rep,End_tag)>::type cartesian_end()const{
+ return CVI()(rep(),End_tag());
+ }
+
+ Vector_d operator-() const
+ {
+ return typename Get_functor<R, Opposite_vector_tag>::type()(*this);
+ }
+
+ /*
+ Direction_d direction() const
+ {
+ return R().construct_direction_d_object()(*this);
+ }
+
+ Vector_d transform(const Aff_transformation_d &t) const
+ {
+ return t.transform(*this);
+ }
+
+ Vector_d operator/(const RT& c) const
+ {
+ return R().construct_divided_vector_d_object()(*this,c);
+ }
+
+ Vector_d operator/(const typename First_if_different<FT_,RT>::Type & c) const
+ {
+ return R().construct_divided_vector_d_object()(*this,c);
+ }
+
+ typename Qualified_result_of<typename R::Compute_x_3, Vector_3>::type
+ x() const
+ {
+ return R().compute_x_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_y_3, Vector_3>::type
+ y() const
+ {
+ return R().compute_y_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_z_3, Vector_3>::type
+ z() const
+ {
+ return R().compute_z_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_hx_3, Vector_3>::type
+ hx() const
+ {
+ return R().compute_hx_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_hy_3, Vector_3>::type
+ hy() const
+ {
+ return R().compute_hy_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_hz_3, Vector_3>::type
+ hz() const
+ {
+ return R().compute_hz_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_hw_3, Vector_3>::type
+ hw() const
+ {
+ return R().compute_hw_3_object()(*this);
+ }
+
+ typename Qualified_result_of<typename R::Compute_x_3, Vector_3>::type
+ cartesian(int i) const
+ {
+ CGAL_kernel_precondition( (i == 0) || (i == 1) || (i == 2) );
+ if (i==0) return x();
+ if (i==1) return y();
+ return z();
+ }
+
+ typename Qualified_result_of<typename R::Compute_hw_3, Vector_3>::type
+ homogeneous(int i) const
+ {
+ CGAL_kernel_precondition( (i >= 0) || (i <= 3) );
+ if (i==0) return hx();
+ if (i==1) return hy();
+ if (i==2) return hz();
+ return hw();
+ }
+
+ int dimension() const // bad idea?
+ {
+ return rep.dimension();
+ }
+*/
+ typename boost::result_of<SLBase(Rep)>::type squared_length()const{
+ return SLBase()(rep());
+ }
+};
+#if 0
+template <class R_> Vector_d<R_>::Vector_d(Vector_d &)=default;
+#endif
+
+//TODO: IO
+
+template <class R_>
+Vector_d<R_> operator+(const Vector_d<R_>& v,const Vector_d<R_>& w)
+{
+ return typename Get_functor<R_, Sum_of_vectors_tag>::type()(v,w);
+}
+
+template <class R_>
+Vector_d<R_> operator-(const Vector_d<R_>& v,const Vector_d<R_>& w)
+{
+ return typename Get_functor<R_, Difference_of_vectors_tag>::type()(v,w);
+}
+
+} //namespace Wrap
+} //namespace CGAL
+
+#endif // CGAL_WRAPPER_VECTOR_D_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Weighted_point_d.h b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Weighted_point_d.h
new file mode 100644
index 00000000..877eea21
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/Wrapper/Weighted_point_d.h
@@ -0,0 +1,129 @@
+// 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_WRAPPER_WEIGHTED_POINT_D_H
+#define CGAL_WRAPPER_WEIGHTED_POINT_D_H
+
+#include <CGAL/representation_tags.h>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <CGAL/Kernel/Return_base_tag.h>
+#include <CGAL/Dimension.h>
+#ifndef CGAL_CXX11
+#include <boost/preprocessor/repetition.hpp>
+#endif
+#include <boost/utility/result_of.hpp>
+
+namespace CGAL {
+namespace Wrap {
+
+template <class R_>
+class Weighted_point_d : public Get_type<typename R_::Kernel_base, Weighted_point_tag>::type
+{
+ typedef typename Get_type<R_, FT_tag>::type FT_;
+ typedef typename R_::Kernel_base Kbase;
+ typedef typename Get_type<R_, Point_tag>::type Point_;
+ typedef typename Get_functor<Kbase, Construct_ttag<Weighted_point_tag> >::type CWPBase;
+ typedef typename Get_functor<Kbase, Point_drop_weight_tag>::type PDWBase;
+ typedef typename Get_functor<Kbase, Point_weight_tag>::type PWBase;
+
+ typedef Weighted_point_d Self;
+ BOOST_STATIC_ASSERT((boost::is_same<Self, typename Get_type<R_, Weighted_point_tag>::type>::value));
+
+public:
+
+ typedef Tag_true Is_wrapper;
+ typedef typename R_::Default_ambient_dimension Ambient_dimension;
+ typedef Dimension_tag<0> Feature_dimension;
+
+ typedef typename Get_type<Kbase, Weighted_point_tag>::type Rep;
+
+ const Rep& rep() const
+ {
+ return *this;
+ }
+
+ Rep& rep()
+ {
+ return *this;
+ }
+
+ typedef R_ R;
+
+#ifdef CGAL_CXX11
+ template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Weighted_point_d> >::value>::type> explicit Weighted_point_d(U&&...u)
+ : Rep(CWPBase()(std::forward<U>(u)...)){}
+
+// // called from Construct_point_d
+// template<class...U> explicit Point_d(Eval_functor&&,U&&...u)
+// : Rep(Eval_functor(), std::forward<U>(u)...){}
+ template<class F,class...U> explicit Weighted_point_d(Eval_functor&&,F&&f,U&&...u)
+ : Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
+
+#if 0
+ // the new standard may make this necessary
+ Point_d(Point_d const&)=default;
+ Point_d(Point_d &);//=default;
+ Point_d(Point_d &&)=default;
+#endif
+
+ // try not to use these
+ Weighted_point_d(Rep const& v) : Rep(v) {}
+ Weighted_point_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
+ Weighted_point_d(Rep&& v) : Rep(std::move(v)) {}
+
+#else
+
+ Weighted_point_d() : Rep(CWPBase()()) {}
+
+ Weighted_point_d(Rep const& v) : Rep(v) {} // try not to use it
+
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ explicit Weighted_point_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(CWPBase()( \
+ BOOST_PP_ENUM_PARAMS(N,t))) {} \
+ \
+ template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Weighted_point_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
+ /*
+ template<BOOST_PP_ENUM_PARAMS(N,class T)> \
+ Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
+ : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
+ */
+
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+
+#endif
+
+ //TODO: use references?
+ Point_ point()const{
+ return Point_(Eval_functor(),PDWBase(),rep());
+ }
+ FT_ weight()const{
+ return PWBase()(rep());
+ }
+
+};
+
+} //namespace Wrap
+} //namespace CGAL
+
+#endif // CGAL_WRAPPER_SPHERE_D_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/function_objects_cartesian.h b/include/gudhi_patches/CGAL/NewKernel_d/function_objects_cartesian.h
new file mode 100644
index 00000000..5a132ad2
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/function_objects_cartesian.h
@@ -0,0 +1,1355 @@
+// 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_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H
+#define CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H
+
+#include <CGAL/NewKernel_d/utils.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/Uncertain.h>
+#include <CGAL/NewKernel_d/store_kernel.h>
+#include <CGAL/is_iterator.h>
+#include <CGAL/iterator_from_indices.h>
+#include <CGAL/number_utils.h>
+#include <CGAL/Kernel/Return_base_tag.h>
+#include <CGAL/transforming_iterator.h>
+#include <CGAL/transforming_pair_iterator.h>
+#include <CGAL/NewKernel_d/functor_tags.h>
+#include <CGAL/NewKernel_d/functor_properties.h>
+#include <CGAL/predicates/sign_of_determinant.h>
+#include <functional>
+#ifdef CGAL_CXX11
+#include <initializer_list>
+#endif
+
+namespace CGAL {
+namespace CartesianDKernelFunctors {
+namespace internal {
+template<class,int> struct Dimension_at_most { enum { value = false }; };
+template<int a,int b> struct Dimension_at_most<Dimension_tag<a>,b> {
+ enum { value = (a <= b) };
+};
+}
+
+template<class R_,class D_=typename R_::Default_ambient_dimension,bool=internal::Dimension_at_most<D_,6>::value> struct Orientation_of_points : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Orientation_of_points)
+ typedef R_ R;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ typedef typename R::LA::Square_matrix Matrix;
+
+ template<class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+ Point const& p0=*f++;
+ int d=pd(p0);
+ Matrix m(d,d);
+ // FIXME: this writes the vector coordinates in lines ? check all the other uses in this file, this may be wrong for some.
+ for(int i=0;f!=e;++f,++i) {
+ Point const& p=*f;
+ for(int j=0;j<d;++j){
+ m(i,j)=c(p,j)-c(p0,j);
+ // should we cache the coordinates of p0 in case they are computed?
+ }
+ }
+ return R::LA::sign_of_determinant(CGAL_MOVE(m));
+ }
+
+#ifdef CGAL_CXX11
+ // Since the dimension is at least 2, there are at least 3 points and no ambiguity with iterators.
+ // template <class...U,class=typename std::enable_if<std::is_same<Dimension_tag<sizeof...(U)-1>,typename R::Default_ambient_dimension>::value>::type>
+ template <class...U,class=typename std::enable_if<(sizeof...(U)>=3)>::type>
+ result_type operator()(U&&...u) const {
+ return operator()({std::forward<U>(u)...});
+ }
+
+ template <class P>
+ result_type operator()(std::initializer_list<P> l) const {
+ return operator()(l.begin(),l.end());
+ }
+#else
+ //should we make it template to avoid instantiation for wrong dim?
+ //or iterate outside the class?
+#define CGAL_VAR(Z,J,I) m(I,J)=c(p##I,J)-c(x,J);
+#define CGAL_VAR2(Z,I,N) BOOST_PP_REPEAT(N,CGAL_VAR,I)
+#define CGAL_CODE(Z,N,_) \
+ result_type operator()(Point const&x, BOOST_PP_ENUM_PARAMS(N,Point const&p)) const { \
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel()); \
+ Matrix m(N,N); \
+ BOOST_PP_REPEAT(N,CGAL_VAR2,N) \
+ return R::LA::sign_of_determinant(CGAL_MOVE(m)); \
+ }
+
+BOOST_PP_REPEAT_FROM_TO(7, 10, CGAL_CODE, _ )
+ // No need to do it for <=6, since that uses a different code path
+#undef CGAL_CODE
+#undef CGAL_VAR2
+#undef CGAL_VAR
+#endif
+};
+
+#ifdef CGAL_CXX11
+template<class R_,int d> struct Orientation_of_points<R_,Dimension_tag<d>,true> : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Orientation_of_points)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ template<class>struct Help;
+ template<int...I>struct Help<Indices<I...> > {
+ template<class C,class P,class T> result_type operator()(C const&c,P const&x,T&&t)const{
+ return sign_of_determinant<RT>(c(std::get<I/d>(t),I%d)-c(x,I%d)...);
+ }
+ };
+ template<class P0,class...P> result_type operator()(P0 const&x,P&&...p)const{
+ static_assert(d==sizeof...(P),"Wrong number of arguments");
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ return Help<typename N_increasing_indices<d*d>::type>()(c,x,std::forward_as_tuple(std::forward<P>(p)...));
+ }
+
+
+ template<int N,class Iter,class...U> result_type help2(Dimension_tag<N>, Iter f, Iter const&e, U&&...u)const{
+ auto const&p=*f;
+ return help2(Dimension_tag<N-1>(),++f,e,std::forward<U>(u)...,p);
+ }
+ template<class Iter,class...U> result_type help2(Dimension_tag<0>, Iter CGAL_assertion_code(f), Iter const& CGAL_assertion_code(e), U&&...u)const{
+ CGAL_assertion(f==e);
+ return operator()(std::forward<U>(u)...);
+ }
+ template<class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ return help2(Dimension_tag<d+1>(),f,e);
+ }
+};
+#else
+#define CGAL_VAR(Z,J,I) c(p##I,J)-x##J
+#define CGAL_VAR2(Z,I,N) BOOST_PP_ENUM(N,CGAL_VAR,I)
+#define CGAL_VAR3(Z,N,_) Point const&p##N=*++f;
+#define CGAL_VAR4(Z,N,_) RT const&x##N=c(x,N);
+#define CGAL_CODE(Z,N,_) \
+template<class R_> struct Orientation_of_points<R_,Dimension_tag<N>,true> : private Store_kernel<R_> { \
+ CGAL_FUNCTOR_INIT_STORE(Orientation_of_points) \
+ typedef R_ R; \
+ typedef typename Get_type<R, RT_tag>::type RT; \
+ typedef typename Get_type<R, Point_tag>::type Point; \
+ typedef typename Get_type<R, Orientation_tag>::type result_type; \
+ result_type operator()(Point const&x, BOOST_PP_ENUM_PARAMS(N,Point const&p)) const { \
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel()); \
+ BOOST_PP_REPEAT(N,CGAL_VAR4,) \
+ return sign_of_determinant<RT>(BOOST_PP_ENUM(N,CGAL_VAR2,N)); \
+ } \
+ template<class Iter> \
+ result_type operator()(Iter f, Iter CGAL_assertion_code(e))const{ \
+ Point const&x=*f; \
+ BOOST_PP_REPEAT(N,CGAL_VAR3,) \
+ CGAL_assertion(++f==e); \
+ return operator()(x,BOOST_PP_ENUM_PARAMS(N,p)); \
+ } \
+};
+
+ BOOST_PP_REPEAT_FROM_TO(2, 7, CGAL_CODE, _ )
+#undef CGAL_CODE
+#undef CGAL_VAR4
+#undef CGAL_VAR3
+#undef CGAL_VAR2
+#undef CGAL_VAR
+
+#endif
+
+template<class R_> struct Orientation_of_points<R_,Dimension_tag<1>,true> : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Orientation_of_points)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ result_type operator()(Point const&x, Point const&y) const {
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ // No sign_of_determinant(RT) :-(
+ return CGAL::compare(c(y,0),c(x,0));
+ }
+ template<class Iter>
+ result_type operator()(Iter f, Iter CGAL_assertion_code(e))const{
+ Point const&x=*f;
+ Point const&y=*++f;
+ CGAL_assertion(++f==e);
+ return operator()(x,y);
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Orientation_of_points_tag,(CartesianDKernelFunctors::Orientation_of_points<K>),(Point_tag),(Point_dimension_tag,Compute_point_cartesian_coordinate_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Orientation_of_vectors : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Orientation_of_vectors)
+ typedef R_ R;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ typedef typename R::LA::Square_matrix Matrix;
+
+ template<class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ typename Get_functor<R, Compute_vector_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type vd(this->kernel());
+ // FIXME: Uh? Using it on a vector ?!
+ Vector const& v0=*f;
+ int d=vd(v0);
+ Matrix m(d,d);
+ for(int j=0;j<d;++j){
+ m(0,j)=c(v0,j);
+ }
+ for(int i=1;++f!=e;++i) {
+ Vector const& v=*f;
+ for(int j=0;j<d;++j){
+ m(i,j)=c(v,j);
+ }
+ }
+ return R::LA::sign_of_determinant(CGAL_MOVE(m));
+ }
+
+#ifdef CGAL_CXX11
+ template <class...U,class=typename std::enable_if<(sizeof...(U)>=3)>::type>
+ result_type operator()(U&&...u) const {
+ return operator()({std::forward<U>(u)...});
+ }
+
+ template <class V>
+ result_type operator()(std::initializer_list<V> l) const {
+ return operator()(l.begin(),l.end());
+ }
+#else
+ //TODO
+#endif
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Orientation_of_vectors_tag,(CartesianDKernelFunctors::Orientation_of_vectors<K>),(Vector_tag),(Point_dimension_tag,Compute_vector_cartesian_coordinate_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Linear_rank : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Linear_rank)
+ typedef R_ R;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ // Computing a sensible Uncertain<int> is not worth it
+ typedef int result_type;
+ typedef typename R::LA::Dynamic_matrix Matrix;
+
+ template<class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ typename Get_functor<R, Compute_vector_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type vd(this->kernel());
+ std::ptrdiff_t n=std::distance(f,e);
+ if (n==0) return 0;
+ Vector const& v0 = *f;
+ // FIXME: Uh? Using it on a vector ?!
+ int d=vd(v0);
+ Matrix m(d,n);
+ for(int j=0;j<d;++j){
+ m(j,0)=c(v0,j);
+ }
+ for(int i=1; ++f!=e; ++i){
+ Vector const& v = *f;
+ for(int j=0;j<d;++j){
+ m(j,i)=c(v,j);
+ }
+ }
+ return R::LA::rank(CGAL_MOVE(m));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Linear_rank_tag,(CartesianDKernelFunctors::Linear_rank<K>),(Vector_tag),(Point_dimension_tag,Compute_vector_cartesian_coordinate_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Linearly_independent : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Linearly_independent)
+ typedef R_ R;
+ typedef typename Get_type<R, Bool_tag>::type result_type;
+
+ template<class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ typename Get_functor<R, Point_dimension_tag>::type vd(this->kernel());
+ std::ptrdiff_t n=std::distance(f,e);
+ // FIXME: Uh? Using it on a vector ?!
+ int d=vd(*f);
+ if (n>d) return false;
+ typename Get_functor<R, Linear_rank_tag>::type lr(this->kernel());
+ return lr(f,e) == n;
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Linearly_independent_tag,(CartesianDKernelFunctors::Linearly_independent<K>),(Vector_tag),(Point_dimension_tag,Linear_rank_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Contained_in_linear_hull : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Contained_in_linear_hull)
+ typedef R_ R;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ // Computing a sensible Uncertain<bool> is not worth it
+ typedef bool result_type;
+ typedef typename R::LA::Dynamic_matrix Matrix;
+
+ template<class Iter,class V>
+ result_type operator()(Iter f, Iter e,V const&w)const{
+ typename Get_functor<R, Compute_vector_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type vd(this->kernel());
+ std::ptrdiff_t n=std::distance(f,e);
+ if (n==0) return false;
+ // FIXME: Uh? Using it on a vector ?!
+ int d=vd(w);
+ Matrix m(d,n+1);
+ for(int i=0; f!=e; ++f,++i){
+ Vector const& v = *f;
+ for(int j=0;j<d;++j){
+ m(j,i)=c(v,j);
+ }
+ }
+ for(int j=0;j<d;++j){
+ m(j,n)=c(w,j);
+ }
+ int r1 = R::LA::rank(m);
+ // FIXME: Don't use eigen directly, go through an interface in LA...
+ m.conservativeResize(Eigen::NoChange, n);
+ int r2 = R::LA::rank(CGAL_MOVE(m));
+ return r1 == r2;
+ // TODO: This is very very far from optimal...
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Contained_in_linear_hull_tag,(CartesianDKernelFunctors::Contained_in_linear_hull<K>),(Vector_tag),(Point_dimension_tag,Compute_vector_cartesian_coordinate_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Affine_rank : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Affine_rank)
+ typedef R_ R;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ // Computing a sensible Uncertain<int> is not worth it
+ typedef int result_type;
+ typedef typename R::LA::Dynamic_matrix Matrix;
+
+ template<class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+ int n=(int)std::distance(f,e);
+ if (--n<=0) return n;
+ Point const& p0 = *f;
+ int d=pd(p0);
+ Matrix m(d,n);
+ for(int i=0; ++f!=e; ++i){
+ Point const& p = *f;
+ for(int j=0;j<d;++j){
+ m(j,i)=c(p,j)-c(p0,j);
+ // TODO: cache p0[j] in case it is computed?
+ }
+ }
+ return R::LA::rank(CGAL_MOVE(m));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Affine_rank_tag,(CartesianDKernelFunctors::Affine_rank<K>),(Point_tag),(Point_dimension_tag,Compute_point_cartesian_coordinate_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Affinely_independent : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Affinely_independent)
+ typedef R_ R;
+ typedef typename Get_type<R, Bool_tag>::type result_type;
+
+ template<class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+ std::ptrdiff_t n=std::distance(f,e);
+ int d=pd(*f);
+ if (--n>d) return false;
+ typename Get_functor<R, Affine_rank_tag>::type ar(this->kernel());
+ return ar(f,e) == n;
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Affinely_independent_tag,(CartesianDKernelFunctors::Affinely_independent<K>),(Point_tag),(Point_dimension_tag,Affine_rank_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Contained_in_simplex : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Contained_in_simplex)
+ typedef R_ R;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ // Computing a sensible Uncertain<*> is not worth it
+ // typedef typename Get_type<R, Boolean_tag>::type result_type;
+ typedef bool result_type;
+ typedef typename Increment_dimension<typename R::Default_ambient_dimension>::type D1;
+ typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type D2;
+ typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
+ typedef typename LA::Dynamic_matrix Matrix;
+ typedef typename LA::Dynamic_vector DynVec;
+ typedef typename LA::Vector Vec;
+
+ template<class Iter, class P>
+ result_type operator()(Iter f, Iter e, P const&q)const{
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+ std::ptrdiff_t n=std::distance(f,e);
+ if (n==0) return false;
+ int d=pd(q);
+ Matrix m(d+1,n);
+ DynVec a(n);
+ // FIXME: Should use the proper vector constructor (Iterator_and_last)
+ Vec b(d+1);
+ for(int j=0;j<d;++j) b[j]=c(q,j);
+ b[d]=1;
+
+ for(int i=0; f!=e; ++i,++f){
+ Point const& p = *f;
+ for(int j=0;j<d;++j){
+ m(j,i)=c(p,j);
+ }
+ m(d,i)=1;
+ }
+ // If the simplex has full dimension, there must be a solution, only the signs need to be checked.
+ if (n == d+1)
+ LA::solve(a,CGAL_MOVE(m),CGAL_MOVE(b));
+ else if (!LA::solve_and_check(a,CGAL_MOVE(m),CGAL_MOVE(b)))
+ return false;
+ for(int i=0;i<n;++i){
+ if (a[i]<0) return false;
+ }
+ return true;
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Contained_in_simplex_tag,(CartesianDKernelFunctors::Contained_in_simplex<K>),(Point_tag),(Point_dimension_tag,Compute_point_cartesian_coordinate_tag));
+
+namespace CartesianDKernelFunctors {
+ namespace internal {
+ template<class Ref_>
+ struct Matrix_col_access {
+ typedef Ref_ result_type;
+ int col;
+ Matrix_col_access(int r):col(r){}
+ template<class Mat> Ref_ operator()(Mat const& m, std::ptrdiff_t row)const{
+ return m(row,col);
+ }
+ };
+ }
+template<class R_> struct Linear_base : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Linear_base)
+ typedef R_ R;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef void result_type;
+ typedef typename R::LA::Dynamic_matrix Matrix;
+
+ template<class Iter, class Oter>
+ result_type operator()(Iter f, Iter e, Oter&o)const{
+ typename Get_functor<R, Compute_vector_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type vd(this->kernel());
+ typename Get_functor<R, Construct_ttag<Vector_tag> >::type cv(this->kernel());
+ std::ptrdiff_t n=std::distance(f,e);
+ if (n==0) return;
+ Vector const& v0 = *f;
+ // FIXME: Uh? Using it on a vector ?!
+ int d=vd(v0);
+ Matrix m(d,n);
+ for(int j=0;j<d;++j){
+ m(0,j)=c(v0,j);
+ }
+ for(int i=1; ++f!=e; ++i){
+ Vector const& v = *f;
+ for(int j=0;j<d;++j){
+ m(i,j)=c(v,j);
+ }
+ }
+ Matrix b = R::LA::basis(CGAL_MOVE(m));
+ for(int i=0; i < R::LA::columns(b); ++i){
+ //*o++ = Vector(b.col(i));
+ typedef
+#ifdef CGAL_CXX11
+ decltype(std::declval<const Matrix>()(0,0))
+#else
+ FT
+#endif
+ Ref;
+ typedef Iterator_from_indices<Matrix, FT, Ref,
+ internal::Matrix_col_access<Ref> > IFI;
+ *o++ = cv(IFI(b,0,i),IFI(b,d,i));
+ }
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Linear_base_tag,(CartesianDKernelFunctors::Linear_base<K>),(Vector_tag),(Point_dimension_tag,Compute_vector_cartesian_coordinate_tag));
+
+#if 0
+namespace CartesianDKernelFunctors {
+template<class R_,bool=boost::is_same<typename R_::Point,typename R_::Vector>::value> struct Orientation : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Orientation)
+ typedef R_ R;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ typedef typename Get_functor<R, Orientation_of_points_tag>::type OP;
+ typedef typename Get_functor<R, Orientation_of_vectors_tag>::type OV;
+
+ //FIXME!!!
+ //when Point and Vector are distinct types, the dispatch should be made
+ //in a way that doesn't instantiate a conversion from Point to Vector
+ template<class Iter>
+ result_type operator()(Iter const&f, Iter const& e)const{
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+ typename std::iterator_traits<Iter>::difference_type d=std::distance(f,e);
+ int dim=pd(*f); // BAD
+ if(d==dim) return OV(this->kernel())(f,e);
+ CGAL_assertion(d==dim+1);
+ return OP(this->kernel())(f,e);
+ }
+ //TODO: version that takes objects directly instead of iterators
+};
+
+template<class R_> struct Orientation<R_,false> : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Orientation)
+ typedef R_ R;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Orientation_tag>::type result_type;
+ typedef typename Get_functor<R, Orientation_of_points_tag>::type OP;
+ typedef typename Get_functor<R, Orientation_of_vectors_tag>::type OV;
+ typedef typename R::LA::Square_matrix Matrix;
+
+ //FIXME!!!
+ //when Point and Vector are distinct types, the dispatch should be made
+ //in a way that doesn't instantiate a conversion from Point to Vector
+ template<class Iter>
+ typename boost::enable_if<is_iterator_to<Iter,Point>,result_type>::type
+ operator()(Iter const&f, Iter const& e)const{
+ return OP(this->kernel())(f,e);
+ }
+ template<class Iter>
+ typename boost::enable_if<is_iterator_to<Iter,Vector>,result_type>::type
+ operator()(Iter const&f, Iter const& e)const{
+ return OV(this->kernel())(f,e);
+ }
+ //TODO: version that takes objects directly instead of iterators
+};
+}
+#endif
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Power_side_of_power_sphere_raw : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Power_side_of_power_sphere_raw)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Oriented_side_tag>::type result_type;
+ typedef typename Increment_dimension<typename R::Default_ambient_dimension>::type D1;
+ typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type D2;
+ typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
+ typedef typename LA::Square_matrix Matrix;
+
+ template<class IterP, class IterW, class Pt, class Wt>
+ result_type operator()(IterP f, IterP const& e, IterW fw, Pt const& p0, Wt const& w0) const {
+ typedef typename Get_functor<R, Squared_distance_to_origin_tag>::type Sqdo;
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+
+ int d=pd(p0);
+ Matrix m(d+1,d+1);
+ if(CGAL::Is_stored<Sqdo>::value) {
+ Sqdo sqdo(this->kernel());
+ FT const& h0 = sqdo(p0) - w0;
+ for(int i=0;f!=e;++f,++fw,++i) {
+ Point const& p=*f;
+ for(int j=0;j<d;++j){
+ RT const& x=c(p,j);
+ m(i,j)=x-c(p0,j);
+ }
+ m(i,d) = sqdo(p) - *fw - h0;
+ }
+ } else {
+ for(int i=0;f!=e;++f,++fw,++i) {
+ Point const& p=*f;
+ m(i,d) = w0 - *fw;
+ for(int j=0;j<d;++j){
+ RT const& x=c(p,j);
+ m(i,j)=x-c(p0,j);
+ m(i,d)+=CGAL::square(m(i,j));
+ }
+ }
+ }
+ if(d%2)
+ return -LA::sign_of_determinant(CGAL_MOVE(m));
+ else
+ return LA::sign_of_determinant(CGAL_MOVE(m));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Power_side_of_power_sphere_raw_tag,(CartesianDKernelFunctors::Power_side_of_power_sphere_raw<K>),(Point_tag),(Point_dimension_tag,Squared_distance_to_origin_tag,Compute_point_cartesian_coordinate_tag));
+
+// TODO: make Side_of_oriented_sphere call Power_side_of_power_sphere_raw
+namespace CartesianDKernelFunctors {
+template<class R_> struct Side_of_oriented_sphere : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Side_of_oriented_sphere)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Oriented_side_tag>::type result_type;
+ typedef typename Increment_dimension<typename R::Default_ambient_dimension>::type D1;
+ typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type D2;
+ typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
+ typedef typename LA::Square_matrix Matrix;
+
+ template<class Iter>
+ result_type operator()(Iter f, Iter const& e)const{
+ Point const& p0=*f++; // *--e ?
+ return this->operator()(f,e,p0);
+ }
+
+ template<class Iter>
+ result_type operator()(Iter f, Iter const& e, Point const& p0) const {
+ typedef typename Get_functor<R, Squared_distance_to_origin_tag>::type Sqdo;
+ typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+
+ int d=pd(p0);
+ Matrix m(d+1,d+1);
+ if(CGAL::Is_stored<Sqdo>::value) {
+ Sqdo sqdo(this->kernel());
+ for(int i=0;f!=e;++f,++i) {
+ Point const& p=*f;
+ for(int j=0;j<d;++j){
+ RT const& x=c(p,j);
+ m(i,j)=x-c(p0,j);
+ }
+ m(i,d) = sqdo(p) - sqdo(p0);
+ }
+ } else {
+ for(int i=0;f!=e;++f,++i) {
+ Point const& p=*f;
+ m(i,d) = 0;
+ for(int j=0;j<d;++j){
+ RT const& x=c(p,j);
+ m(i,j)=x-c(p0,j);
+ m(i,d)+=CGAL::square(m(i,j));
+ }
+ }
+ }
+ if(d%2)
+ return -LA::sign_of_determinant(CGAL_MOVE(m));
+ else
+ return LA::sign_of_determinant(CGAL_MOVE(m));
+ }
+
+#ifdef CGAL_CXX11
+ template <class...U,class=typename std::enable_if<(sizeof...(U)>=4)>::type>
+ result_type operator()(U&&...u) const {
+ return operator()({std::forward<U>(u)...});
+ }
+
+ template <class P>
+ result_type operator()(std::initializer_list<P> l) const {
+ return operator()(l.begin(),l.end());
+ }
+#else
+ //TODO
+#endif
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Side_of_oriented_sphere_tag,(CartesianDKernelFunctors::Side_of_oriented_sphere<K>),(Point_tag),(Point_dimension_tag,Squared_distance_to_origin_tag,Compute_point_cartesian_coordinate_tag));
+
+namespace CartesianDKernelFunctors {
+template <class R_> struct Construct_circumcenter : Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Construct_circumcenter)
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef Point result_type;
+ typedef typename Get_type<R_, FT_tag>::type FT;
+ template <class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ typedef typename Get_type<R_, Point_tag>::type Point;
+ typedef typename R_::LA LA;
+ 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());
+
+ Point const& p0=*f;
+ int d = pd(p0);
+ if (d+1 == std::distance(f,e))
+ {
+ // 2*(x-y).c == x^2-y^2
+ typedef typename LA::Square_matrix Matrix;
+ typedef typename LA::Vector Vec;
+ typedef typename LA::Construct_vector CVec;
+ FT const& n0 = sdo(p0);
+ Matrix m(d,d);
+ Vec b = typename CVec::Dimension()(d);
+ // Write the point coordinates in lines.
+ int i;
+ for(i=0; ++f!=e; ++i) {
+ Point const& p=*f;
+ for(int j=0;j<d;++j) {
+ m(i,j)=2*(c(p,j)-c(p0,j));
+ b[i] = sdo(p) - 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;
+ return cp(d,LA::vector_begin(res),LA::vector_end(res));
+ }
+ else
+ {
+ /*
+ * Matrix P=(p1, p2, ...) (each point as a column)
+ * Matrix Q=2*t(p2-p1,p3-p1, ...) (each vector as a line)
+ * Matrix M: QP, adding a line of 1 at the top
+ * Vector B: (1, p2^2-p1^2, p3^2-p1^2, ...)
+ * Solve ML=B, the center of the sphere is PL
+ *
+ * It would likely be faster to write P then transpose, multiply,
+ * etc instead of doing it by hand.
+ */
+ // TODO: check for degenerate cases?
+
+ typedef typename R_::Max_ambient_dimension D2;
+ typedef typename R_::LA::template Rebind_dimension<Dynamic_dimension_tag,D2>::Other LAd;
+ typedef typename LAd::Square_matrix Matrix;
+ typedef typename LAd::Vector Vec;
+ typename Get_functor<R_, Scalar_product_tag>::type sp(this->kernel());
+ int k=static_cast<int>(std::distance(f,e));
+ Matrix m(k,k);
+ Vec b(k);
+ Vec l(k);
+ int j,i=0;
+ for(Iter f2=f;f2!=e;++f2,++i){
+ b(i)=m(i,i)=sdo(*f2);
+ j=0;
+ for(Iter f3=f;f3!=e;++f3,++j){
+ m(j,i)=m(i,j)=sp(*f2,*f3);
+ }
+ }
+ for(i=1;i<k;++i){
+ b(i)-=b(0);
+ for(j=0;j<k;++j){
+ m(i,j)=2*(m(i,j)-m(0,j));
+ }
+ }
+ for(j=0;j<k;++j) m(0,j)=1;
+ b(0)=1;
+
+ LAd::solve(l,CGAL_MOVE(m),CGAL_MOVE(b));
+
+ typename LA::Vector center=typename LA::Construct_vector::Dimension()(d);
+ for(i=0;i<d;++i) center(i)=0;
+ j=0;
+ for(Iter f2=f;f2!=e;++f2,++j){
+ for(i=0;i<d;++i){
+ center(i)+=l(j)*c(*f2,i);
+ }
+ }
+
+ return cp(LA::vector_begin(center),LA::vector_end(center));
+ }
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Construct_circumcenter_tag,(CartesianDKernelFunctors::Construct_circumcenter<K>),(Point_tag),(Construct_ttag<Point_tag>,Compute_point_cartesian_coordinate_tag,Scalar_product_tag,Squared_distance_to_origin_tag,Point_dimension_tag));
+
+namespace CartesianDKernelFunctors {
+template <class R_> struct Squared_circumradius : Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Squared_circumradius)
+ typedef typename Get_type<R_, FT_tag>::type result_type;
+ template <class Iter>
+ result_type operator()(Iter f, Iter e)const{
+ typename Get_functor<R_, Construct_circumcenter_tag>::type cc(this->kernel());
+ typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());
+ return sd(cc(f, e), *f);
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Squared_circumradius_tag,(CartesianDKernelFunctors::Squared_circumradius<K>),(Point_tag),(Construct_circumcenter_tag,Squared_distance_tag));
+
+namespace CartesianDKernelFunctors {
+// TODO: implement it directly, it should be at least as fast as Side_of_oriented_sphere.
+template<class R_> struct Side_of_bounded_sphere : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Side_of_bounded_sphere)
+ typedef R_ R;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Bounded_side_tag>::type result_type;
+
+ template<class Iter>
+ result_type operator()(Iter f, Iter const& e) const {
+ Point const& p0 = *f++; // *--e ?
+ typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
+ //FIXME: Doesn't work for non-full dimension.
+ CGAL_assertion (std::distance(f,e) == pd(p0)+1);
+ return operator() (f, e, p0);
+ }
+
+ template<class Iter>
+ result_type operator()(Iter const& f, Iter const& e, Point const& p0) const {
+ typename Get_functor<R, Side_of_oriented_sphere_tag>::type sos (this->kernel());
+ typename Get_functor<R, Orientation_of_points_tag>::type op (this->kernel());
+ // enum_cast is not very generic, but since this function isn't supposed to remain like this...
+ return enum_cast<Bounded_side> (sos (f, e, p0) * op (f, e));
+ }
+
+#ifdef CGAL_CXX11
+ template <class...U,class=typename std::enable_if<(sizeof...(U)>=4)>::type>
+ result_type operator()(U&&...u) const {
+ return operator()({std::forward<U>(u)...});
+ }
+
+ template <class P>
+ result_type operator()(std::initializer_list<P> l) const {
+ return operator()(l.begin(),l.end());
+ }
+#else
+ //TODO
+#endif
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Side_of_bounded_sphere_tag,(CartesianDKernelFunctors::Side_of_bounded_sphere<K>),(Point_tag),(Side_of_oriented_sphere_tag,Orientation_of_points_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Side_of_bounded_circumsphere : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Side_of_bounded_circumsphere)
+ typedef typename Get_type<R_, Bounded_side_tag>::type result_type;
+
+ template<class Iter, class P>
+ result_type operator()(Iter f, Iter const& e, P const& p0) const {
+ // TODO: Special case when the dimension is full.
+ typename Get_functor<R_, Construct_circumcenter_tag>::type cc(this->kernel());
+ typename Get_functor<R_, Compare_distance_tag>::type cd(this->kernel());
+
+ return enum_cast<Bounded_side>(cd(cc(f, e), *f, p0));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Side_of_bounded_circumsphere_tag,(CartesianDKernelFunctors::Side_of_bounded_circumsphere<K>),(Point_tag),(Squared_distance_tag,Construct_circumcenter_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Point_to_vector : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Point_to_vector)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
+ typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
+ typedef Vector result_type;
+ typedef Point argument_type;
+ result_type operator()(argument_type const&v)const{
+ CI ci(this->kernel());
+ return CV(this->kernel())(ci(v,Begin_tag()),ci(v,End_tag()));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Point_to_vector_tag,(CartesianDKernelFunctors::Point_to_vector<K>),(Point_tag,Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Point_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Vector_to_point : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Vector_to_point)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_functor<R, Construct_ttag<Point_tag> >::type CP;
+ typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
+ typedef Point result_type;
+ typedef Vector argument_type;
+ result_type operator()(argument_type const&v)const{
+ CI ci(this->kernel());
+ return CP(this->kernel())(ci(v,Begin_tag()),ci(v,End_tag()));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Vector_to_point_tag,(CartesianDKernelFunctors::Vector_to_point<K>),(Point_tag,Vector_tag),(Construct_ttag<Point_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Opposite_vector : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Opposite_vector)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
+ typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
+ typedef Vector result_type;
+ typedef Vector argument_type;
+ result_type operator()(Vector const&v)const{
+ CI ci(this->kernel());
+ return CV(this->kernel())(make_transforming_iterator(ci(v,Begin_tag()),std::negate<RT>()),make_transforming_iterator(ci(v,End_tag()),std::negate<RT>()));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Opposite_vector_tag,(CartesianDKernelFunctors::Opposite_vector<K>),(Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Scaled_vector : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Scaled_vector)
+ typedef R_ R;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
+ typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
+ typedef Vector result_type;
+ typedef Vector first_argument_type;
+ typedef FT second_argument_type;
+ result_type operator()(Vector const&v,FT const& s)const{
+ CI ci(this->kernel());
+ return CV(this->kernel())(make_transforming_iterator(ci(v,Begin_tag()),Scale<FT>(s)),make_transforming_iterator(ci(v,End_tag()),Scale<FT>(s)));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Scaled_vector_tag,(CartesianDKernelFunctors::Scaled_vector<K>),(Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Sum_of_vectors : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Sum_of_vectors)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
+ typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
+ typedef Vector result_type;
+ typedef Vector first_argument_type;
+ typedef Vector second_argument_type;
+ result_type operator()(Vector const&a, Vector const&b)const{
+ CI ci(this->kernel());
+ return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::plus<RT>()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::plus<RT>()));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Sum_of_vectors_tag,(CartesianDKernelFunctors::Sum_of_vectors<K>),(Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Difference_of_vectors : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Difference_of_vectors)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
+ typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
+ typedef Vector result_type;
+ typedef Vector first_argument_type;
+ typedef Vector second_argument_type;
+ result_type operator()(Vector const&a, Vector const&b)const{
+ CI ci(this->kernel());
+ return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::minus<RT>()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::minus<RT>()));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Difference_of_vectors_tag,(CartesianDKernelFunctors::Difference_of_vectors<K>),(Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Translated_point : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Translated_point)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_functor<R, Construct_ttag<Point_tag> >::type CP;
+ typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CVI;
+ typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CPI;
+ typedef Point result_type;
+ typedef Point first_argument_type;
+ typedef Vector second_argument_type;
+ result_type operator()(Point const&a, Vector const&b)const{
+ CVI cvi(this->kernel());
+ CPI cpi(this->kernel());
+ return CP(this->kernel())(make_transforming_pair_iterator(cpi(a,Begin_tag()),cvi(b,Begin_tag()),std::plus<RT>()),make_transforming_pair_iterator(cpi(a,End_tag()),cvi(b,End_tag()),std::plus<RT>()));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Translated_point_tag,(CartesianDKernelFunctors::Translated_point<K>),(Point_tag, Vector_tag),(Construct_ttag<Point_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>, Construct_ttag<Point_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Difference_of_points : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Difference_of_points)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
+ typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
+ typedef Vector result_type;
+ typedef Point first_argument_type;
+ typedef Point second_argument_type;
+ result_type operator()(Point const&a, Point const&b)const{
+ CI ci(this->kernel());
+ return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::minus<RT>()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::minus<RT>()));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Difference_of_points_tag,(CartesianDKernelFunctors::Difference_of_points<K>),(Point_tag, Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Point_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Midpoint : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Midpoint)
+ typedef R_ R;
+ typedef typename Get_type<R, FT_tag>::type FT;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_functor<R, Construct_ttag<Point_tag> >::type CP;
+ typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
+ typedef Point result_type;
+ typedef Point first_argument_type;
+ typedef Point second_argument_type;
+ // There is a division, but it will be cast to RT afterwards anyway, so maybe we could use RT.
+ struct Average : std::binary_function<FT,RT,FT> {
+ FT operator()(FT const&a, RT const&b)const{
+ return (a+b)/2;
+ }
+ };
+ result_type operator()(Point const&a, Point const&b)const{
+ CI ci(this->kernel());
+ //Divide<FT,int> half(2);
+ //return CP(this->kernel())(make_transforming_iterator(make_transforming_pair_iterator(ci.begin(a),ci.begin(b),std::plus<FT>()),half),make_transforming_iterator(make_transforming_pair_iterator(ci.end(a),ci.end(b),std::plus<FT>()),half));
+ return CP(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),Average()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),Average()));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Midpoint_tag,(CartesianDKernelFunctors::Midpoint<K>),(Point_tag),(Construct_ttag<Point_tag>, Construct_ttag<Point_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Squared_length : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Squared_length)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
+ typedef RT result_type;
+ typedef Vector argument_type;
+ result_type operator()(Vector const&a)const{
+ CI ci(this->kernel());
+ typename Algebraic_structure_traits<RT>::Square f;
+ // TODO: avoid this RT(0)+...
+ return std::accumulate(make_transforming_iterator(ci(a,Begin_tag()),f),make_transforming_iterator(ci(a,End_tag()),f),RT(0));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Squared_length_tag,(CartesianDKernelFunctors::Squared_length<K>),(Vector_tag),(Construct_ttag<Vector_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Squared_distance_to_origin : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Squared_distance_to_origin)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
+ typedef RT result_type;
+ typedef Point argument_type;
+ result_type operator()(Point const&a)const{
+ CI ci(this->kernel());
+ typename Algebraic_structure_traits<RT>::Square f;
+ // TODO: avoid this RT(0)+...
+ return std::accumulate(make_transforming_iterator(ci(a,Begin_tag()),f),make_transforming_iterator(ci(a,End_tag()),f),RT(0));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Squared_distance_to_origin_tag,(CartesianDKernelFunctors::Squared_distance_to_origin<K>),(Point_tag),(Construct_ttag<Point_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Squared_distance : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Squared_distance)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
+ typedef RT result_type;
+ typedef Point first_argument_type;
+ typedef Point second_argument_type;
+ struct Sq_diff : std::binary_function<RT,RT,RT> {
+ RT operator()(RT const&a, RT const&b)const{
+ return CGAL::square(a-b);
+ }
+ };
+ result_type operator()(Point const&a, Point const&b)const{
+ CI ci(this->kernel());
+ Sq_diff f;
+ // TODO: avoid this RT(0)+...
+ return std::accumulate(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),f),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),f),RT(0));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Squared_distance_tag,(CartesianDKernelFunctors::Squared_distance<K>),(Point_tag),(Construct_ttag<Point_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Scalar_product : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Scalar_product)
+ typedef R_ R;
+ typedef typename Get_type<R, RT_tag>::type RT;
+ typedef typename Get_type<R, Vector_tag>::type Vector;
+ typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
+ typedef RT result_type;
+ typedef Vector first_argument_type;
+ typedef Vector second_argument_type;
+ result_type operator()(Vector const&a, Vector const&b)const{
+ CI ci(this->kernel());
+ std::multiplies<RT> f;
+ // TODO: avoid this RT(0)+...
+ return std::accumulate(
+ make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),f),
+ make_transforming_pair_iterator(ci(a, End_tag()),ci(b, End_tag()),f),
+ RT(0));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Scalar_product_tag,(CartesianDKernelFunctors::Scalar_product<K>),(Vector_tag),(Construct_ttag<Vector_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Compare_distance : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Compare_distance)
+ typedef R_ R;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_functor<R, Squared_distance_tag>::type CSD;
+ typedef typename Get_type<R, Comparison_result_tag>::type result_type;
+ typedef Point first_argument_type;
+ typedef Point second_argument_type;
+ typedef Point third_argument_type; // why am I doing this already?
+ typedef Point fourth_argument_type;
+ result_type operator()(Point const&a, Point const&b, Point const&c)const{
+ CSD csd(this->kernel());
+ return CGAL_NTS compare(csd(a,b),csd(a,c));
+ }
+ result_type operator()(Point const&a, Point const&b, Point const&c, Point const&d)const{
+ CSD csd(this->kernel());
+ return CGAL_NTS compare(csd(a,b),csd(c,d));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Compare_distance_tag,(CartesianDKernelFunctors::Compare_distance<K>),(Point_tag),(Squared_distance_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Less_point_cartesian_coordinate : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Less_point_cartesian_coordinate)
+ typedef R_ R;
+ typedef typename Get_type<R, Bool_tag>::type result_type;
+ typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type Cc;
+ // TODO: This is_exact thing should be reengineered.
+ // the goal is to have a way to tell: don't filter this
+ typedef typename CGAL::Is_exact<Cc> Is_exact;
+
+ template<class V,class W,class I>
+ result_type operator()(V const&a, W const&b, I i)const{
+ Cc c(this->kernel());
+ return c(a,i)<c(b,i);
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Less_point_cartesian_coordinate_tag,(CartesianDKernelFunctors::Less_point_cartesian_coordinate<K>),(),(Compute_point_cartesian_coordinate_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Compare_point_cartesian_coordinate : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Compare_point_cartesian_coordinate)
+ typedef R_ R;
+ typedef typename Get_type<R, Comparison_result_tag>::type result_type;
+ typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type Cc;
+ // TODO: This is_exact thing should be reengineered.
+ // the goal is to have a way to tell: don't filter this
+ typedef typename CGAL::Is_exact<Cc> Is_exact;
+
+ template<class V,class W,class I>
+ result_type operator()(V const&a, W const&b, I i)const{
+ Cc c(this->kernel());
+ return CGAL_NTS compare(c(a,i),c(b,i));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Compare_point_cartesian_coordinate_tag,(CartesianDKernelFunctors::Compare_point_cartesian_coordinate<K>),(),(Compute_point_cartesian_coordinate_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Compare_lexicographically : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Compare_lexicographically)
+ typedef R_ R;
+ typedef typename Get_type<R, Comparison_result_tag>::type result_type;
+ typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
+ // TODO: This is_exact thing should be reengineered.
+ // the goal is to have a way to tell: don't filter this
+ typedef typename CGAL::Is_exact<CI> Is_exact;
+
+ template<class V,class W>
+ result_type operator()(V const&a, W const&b)const{
+ CI c(this->kernel());
+#ifdef CGAL_CXX11
+ auto
+#else
+ typename CI::result_type
+#endif
+ a_begin=c(a,Begin_tag()),
+ b_begin=c(b,Begin_tag()),
+ a_end=c(a,End_tag());
+ result_type res;
+ // can't we do slightly better for Uncertain<*> ?
+ // after res=...; if(is_uncertain(res))return indeterminate<result_type>();
+ do res=CGAL_NTS compare(*a_begin++,*b_begin++);
+ while(a_begin!=a_end && res==EQUAL);
+ return res;
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Compare_lexicographically_tag,(CartesianDKernelFunctors::Compare_lexicographically<K>),(),(Construct_ttag<Point_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Less_lexicographically : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Less_lexicographically)
+ typedef R_ R;
+ typedef typename Get_type<R, Bool_tag>::type result_type;
+ typedef typename Get_functor<R, Compare_lexicographically_tag>::type CL;
+ typedef typename CGAL::Is_exact<CL> Is_exact;
+
+ template <class V, class W>
+ result_type operator() (V const&a, W const&b) const {
+ CL c (this->kernel());
+ return c(a,b) < 0;
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Less_lexicographically_tag,(CartesianDKernelFunctors::Less_lexicographically<K>),(),(Compare_lexicographically_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Less_or_equal_lexicographically : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Less_or_equal_lexicographically)
+ typedef R_ R;
+ typedef typename Get_type<R, Bool_tag>::type result_type;
+ typedef typename Get_functor<R, Compare_lexicographically_tag>::type CL;
+ typedef typename CGAL::Is_exact<CL> Is_exact;
+
+ template <class V, class W>
+ result_type operator() (V const&a, W const&b) const {
+ CL c (this->kernel());
+ return c(a,b) <= 0;
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Less_or_equal_lexicographically_tag,(CartesianDKernelFunctors::Less_or_equal_lexicographically<K>),(),(Compare_lexicographically_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Equal_points : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Equal_points)
+ typedef R_ R;
+ typedef typename Get_type<R, Bool_tag>::type result_type;
+ typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
+ // TODO: This is_exact thing should be reengineered.
+ // the goal is to have a way to tell: don't filter this
+ typedef typename CGAL::Is_exact<CI> Is_exact;
+
+ template<class V,class W>
+ result_type operator()(V const&a, W const&b)const{
+ CI c(this->kernel());
+#ifdef CGAL_CXX11
+ auto
+#else
+ typename CI::result_type
+#endif
+ a_begin=c(a,Begin_tag()),
+ b_begin=c(b,Begin_tag()),
+ a_end=c(a,End_tag());
+ result_type res = true;
+ // Is using CGAL::possibly for Uncertain really an optimization?
+ do res = res & (*a_begin++ == *b_begin++);
+ while(a_begin!=a_end && possibly(res));
+ return res;
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Equal_points_tag,(CartesianDKernelFunctors::Equal_points<K>),(),(Construct_ttag<Point_cartesian_const_iterator_tag>));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Oriented_side : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Oriented_side)
+ typedef R_ R;
+ typedef typename Get_type<R, Oriented_side_tag>::type result_type;
+ typedef typename Get_type<R, Point_tag>::type Point;
+ typedef typename Get_type<R, Hyperplane_tag>::type Hyperplane;
+ typedef typename Get_type<R, Sphere_tag>::type Sphere;
+ typedef typename Get_functor<R, Value_at_tag>::type VA;
+ typedef typename Get_functor<R, Hyperplane_translation_tag>::type HT;
+ typedef typename Get_functor<R, Squared_distance_tag>::type SD;
+ typedef typename Get_functor<R, Squared_radius_tag>::type SR;
+ typedef typename Get_functor<R, Center_of_sphere_tag>::type CS;
+
+ result_type operator()(Hyperplane const&h, Point const&p)const{
+ HT ht(this->kernel());
+ VA va(this->kernel());
+ return CGAL::compare(va(h,p),ht(h));
+ }
+ result_type operator()(Sphere const&s, Point const&p)const{
+ SD sd(this->kernel());
+ SR sr(this->kernel());
+ CS cs(this->kernel());
+ return CGAL::compare(sd(cs(s),p),sr(s));
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Oriented_side_tag,(CartesianDKernelFunctors::Oriented_side<K>),(Point_tag,Sphere_tag,Hyperplane_tag),(Value_at_tag,Hyperplane_translation_tag,Squared_distance_tag,Squared_radius_tag,Center_of_sphere_tag));
+
+namespace CartesianDKernelFunctors {
+template<class R_> struct Has_on_positive_side : private Store_kernel<R_> {
+ CGAL_FUNCTOR_INIT_STORE(Has_on_positive_side)
+ typedef R_ R;
+ typedef typename Get_type<R, Bool_tag>::type result_type;
+ typedef typename Get_functor<R, Oriented_side_tag>::type OS;
+
+ template <class Obj, class Pt>
+ result_type operator()(Obj const&o, Pt const&p)const{
+ OS os(this->kernel());
+ return os(o,p) == ON_POSITIVE_SIDE;
+ }
+};
+}
+
+CGAL_KD_DEFAULT_FUNCTOR(Has_on_positive_side_tag,(CartesianDKernelFunctors::Has_on_positive_side<K>),(),(Oriented_side_tag));
+
+}
+#include <CGAL/NewKernel_d/Coaffine.h>
+#endif // CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/functor_properties.h b/include/gudhi_patches/CGAL/NewKernel_d/functor_properties.h
new file mode 100644
index 00000000..c25c4e2b
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/functor_properties.h
@@ -0,0 +1,40 @@
+// 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_EXACTNESS_H
+#define CGAL_EXACTNESS_H
+#include <boost/mpl/has_xxx.hpp>
+#include <CGAL/tags.h>
+namespace CGAL {
+
+#define CGAL_STRAWBERRY(Is_pretty) \
+ namespace internal { \
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(Is_pretty) \
+ } \
+ template<class T,bool=internal::has_##Is_pretty<T>::value> \
+ struct Is_pretty : boost::false_type {}; \
+ template<class T> \
+ struct Is_pretty<T,true> : T::Is_pretty {}
+
+CGAL_STRAWBERRY(Is_exact);
+CGAL_STRAWBERRY(Is_fast);
+CGAL_STRAWBERRY(Is_stored);
+#undef CGAL_STRAWBERRY
+}
+#endif // CGAL_EXACTNESS_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/functor_tags.h b/include/gudhi_patches/CGAL/NewKernel_d/functor_tags.h
new file mode 100644
index 00000000..b8e17886
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/functor_tags.h
@@ -0,0 +1,363 @@
+// 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_FUNCTOR_TAGS_H
+#define CGAL_FUNCTOR_TAGS_H
+#include <CGAL/tags.h> // for Null_tag
+#include <CGAL/NewKernel_d/utils.h>
+#ifdef CGAL_CXX11
+#include <type_traits>
+#include <utility>
+#endif
+#include <boost/type_traits.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/empty.hpp>
+#include <boost/mpl/front.hpp>
+#include <boost/mpl/pop_front.hpp>
+namespace CGAL {
+
+ // Find a better place for this later
+
+ template <class K, class T, class=void> struct Get_type
+ : K::template Type<T> {};
+ template <class K, class F, class O=void, class=void> struct Get_functor
+ : K::template Functor<F, O> {};
+#ifdef CGAL_CXX11
+ template <class K, class T> using Type = typename Get_type<K, T>::type;
+ template <class K, class T> using Functor = typename Get_functor<K, T>::type;
+#endif
+
+ class Null_type {~Null_type();}; // no such object should be created
+
+ // To construct iterators
+ struct Begin_tag {};
+ struct End_tag {};
+
+ // Functor category
+ struct Predicate_tag {};
+ struct Construct_tag {};
+ struct Construct_iterator_tag {};
+ struct Compute_tag {};
+ struct Misc_tag {};
+
+ struct No_filter_tag {};
+
+ template<class>struct Construct_ttag {};
+ template<class>struct Convert_ttag {};
+
+ template <class K, class F, class=void, class=void> struct Get_functor_category { typedef Misc_tag type; };
+ template<class Tg, class Obj, class Base> struct Typedef_tag_type;
+ //template<class Kernel, class Tg> struct Read_tag_type {};
+
+ template<class Kernel, class Tg>
+ struct Provides_type
+ : Has_type_different_from<Get_type<Kernel, Tg>, Null_type> {};
+
+ template<class Kernel, class Tg, class O=void>
+ struct Provides_functor
+ : Has_type_different_from<Get_functor<Kernel, Tg, O>, Null_functor> {};
+
+ template<class K, class List, bool=boost::mpl::empty<List>::type::value>
+ struct Provides_functors : boost::mpl::and_ <
+ Provides_functor<K, typename boost::mpl::front<List>::type>,
+ Provides_functors<K, typename boost::mpl::pop_front<List>::type> > {};
+ template<class K, class List>
+ struct Provides_functors<K, List, true> : boost::true_type {};
+
+ template<class K, class List, bool=boost::mpl::empty<List>::type::value>
+ struct Provides_types : boost::mpl::and_ <
+ Provides_type<K, typename boost::mpl::front<List>::type>,
+ Provides_types<K, typename boost::mpl::pop_front<List>::type> > {};
+ template<class K, class List>
+ struct Provides_types<K, List, true> : boost::true_type {};
+
+ namespace internal { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_Type,template Type<Null_tag>,false) }
+ template<class Kernel, class Tg,
+ bool = internal::has_Type<Kernel>::value /* false */>
+ struct Provides_type_i : boost::false_type {};
+ template<class Kernel, class Tg>
+ struct Provides_type_i <Kernel, Tg, true>
+ : Has_type_different_from<typename Kernel::template Type<Tg>, Null_type> {};
+
+ //// This version does not like Functor<T,bool=false>
+ //namespace internal { BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_Functor,Functor,false) }
+ // This version lets us use non-type template parameters, but fails with older EDG-based compilers (Intel 14).
+ namespace internal { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_Functor,template Functor<Null_tag>,false) }
+
+ template<class Kernel, class Tg, class O=void,
+ bool = internal::has_Functor<Kernel>::value /* false */>
+ struct Provides_functor_i : boost::false_type {};
+ template<class Kernel, class Tg, class O>
+ struct Provides_functor_i <Kernel, Tg, O, true>
+ : Has_type_different_from<typename Kernel::template Functor<Tg, O>, Null_functor> {};
+
+ // TODO: Refine this a bit.
+ template <class K, class T, class D=void,
+ //bool=Provides_functor<K,T>::value,
+ //bool=Provides_functor_i<K,T>::value,
+ bool = internal::has_Functor<K>::value
+ >
+ struct Inherit_functor : K::template Functor<T> {};
+ template <class K, class T, class D>
+ struct Inherit_functor <K, T, D, false> {};
+
+ template <class K, class T, bool=internal::has_Type<K>::value>
+ struct Inherit_type : K::template Type<T> {};
+ template <class K, class T>
+ struct Inherit_type <K, T, false> {};
+
+ struct Number_tag {};
+ struct Discrete_tag {};
+ struct Object_tag {};
+ template <class K, class T, class=void> struct Get_type_category {
+ // The lazy kernel uses it too eagerly,
+ // so it currently needs a default.
+ typedef Null_tag type;
+ };
+
+#define CGAL_DECL_OBJ_(X,Y) \
+ template<class Obj,class Base> \
+ struct Typedef_tag_type<X##_tag, Obj, Base> : Base { typedef Obj X; }; \
+ template<class K, class D> \
+ struct Get_type_category <K, X##_tag, D> { typedef Y##_tag type; }
+#define CGAL_DECL_OBJ(X,Y) struct X##_tag {}; \
+ CGAL_DECL_OBJ_(X,Y)
+
+ //namespace has_object { BOOST_MPL_HAS_XXX_TRAIT_DEF(X) }
+ //template<class Kernel>
+ //struct Provides_tag_type<Kernel, X##_tag> : has_object::has_##X<Kernel> {};
+ //template<class Kernel>
+ //struct Read_tag_type<Kernel, X##_tag> { typedef typename Kernel::X type; }
+
+ // Not exactly objects, but the extras can't hurt.
+ CGAL_DECL_OBJ(FT, Number);
+ CGAL_DECL_OBJ(RT, Number);
+
+ CGAL_DECL_OBJ(Bool, Discrete); // Boolean_tag is already taken, and is a template :-(
+ CGAL_DECL_OBJ(Comparison_result, Discrete);
+ CGAL_DECL_OBJ(Sign, Discrete);
+ CGAL_DECL_OBJ(Orientation, Discrete); // Note: duplicate with the functor tag!
+ CGAL_DECL_OBJ(Oriented_side, Discrete);
+ CGAL_DECL_OBJ(Bounded_side, Discrete);
+ CGAL_DECL_OBJ(Angle, Discrete);
+ CGAL_DECL_OBJ(Flat_orientation, Discrete);
+
+ CGAL_DECL_OBJ(Vector, Object);
+ CGAL_DECL_OBJ(Point, Object);
+ CGAL_DECL_OBJ(Segment, Object);
+ CGAL_DECL_OBJ(Sphere, Object);
+ CGAL_DECL_OBJ(Line, Object);
+ CGAL_DECL_OBJ(Direction, Object);
+ CGAL_DECL_OBJ(Hyperplane, Object);
+ CGAL_DECL_OBJ(Ray, Object);
+ CGAL_DECL_OBJ(Iso_box, Object);
+ CGAL_DECL_OBJ(Bbox, Object);
+ CGAL_DECL_OBJ(Aff_transformation, Object);
+ CGAL_DECL_OBJ(Weighted_point, Object);
+#undef CGAL_DECL_OBJ_
+#undef CGAL_DECL_OBJ
+
+// Intel fails with those, and they are not so useful.
+// CGAL_KD_DEFAULT_TYPE(RT_tag,(typename Get_type<K, FT_tag>::type),(),());
+// CGAL_KD_DEFAULT_TYPE(FT_tag,(CGAL::Quotient<typename Get_type<K, RT_tag>::type>),(),());
+
+#define CGAL_SMURF2(A,B) CGAL_KD_DEFAULT_TYPE(A##_tag,(typename Same_uncertainty_nt<B, typename Get_type<K,RT_tag>::type>::type),(RT_tag),())
+#define CGAL_SMURF1(A) CGAL_SMURF2(A,CGAL::A)
+ CGAL_SMURF2(Bool, bool);
+ CGAL_SMURF1(Sign);
+ CGAL_SMURF1(Comparison_result);
+ CGAL_SMURF1(Orientation);
+ CGAL_SMURF1(Oriented_side);
+ CGAL_SMURF1(Bounded_side);
+ CGAL_SMURF1(Angle);
+#undef CGAL_SMURF1
+#undef CGAL_SMURF2
+
+ // TODO: replace with Get_type_category
+ template<class> struct is_NT_tag { enum { value = false }; };
+ template<> struct is_NT_tag<FT_tag> { enum { value = true }; };
+ template<> struct is_NT_tag<RT_tag> { enum { value = true }; };
+
+ template<class> struct iterator_tag_traits {
+ enum { is_iterator = false, has_nth_element = false };
+ typedef Null_tag value_tag;
+ };
+
+#define CGAL_DECL_COMPUTE(X) struct X##_tag {}; \
+ template<class A,class B,class C>struct Get_functor_category<A,X##_tag,B,C>{typedef Compute_tag type;}
+ CGAL_DECL_COMPUTE(Compute_point_cartesian_coordinate);
+ CGAL_DECL_COMPUTE(Compute_vector_cartesian_coordinate);
+ CGAL_DECL_COMPUTE(Compute_homogeneous_coordinate);
+ CGAL_DECL_COMPUTE(Squared_distance);
+ CGAL_DECL_COMPUTE(Squared_distance_to_origin);
+ CGAL_DECL_COMPUTE(Squared_length);
+ CGAL_DECL_COMPUTE(Squared_radius);
+ CGAL_DECL_COMPUTE(Squared_circumradius);
+ CGAL_DECL_COMPUTE(Scalar_product);
+ CGAL_DECL_COMPUTE(Hyperplane_translation);
+ CGAL_DECL_COMPUTE(Value_at);
+ CGAL_DECL_COMPUTE(Point_weight);
+ CGAL_DECL_COMPUTE(Power_distance);
+ CGAL_DECL_COMPUTE(Power_distance_to_point);
+#undef CGAL_DECL_COMPUTE
+
+#define CGAL_DECL_ITER_OBJ(X,Y,Z,C) struct X##_tag {}; \
+ template<>struct iterator_tag_traits<X##_tag> { \
+ enum { is_iterator = true, has_nth_element = true }; \
+ typedef Y##_tag value_tag; \
+ typedef Z##_tag nth_element; \
+ typedef C##_tag container; \
+ }; \
+ template<class Obj,class Base> \
+ struct Typedef_tag_type<X##_tag, Obj, Base> : Base { typedef Obj X; }
+
+ //namespace has_object { BOOST_MPL_HAS_XXX_TRAIT_DEF(X) }
+ //template<class Kernel>
+ //struct Provides_tag_type<Kernel, X##_tag> : has_object::has_##X<Kernel> {};
+ //template<class Kernel>
+ //struct Read_tag_type<Kernel, X##_tag> { typedef typename Kernel::X type; }
+
+ CGAL_DECL_ITER_OBJ(Vector_cartesian_const_iterator, FT, Compute_vector_cartesian_coordinate, Vector);
+ CGAL_DECL_ITER_OBJ(Point_cartesian_const_iterator, FT, Compute_point_cartesian_coordinate, Point);
+#undef CGAL_DECL_ITER_OBJ
+
+ template<class>struct map_result_tag{typedef Null_type type;};
+ template<class T>struct map_result_tag<Construct_ttag<T> >{typedef T type;};
+
+ template<class A,class T,class B,class C>struct Get_functor_category<A,Construct_ttag<T>,B,C> :
+ boost::mpl::if_c<iterator_tag_traits<T>::is_iterator,
+ Construct_iterator_tag,
+ Construct_tag> {};
+
+ // Really?
+ template<class A,class T,class B,class C>struct Get_functor_category<A,Convert_ttag<T>,B,C>{typedef Misc_tag type;};
+
+#define CGAL_DECL_CONSTRUCT(X,Y) struct X##_tag {}; \
+ template<>struct map_result_tag<X##_tag>{typedef Y##_tag type;}; \
+ template<class A,class B,class C>struct Get_functor_category<A,X##_tag,B,C>{typedef Construct_tag type;}
+ CGAL_DECL_CONSTRUCT(Midpoint,Point);
+ CGAL_DECL_CONSTRUCT(Center_of_sphere,Point);
+ CGAL_DECL_CONSTRUCT(Point_of_sphere,Point);
+ CGAL_DECL_CONSTRUCT(Segment_extremity,Point);
+ CGAL_DECL_CONSTRUCT(Sum_of_vectors,Vector);
+ CGAL_DECL_CONSTRUCT(Difference_of_vectors,Vector);
+ CGAL_DECL_CONSTRUCT(Opposite_vector,Vector);
+ CGAL_DECL_CONSTRUCT(Scaled_vector,Vector);
+ CGAL_DECL_CONSTRUCT(Orthogonal_vector,Vector);
+ CGAL_DECL_CONSTRUCT(Difference_of_points,Vector);
+ CGAL_DECL_CONSTRUCT(Translated_point,Point);
+ CGAL_DECL_CONSTRUCT(Point_to_vector,Vector);
+ CGAL_DECL_CONSTRUCT(Vector_to_point,Point);
+ CGAL_DECL_CONSTRUCT(Construct_min_vertex,Point);
+ CGAL_DECL_CONSTRUCT(Construct_max_vertex,Point);
+ CGAL_DECL_CONSTRUCT(Construct_circumcenter,Point);
+ CGAL_DECL_CONSTRUCT(Point_drop_weight,Point);
+ CGAL_DECL_CONSTRUCT(Power_center,Weighted_point);
+#undef CGAL_DECL_CONSTRUCT
+#if 0
+#define CGAL_DECL_ITER_CONSTRUCT(X,Y) struct X##_tag {}; \
+ template<>struct map_result_tag<X##_tag>{typedef Y##_tag type;}; \
+ template<>struct map_functor_type<X##_tag>{typedef Construct_iterator_tag type;}
+ CGAL_DECL_ITER_CONSTRUCT(Construct_point_cartesian_const_iterator,Point_cartesian_const_iterator);
+ CGAL_DECL_ITER_CONSTRUCT(Construct_vector_cartesian_const_iterator,Vector_cartesian_const_iterator);
+#undef CGAL_DECL_ITER_CONSTRUCT
+#endif
+
+ //FIXME: choose a convention: prefix with Predicate_ ?
+#define CGAL_DECL_PREDICATE_(X) \
+ template<class A,class B,class C>struct Get_functor_category<A,X##_tag,B,C>{typedef Predicate_tag type;}
+#define CGAL_DECL_PREDICATE(X) struct X##_tag {}; \
+ CGAL_DECL_PREDICATE_(X)
+ CGAL_DECL_PREDICATE(Less_point_cartesian_coordinate);
+ CGAL_DECL_PREDICATE(Compare_point_cartesian_coordinate);
+ CGAL_DECL_PREDICATE(Compare_distance);
+ CGAL_DECL_PREDICATE(Compare_lexicographically);
+ CGAL_DECL_PREDICATE(Less_lexicographically);
+ CGAL_DECL_PREDICATE(Less_or_equal_lexicographically);
+ CGAL_DECL_PREDICATE(Equal_points);
+ CGAL_DECL_PREDICATE(Has_on_positive_side);
+ CGAL_DECL_PREDICATE_(Orientation); // duplicate with the type
+ CGAL_DECL_PREDICATE_(Oriented_side); // duplicate with the type
+ CGAL_DECL_PREDICATE(Orientation_of_points);
+ CGAL_DECL_PREDICATE(Orientation_of_vectors);
+ CGAL_DECL_PREDICATE(Side_of_oriented_sphere);
+ CGAL_DECL_PREDICATE(Side_of_bounded_sphere);
+ CGAL_DECL_PREDICATE(Side_of_bounded_circumsphere);
+ CGAL_DECL_PREDICATE(Contained_in_affine_hull);
+ CGAL_DECL_PREDICATE(In_flat_orientation);
+ CGAL_DECL_PREDICATE(In_flat_side_of_oriented_sphere);
+ CGAL_DECL_PREDICATE(Construct_flat_orientation); // Making it a predicate is a questionable choice, it should be possible to let it be a construction for some implementations. Not sure how to do that... TODO
+ CGAL_DECL_PREDICATE(Linear_rank);
+ CGAL_DECL_PREDICATE(Affine_rank);
+ CGAL_DECL_PREDICATE(Linearly_independent);
+ CGAL_DECL_PREDICATE(Affinely_independent);
+ CGAL_DECL_PREDICATE(Contained_in_linear_hull);
+ CGAL_DECL_PREDICATE(Contained_in_simplex);
+ CGAL_DECL_PREDICATE(Power_side_of_power_sphere_raw);
+ CGAL_DECL_PREDICATE(Power_side_of_power_sphere);
+ CGAL_DECL_PREDICATE(In_flat_power_side_of_power_sphere_raw);
+ CGAL_DECL_PREDICATE(In_flat_power_side_of_power_sphere);
+#undef CGAL_DECL_PREDICATE
+
+#define CGAL_DECL_MISC(X) struct X##_tag {}; \
+ template<class A,class B,class C>struct Get_functor_category<A,X##_tag,B,C>{typedef Misc_tag type;}
+ //TODO: split into _begin and _end ?
+ //CGAL_DECL_MISC(Construct_point_cartesian_const_iterator);
+ //CGAL_DECL_MISC(Construct_vector_cartesian_const_iterator);
+ CGAL_DECL_MISC(Point_dimension);
+ CGAL_DECL_MISC(Vector_dimension);
+ CGAL_DECL_MISC(Linear_base); // Find a more appropriate category?
+#undef CGAL_DECL_MISC
+
+
+ // Properties for LA
+ struct Has_extra_dimension_tag {};
+ struct Has_vector_plus_minus_tag {};
+ struct Has_vector_scalar_ops_tag {};
+ struct Has_dot_product_tag {};
+ struct Has_determinant_of_vectors_tag {};
+ struct Has_determinant_of_points_tag {};
+ struct Has_determinant_of_iterator_to_vectors_tag {};
+ struct Has_determinant_of_iterator_to_points_tag {};
+ struct Has_determinant_of_vectors_omit_last_tag {};
+ struct Stores_squared_norm_tag {};
+
+ template<class> struct Preserved_by_non_linear_extra_coordinate
+ : boost::false_type {};
+ template<> struct Preserved_by_non_linear_extra_coordinate
+ <Has_extra_dimension_tag> : boost::true_type {};
+ template<> struct Preserved_by_non_linear_extra_coordinate
+ <Has_determinant_of_vectors_tag> : boost::true_type {};
+ template<> struct Preserved_by_non_linear_extra_coordinate
+ <Has_determinant_of_points_tag> : boost::true_type {};
+ template<> struct Preserved_by_non_linear_extra_coordinate
+ <Has_determinant_of_iterator_to_vectors_tag> : boost::true_type {};
+ template<> struct Preserved_by_non_linear_extra_coordinate
+ <Has_determinant_of_iterator_to_points_tag> : boost::true_type {};
+ template<> struct Preserved_by_non_linear_extra_coordinate
+ <Has_determinant_of_vectors_omit_last_tag> : boost::true_type {};
+
+ // Kernel properties
+ struct Point_stores_squared_distance_to_origin_tag {};
+
+}
+#endif // CGAL_FUNCTOR_TAGS_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/static_int.h b/include/gudhi_patches/CGAL/NewKernel_d/static_int.h
new file mode 100644
index 00000000..21858804
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/static_int.h
@@ -0,0 +1,61 @@
+// 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_STATIC_INT_H
+#define CGAL_STATIC_INT_H
+#include <CGAL/constant.h>
+
+namespace CGAL {
+template <class NT> struct static_zero {
+ operator NT() const { return constant<NT,0>(); }
+};
+template <class NT> struct static_one {
+ operator NT() const { return constant<NT,1>(); }
+};
+
+template <class NT> static_zero<NT> operator-(static_zero<NT>) { return static_zero<NT>(); }
+
+template <class NT> NT operator+(NT const& x, static_zero<NT>) { return x; }
+template <class NT> NT operator+(static_zero<NT>, NT const& x) { return x; }
+template <class NT> static_zero<NT> operator+(static_zero<NT>, static_zero<NT>) { return static_zero<NT>(); }
+template <class NT> static_one<NT> operator+(static_zero<NT>, static_one<NT>) { return static_one<NT>(); }
+template <class NT> static_one<NT> operator+(static_one<NT>, static_zero<NT>) { return static_one<NT>(); }
+
+template <class NT> NT operator-(NT const& x, static_zero<NT>) { return x; }
+template <class NT> NT operator-(static_zero<NT>, NT const& x) { return -x; }
+template <class NT> static_zero<NT> operator-(static_zero<NT>, static_zero<NT>) { return static_zero<NT>(); }
+template <class NT> static_zero<NT> operator-(static_one<NT>, static_one<NT>) { return static_zero<NT>(); }
+template <class NT> static_one<NT> operator-(static_one<NT>, static_zero<NT>) { return static_one<NT>(); }
+
+template <class NT> NT operator*(NT const& x, static_one<NT>) { return x; }
+template <class NT> NT operator*(static_one<NT>, NT const& x) { return x; }
+template <class NT> static_zero<NT> operator*(NT const&, static_zero<NT>) { return static_zero<NT>(); }
+template <class NT> static_zero<NT> operator*(static_zero<NT>, NT const&) { return static_zero<NT>(); }
+template <class NT> static_zero<NT> operator*(static_zero<NT>, static_zero<NT>) { return static_zero<NT>(); }
+template <class NT> static_one<NT> operator*(static_one<NT>, static_one<NT>) { return static_one<NT>(); }
+template <class NT> static_zero<NT> operator*(static_zero<NT>, static_one<NT>) { return static_zero<NT>(); }
+template <class NT> static_zero<NT> operator*(static_one<NT>, static_zero<NT>) { return static_zero<NT>(); }
+
+template <class NT> NT operator/(NT const& x, static_one<NT>) { return x; }
+template <class NT> static_zero<NT> operator/(static_zero<NT>, NT const&) { return static_zero<NT>(); }
+template <class NT> static_zero<NT> operator/(static_zero<NT>, static_one<NT>) { return static_zero<NT>(); }
+template <class NT> static_one<NT> operator/(static_one<NT>, static_one<NT>) { return static_one<NT>(); }
+
+}
+#endif // CGAL_STATIC_INT_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/store_kernel.h b/include/gudhi_patches/CGAL/NewKernel_d/store_kernel.h
new file mode 100644
index 00000000..253e1282
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/store_kernel.h
@@ -0,0 +1,104 @@
+// 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_STORE_KERNEL_H
+#define CGAL_STORE_KERNEL_H
+
+#include <CGAL/assertions.h>
+#include <boost/type_traits/is_empty.hpp>
+
+namespace CGAL {
+namespace internal {
+BOOST_MPL_HAS_XXX_TRAIT_DEF(Do_not_store_kernel)
+template<class T,bool=boost::is_empty<T>::value,bool=has_Do_not_store_kernel<T>::value> struct Do_not_store_kernel {
+ enum { value=false };
+ typedef Tag_false type;
+};
+template<class T> struct Do_not_store_kernel<T,true,false> {
+ enum { value=true };
+ typedef Tag_true type;
+};
+template<class T,bool b> struct Do_not_store_kernel<T,b,true> {
+ typedef typename T::Do_not_store_kernel type;
+ enum { value=type::value };
+};
+}
+
+template<class R_,bool=internal::Do_not_store_kernel<R_>::value>
+struct Store_kernel {
+ Store_kernel(){}
+ Store_kernel(R_ const&){}
+ enum { kernel_is_stored = false };
+ R_ kernel()const{return R_();}
+ typedef R_ reference_type;
+ void set_kernel(R_ const&){}
+};
+template<class R_>
+struct Store_kernel<R_,false> {
+ Store_kernel():rp(0){
+ CGAL_warning_msg(true,"I should know my kernel");
+ }
+ Store_kernel(R_ const& r):rp(&r){}
+ enum { kernel_is_stored = true };
+ R_ const& kernel()const{
+ CGAL_warning_msg(rp!=0,"I should know my kernel");
+ return *rp;
+ }
+ typedef R_ const& reference_type;
+ void set_kernel(R_ const&r){rp=&r;}
+ private:
+ R_ const* rp;
+};
+
+//For a second kernel. TODO: find something more elegant
+template<class R_,bool=internal::Do_not_store_kernel<R_>::value>
+struct Store_kernel2 {
+ Store_kernel2(){}
+ Store_kernel2(R_ const&){}
+ enum { kernel2_is_stored = false };
+ R_ kernel2()const{return R_();}
+ typedef R_ reference2_type;
+ void set_kernel2(R_ const&){}
+};
+template<class R_>
+struct Store_kernel2<R_,false> {
+ Store_kernel2(){
+ //CGAL_warning_msg(true,"I should know my kernel");
+ }
+ Store_kernel2(R_ const& r):rp(&r){}
+ enum { kernel2_is_stored = true };
+ R_ const& kernel2()const{
+ CGAL_warning_msg(rp==0,"I should know my kernel");
+ return *rp;
+ }
+ typedef R_ const& reference2_type;
+ void set_kernel2(R_ const&r){rp=&r;}
+ private:
+ R_ const* rp;
+};
+}
+#define CGAL_BASE_INIT(X,Y) \
+ X():Y(){} \
+ X(R_ const&r):Y(r){}
+#define CGAL_FUNCTOR_INIT_STORE(X) CGAL_BASE_INIT(X,Store_kernel<R_>)
+#define CGAL_FUNCTOR_INIT_IGNORE(X) \
+ X(){} \
+ X(R_ const&){}
+
+#endif // CGAL_STORE_KERNEL_H
diff --git a/include/gudhi_patches/CGAL/NewKernel_d/utils.h b/include/gudhi_patches/CGAL/NewKernel_d/utils.h
new file mode 100644
index 00000000..238a2230
--- /dev/null
+++ b/include/gudhi_patches/CGAL/NewKernel_d/utils.h
@@ -0,0 +1,306 @@
+// 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_MARCUTILS
+#define CGAL_MARCUTILS
+
+#include <CGAL/config.h>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4003) // not enough actual parameters for macro 'BOOST_PP_EXPAND_I'
+ // http://lists.boost.org/boost-users/2014/11/83291.php
+#endif
+
+#ifdef CGAL_CXX11
+#include <type_traits>
+#include <utility>
+#define CGAL_FORWARDABLE(T) T&&
+#define CGAL_FORWARD(T,t) std::forward<T>(t)
+#define CGAL_MOVE(t) std::move(t)
+#define CGAL_CONSTEXPR constexpr
+#else
+#define CGAL_FORWARDABLE(T) T const&
+#define CGAL_FORWARD(T,t) t
+#define CGAL_MOVE(t) t
+#define CGAL_CONSTEXPR
+#endif
+#include <boost/utility/enable_if.hpp>
+#include <boost/preprocessor/repetition.hpp>
+#include <CGAL/Rational_traits.h>
+#include <CGAL/tuple.h>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/type_traits.hpp>
+
+#ifdef CGAL_CXX11
+#define CGAL_BOOSTD std::
+#else
+#define CGAL_BOOSTD boost::
+#endif
+
+namespace CGAL {
+namespace internal {
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
+}
+
+template <class T, class No, bool=internal::has_type<T>::value /*false*/>
+struct Has_type_different_from : boost::false_type {};
+template <class T, class No>
+struct Has_type_different_from <T, No, true>
+: boost::mpl::not_<boost::is_same<typename T::type, No> > {};
+
+
+ template <class T> struct Wrap_type { typedef T type; };
+
+ // tell a function f(a,b,c) that its real argument is a(b,c)
+ struct Eval_functor {};
+
+ // forget the first argument. Useful to make something dependant
+ // (and thus usable in SFINAE), although that's not a great design.
+ template<class A,class B> struct Second_arg {
+ typedef B type;
+ };
+
+ // like std::forward, except for basic types where it does a cast, to
+ // avoid issues with narrowing conversions
+#ifdef CGAL_CXX11
+ template<class T,class U,class V> inline
+ typename std::conditional<std::is_arithmetic<T>::value&&std::is_arithmetic<typename std::remove_reference<U>::type>::value,T,U&&>::type
+ forward_safe(V&& u) { return std::forward<U>(u); }
+#else
+ template<class T,class U> inline U const& forward_safe(U const& u) {
+ return u;
+ }
+#endif
+
+#ifdef CGAL_CXX11
+ template<class...> struct Constructible_from_each;
+ template<class To,class From1,class...From> struct Constructible_from_each<To,From1,From...>{
+ enum { value=std::is_convertible<From1,To>::value&&Constructible_from_each<To,From...>::value };
+ };
+ template<class To> struct Constructible_from_each<To>{
+ enum { value=true };
+ };
+#else
+// currently only used in C++0X code
+#endif
+
+ template<class T> struct Scale {
+#ifndef CGAL_CXX11
+ template<class> struct result;
+ template<class FT> struct result<Scale(FT)> {
+ typedef FT type;
+ };
+#endif
+ T const& scale;
+ Scale(T const& t):scale(t){}
+ template<class FT>
+#ifdef CGAL_CXX11
+ auto operator()(FT&& x)const->decltype(scale*std::forward<FT>(x))
+#else
+ FT operator()(FT const& x)const
+#endif
+ {
+ return scale*CGAL_FORWARD(FT,x);
+ }
+ };
+ template<class NT,class T> struct Divide {
+#if !defined(CGAL_CXX11) || !defined(BOOST_RESULT_OF_USE_DECLTYPE)
+ // requires boost > 1.44
+ // shouldn't be needed with C++0X
+ //template<class> struct result;
+ //template<class FT> struct result<Divide(FT)> {
+ // typedef FT type;
+ //};
+ typedef NT result_type;
+#endif
+ T const& scale;
+ Divide(T const& t):scale(t){}
+ template<class FT>
+#ifdef CGAL_CXX11
+ //FIXME: gcc complains for Gmpq
+ //auto operator()(FT&& x)const->decltype(Rational_traits<NT>().make_rational(std::forward<FT>(x),scale))
+ NT operator()(FT&& x)const
+#else
+ NT operator()(FT const& x)const
+#endif
+ {
+ return Rational_traits<NT>().
+ make_rational(CGAL_FORWARD(FT,x),scale);
+ }
+ };
+
+ template <class NT> struct has_cheap_constructor : boost::is_arithmetic<NT>{};
+ template <bool p> struct has_cheap_constructor<Interval_nt<p> > {
+ enum { value=true };
+ };
+
+ // like std::multiplies but allows mixing types
+ // in C++11 in doesn't need to be a template
+ template < class Ret >
+ struct multiplies {
+ template<class A,class B>
+#ifdef CGAL_CXX11
+ auto operator()(A&&a,B&&b)const->decltype(std::forward<A>(a)*std::forward<B>(b))
+#else
+ Ret operator()(A const& a, B const& b)const
+#endif
+ {
+ return CGAL_FORWARD(A,a)*CGAL_FORWARD(B,b);
+ }
+ };
+ template < class Ret >
+ struct division {
+ template<class A,class B>
+#ifdef CGAL_CXX11
+ auto operator()(A&&a,B&&b)const->decltype(std::forward<A>(a)/std::forward<B>(b))
+#else
+ Ret operator()(A const& a, B const& b)const
+#endif
+ {
+ return CGAL_FORWARD(A,a)/CGAL_FORWARD(B,b);
+ }
+ };
+
+#ifdef CGAL_CXX11
+ using std::decay;
+#else
+ template<class T> struct decay : boost::remove_cv<typename boost::decay<T>::type> {};
+#endif
+
+ template<class T,class U> struct Type_copy_ref { typedef U type; };
+ template<class T,class U> struct Type_copy_ref<T&,U> { typedef U& type; };
+#ifdef CGAL_CXX11
+ template<class T,class U> struct Type_copy_ref<T&&,U> { typedef U&& type; };
+#endif
+ template<class T,class U> struct Type_copy_cv { typedef U type; };
+ template<class T,class U> struct Type_copy_cv<T const,U> { typedef U const type; };
+ template<class T,class U> struct Type_copy_cv<T volatile,U> { typedef U volatile type; };
+ template<class T,class U> struct Type_copy_cv<T const volatile,U> { typedef U const volatile type; };
+
+ template<class T,class U> struct Type_copy_cvref :
+ Type_copy_ref<T,typename Type_copy_cv<typename boost::remove_reference<T>::type,U>::type> {};
+
+ struct Dereference_functor {
+ template<class> struct result{};
+ template<class It> struct result<Dereference_functor(It)> {
+ typedef typename std::iterator_traits<It>::reference type;
+ };
+ template<class It> typename result<Dereference_functor(It)>::type
+ operator()(It const&i)const{
+ return *i;
+ }
+ };
+
+#ifdef CGAL_CXX11
+ template<int...> struct Indices{};
+ template<class> struct Next_increasing_indices;
+ template<int...I> struct Next_increasing_indices<Indices<I...> > {
+ typedef Indices<I...,sizeof...(I)> type;
+ };
+ template<int N> struct N_increasing_indices {
+ typedef typename Next_increasing_indices<typename N_increasing_indices<N-1>::type>::type type;
+ };
+ template<> struct N_increasing_indices<0> { typedef Indices<> type; };
+ namespace internal {
+ template<class F,class...U,int...I> inline typename std::result_of<F&&(U...)>::type
+ do_call_on_tuple_elements(F&&f, std::tuple<U...>&&t, Indices<I...>&&) {
+ return f(std::get<I>(std::move(t))...);
+ }
+ } // internal
+ template<class/*result type, ignored*/,class F,class...U>
+ inline typename std::result_of<F&&(U...)>::type
+ call_on_tuple_elements(F&&f, std::tuple<U...>&&t) {
+ return internal::do_call_on_tuple_elements(std::forward<F>(f),std::move(t),
+ typename N_increasing_indices<sizeof...(U)>::type());
+ }
+#else
+#define CGAL_VAR(Z,N,_) cpp0x::get<N>(t)
+#define CGAL_CODE(Z,N,_) template<class Res, class F BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N,class U)> \
+ inline Res call_on_tuple_elements(F const&f, \
+ cpp0x::tuple<BOOST_PP_ENUM_PARAMS(N,U)> const&t) { \
+ return f(BOOST_PP_ENUM(N,CGAL_VAR,)); \
+ }
+ template<class Res, class F>
+ inline Res call_on_tuple_elements(F const&f, cpp0x::tuple<>) {
+ return f();
+ }
+BOOST_PP_REPEAT_FROM_TO(1, 8, CGAL_CODE, _ )
+#undef CGAL_CODE
+#undef CGAL_VAR
+#endif
+
+ template<class A> struct Factory {
+ typedef A result_type;
+#ifdef CGAL_CXX11
+ template<class...U> result_type operator()(U&&...u)const{
+ return A(std::forward<U>(u)...);
+ }
+#else
+ result_type operator()()const{
+ return A();
+ }
+#define CGAL_CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> \
+ result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \
+ return A(BOOST_PP_ENUM_PARAMS(N,u)); \
+ }
+BOOST_PP_REPEAT_FROM_TO(1, 8, CGAL_CODE, _ )
+#undef CGAL_CODE
+#endif
+ };
+}
+
+// TODO: make a Cartesian-only variant
+// WARNING: do not use the Req* parameters too much, they can cause circular instanciations and are only useful for dispatching.
+#define CGAL_STRIP_PAREN_(...) __VA_ARGS__
+#define CGAL_STRIP_PAREN(...) CGAL_STRIP_PAREN_ __VA_ARGS__
+// What to do with O? pass it down to other functors or drop it?
+#define CGAL_KD_DEFAULT_FUNCTOR(Tg,Name,ReqTyp,ReqFun) \
+ template <class K, class O> \
+ struct Get_functor<K, Tg, O, \
+ typename boost::mpl::if_c< \
+ Provides_functor_i<K, Tg, O>::value \
+ || !Provides_types<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqTyp> >::value \
+ || !Provides_functors<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqFun> >::value \
+ , int, void>::type> \
+ { \
+ typedef CGAL_STRIP_PAREN_ Name type; \
+ typedef K Bound_kernel; \
+ }
+
+// Not used yet, may need some changes.
+#define CGAL_KD_DEFAULT_TYPE(Tg,Name,ReqTyp,ReqFun) \
+ template <class K> \
+ struct Get_type<K, Tg, \
+ typename boost::mpl::if_c< \
+ Provides_type_i<K, Tg>::value \
+ || !Provides_types<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqTyp> >::value \
+ || !Provides_functors<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqFun> >::value \
+ , int, void>::type> \
+ { \
+ typedef CGAL_STRIP_PAREN_ Name type; \
+ typedef K Bound_kernel; \
+ }
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif
diff --git a/include/gudhi_patches/CGAL/Orthogonal_incremental_neighbor_search.h b/include/gudhi_patches/CGAL/Orthogonal_incremental_neighbor_search.h
new file mode 100644
index 00000000..e29ce14f
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Orthogonal_incremental_neighbor_search.h
@@ -0,0 +1,620 @@
+// Copyright (c) 2002,2011 Utrecht University (The Netherlands).
+// 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) : Hans Tangelder (<hanst@cs.uu.nl>)
+
+#ifndef CGAL_ORTHOGONAL_INCREMENTAL_NEIGHBOR_SEARCH
+#define CGAL_ORTHOGONAL_INCREMENTAL_NEIGHBOR_SEARCH
+
+#include <CGAL/Kd_tree.h>
+#include <cstring>
+#include <list>
+#include <queue>
+#include <memory>
+#include <CGAL/Euclidean_distance.h>
+#include <CGAL/tuple.h>
+
+namespace CGAL {
+
+ template <class SearchTraits,
+ class Distance_= typename internal::Spatial_searching_default_distance<SearchTraits>::type,
+ class Splitter_ = Sliding_midpoint<SearchTraits>,
+ class Tree_= Kd_tree<SearchTraits, Splitter_, Tag_true> >
+ class Orthogonal_incremental_neighbor_search {
+
+ public:
+ typedef Splitter_ Splitter;
+ typedef Tree_ Tree;
+ typedef Distance_ Distance;
+ typedef typename SearchTraits::Point_d Point_d;
+ typedef typename Distance::Query_item Query_item;
+ typedef typename SearchTraits::FT FT;
+ typedef typename Tree::Point_d_iterator Point_d_iterator;
+ typedef typename Tree::Node_const_handle Node_const_handle;
+
+ typedef std::pair<Point_d,FT> Point_with_transformed_distance;
+ typedef CGAL::cpp11::tuple<Node_const_handle,FT,std::vector<FT> > Node_with_distance;
+ typedef std::vector<Node_with_distance*> Node_with_distance_vector;
+ typedef std::vector<Point_with_transformed_distance*> Point_with_transformed_distance_vector;
+
+ template<class T>
+ struct Object_wrapper
+ {
+ T object;
+ Object_wrapper(const T& t):object(t){}
+ const T& operator* () const { return object; }
+ const T* operator-> () const { return &object; }
+ };
+
+ class Iterator_implementation {
+ SearchTraits traits;
+ public:
+
+ int number_of_neighbours_computed;
+ int number_of_internal_nodes_visited;
+ int number_of_leaf_nodes_visited;
+ int number_of_items_visited;
+
+ private:
+
+ typedef std::vector<FT> Distance_vector;
+
+ Distance_vector dists;
+
+ Distance Orthogonal_distance_instance;
+
+ FT multiplication_factor;
+
+ Query_item query_point;
+
+ FT distance_to_root;
+
+ bool search_nearest_neighbour;
+
+ FT rd;
+
+
+ class Priority_higher {
+ public:
+
+ bool search_nearest;
+
+ Priority_higher(bool search_the_nearest_neighbour)
+ : search_nearest(search_the_nearest_neighbour)
+ {}
+
+ //highest priority is smallest distance
+ bool
+ operator() (Node_with_distance* n1, Node_with_distance* n2) const
+ {
+ return (search_nearest) ? (CGAL::cpp11::get<1>(*n1) > CGAL::cpp11::get<1>(*n2)) : (CGAL::cpp11::get<1>(*n2) > CGAL::cpp11::get<1>(*n1));
+ }
+ };
+
+ class Distance_smaller {
+
+ public:
+
+ bool search_nearest;
+
+ Distance_smaller(bool search_the_nearest_neighbour)
+ : search_nearest(search_the_nearest_neighbour)
+ {}
+
+ //highest priority is smallest distance
+ bool operator() (Point_with_transformed_distance* p1, Point_with_transformed_distance* p2) const
+ {
+ return (search_nearest) ? (p1->second > p2->second) : (p2->second > p1->second);
+ }
+ };
+
+
+ std::priority_queue<Node_with_distance*, Node_with_distance_vector,
+ Priority_higher> PriorityQueue;
+
+ public:
+ std::priority_queue<Point_with_transformed_distance*, Point_with_transformed_distance_vector,
+ Distance_smaller> Item_PriorityQueue;
+
+
+ public:
+
+ int reference_count;
+
+
+
+ // constructor
+ Iterator_implementation(const Tree& tree,const Query_item& q, const Distance& tr,
+ FT Eps=FT(0.0), bool search_nearest=true)
+ : traits(tree.traits()),number_of_neighbours_computed(0), number_of_internal_nodes_visited(0),
+ number_of_leaf_nodes_visited(0), number_of_items_visited(0),
+ Orthogonal_distance_instance(tr), multiplication_factor(Orthogonal_distance_instance.transformed_distance(FT(1.0)+Eps)),
+ query_point(q), search_nearest_neighbour(search_nearest),
+ PriorityQueue(Priority_higher(search_nearest)), Item_PriorityQueue(Distance_smaller(search_nearest)),
+ reference_count(1)
+
+
+ {
+ if (tree.empty()) return;
+
+ typename SearchTraits::Construct_cartesian_const_iterator_d ccci=traits.construct_cartesian_const_iterator_d_object();
+ int dim = static_cast<int>(std::distance(ccci(q), ccci(q,0)));
+
+ dists.resize(dim);
+ for(int i=0 ; i<dim ; ++i){
+ dists[i] = 0;
+ }
+
+ if (search_nearest){
+ distance_to_root=
+ Orthogonal_distance_instance.min_distance_to_rectangle(q, tree.bounding_box(),dists);
+ Node_with_distance *The_Root = new Node_with_distance(tree.root(),
+ distance_to_root, dists);
+ PriorityQueue.push(The_Root);
+
+ // rd is the distance of the top of the priority queue to q
+ rd=CGAL::cpp11::get<1>(*The_Root);
+ Compute_the_next_nearest_neighbour();
+ }
+ else{
+ distance_to_root=
+ Orthogonal_distance_instance.max_distance_to_rectangle(q,
+ tree.bounding_box(), dists);
+ Node_with_distance *The_Root = new Node_with_distance(tree.root(),
+ distance_to_root, dists);
+ PriorityQueue.push(The_Root);
+
+ // rd is the distance of the top of the priority queue to q
+ rd=CGAL::cpp11::get<1>(*The_Root);
+ Compute_the_next_furthest_neighbour();
+ }
+
+
+ }
+
+ // * operator
+ const Point_with_transformed_distance&
+ operator* () const
+ {
+ return *(Item_PriorityQueue.top());
+ }
+
+ // prefix operator
+ Iterator_implementation&
+ operator++()
+ {
+ Delete_the_current_item_top();
+ if(search_nearest_neighbour)
+ Compute_the_next_nearest_neighbour();
+ else
+ Compute_the_next_furthest_neighbour();
+ return *this;
+ }
+
+ // postfix operator
+ Object_wrapper<Point_with_transformed_distance>
+ operator++(int)
+ {
+ Object_wrapper<Point_with_transformed_distance> result( *(Item_PriorityQueue.top()) );
+ ++*this;
+ return result;
+ }
+
+ // Print statistics of the general priority search process.
+ std::ostream&
+ statistics (std::ostream& s) const {
+ s << "Orthogonal priority search statistics:"
+ << std::endl;
+ s << "Number of internal nodes visited:"
+ << number_of_internal_nodes_visited << std::endl;
+ s << "Number of leaf nodes visited:"
+ << number_of_leaf_nodes_visited << std::endl;
+ s << "Number of items visited:"
+ << number_of_items_visited << std::endl;
+ s << "Number of neighbours computed:"
+ << number_of_neighbours_computed << std::endl;
+ return s;
+ }
+
+
+ //destructor
+ ~Iterator_implementation()
+ {
+ while (!PriorityQueue.empty()) {
+ Node_with_distance* The_top=PriorityQueue.top();
+ PriorityQueue.pop();
+ delete The_top;
+ }
+ while (!Item_PriorityQueue.empty()) {
+ Point_with_transformed_distance* The_top=Item_PriorityQueue.top();
+ Item_PriorityQueue.pop();
+ delete The_top;
+ }
+ }
+
+ private:
+
+ void
+ Delete_the_current_item_top()
+ {
+ Point_with_transformed_distance* The_item_top=Item_PriorityQueue.top();
+ Item_PriorityQueue.pop();
+ delete The_item_top;
+ }
+
+ void
+ Compute_the_next_nearest_neighbour()
+ {
+ // compute the next item
+ bool next_neighbour_found=false;
+ if (!(Item_PriorityQueue.empty())) {
+ next_neighbour_found=
+ (multiplication_factor*rd > Item_PriorityQueue.top()->second);
+ }
+ typename SearchTraits::Construct_cartesian_const_iterator_d construct_it=traits.construct_cartesian_const_iterator_d_object();
+ typename SearchTraits::Cartesian_const_iterator_d query_point_it = construct_it(query_point);
+ // otherwise browse the tree further
+ while ((!next_neighbour_found) && (!PriorityQueue.empty())) {
+ Node_with_distance* The_node_top=PriorityQueue.top();
+ Node_const_handle N= CGAL::cpp11::get<0>(*The_node_top);
+ dists = CGAL::cpp11::get<2>(*The_node_top);
+ PriorityQueue.pop();
+ delete The_node_top;
+ FT copy_rd=rd;
+ while (!(N->is_leaf())) { // compute new distance
+ typename Tree::Internal_node_const_handle node =
+ static_cast<typename Tree::Internal_node_const_handle>(N);
+ number_of_internal_nodes_visited++;
+ int new_cut_dim=node->cutting_dimension();
+ FT new_rd,dst = dists[new_cut_dim];
+ FT val = *(query_point_it + new_cut_dim);
+ FT diff1 = val - node->upper_low_value();
+ FT diff2 = val - node->lower_high_value();
+ if (diff1 + diff2 < FT(0.0)) {
+ new_rd=
+ Orthogonal_distance_instance.new_distance(copy_rd,dst,diff1,new_cut_dim);
+
+ CGAL_assertion(new_rd >= copy_rd);
+ dists[new_cut_dim] = diff1;
+ Node_with_distance *Upper_Child =
+ new Node_with_distance(node->upper(), new_rd, dists);
+ PriorityQueue.push(Upper_Child);
+ dists[new_cut_dim] = dst;
+ N=node->lower();
+
+ }
+ else { // compute new distance
+ new_rd=Orthogonal_distance_instance.new_distance(copy_rd,dst,diff2,new_cut_dim);
+ CGAL_assertion(new_rd >= copy_rd);
+ dists[new_cut_dim] = diff2;
+ Node_with_distance *Lower_Child =
+ new Node_with_distance(node->lower(), new_rd, dists);
+ PriorityQueue.push(Lower_Child);
+ dists[new_cut_dim] = dst;
+ N=node->upper();
+ }
+ }
+ // n is a leaf
+ typename Tree::Leaf_node_const_handle node =
+ static_cast<typename Tree::Leaf_node_const_handle>(N);
+ number_of_leaf_nodes_visited++;
+ if (node->size() > 0) {
+ for (typename Tree::iterator it=node->begin(); it != node->end(); it++) {
+ number_of_items_visited++;
+ FT distance_to_query_point=
+ Orthogonal_distance_instance.transformed_distance(query_point,*it);
+ Point_with_transformed_distance *NN_Candidate=
+ new Point_with_transformed_distance(*it,distance_to_query_point);
+ Item_PriorityQueue.push(NN_Candidate);
+ }
+ // old top of PriorityQueue has been processed,
+ // hence update rd
+
+ if (!(PriorityQueue.empty())) {
+ rd = CGAL::cpp11::get<1>(*PriorityQueue.top());
+ next_neighbour_found =
+ (multiplication_factor*rd >
+ Item_PriorityQueue.top()->second);
+ }
+ else // priority queue empty => last neighbour found
+ {
+ next_neighbour_found=true;
+ }
+
+ number_of_neighbours_computed++;
+ }
+ } // next_neighbour_found or priority queue is empty
+ // in the latter case also the item priority quee is empty
+ }
+
+
+ void
+ Compute_the_next_furthest_neighbour()
+ {
+ // compute the next item
+ bool next_neighbour_found=false;
+ if (!(Item_PriorityQueue.empty())) {
+ next_neighbour_found=
+ (rd < multiplication_factor*Item_PriorityQueue.top()->second);
+ }
+ typename SearchTraits::Construct_cartesian_const_iterator_d construct_it=traits.construct_cartesian_const_iterator_d_object();
+ typename SearchTraits::Cartesian_const_iterator_d query_point_it = construct_it(query_point);
+ // otherwise browse the tree further
+ while ((!next_neighbour_found) && (!PriorityQueue.empty())) {
+ Node_with_distance* The_node_top=PriorityQueue.top();
+ Node_const_handle N= CGAL::cpp11::get<0>(*The_node_top);
+ dists = CGAL::cpp11::get<2>(*The_node_top);
+ PriorityQueue.pop();
+ delete The_node_top;
+ FT copy_rd=rd;
+ while (!(N->is_leaf())) { // compute new distance
+ typename Tree::Internal_node_const_handle node =
+ static_cast<typename Tree::Internal_node_const_handle>(N);
+ number_of_internal_nodes_visited++;
+ int new_cut_dim=node->cutting_dimension();
+ FT new_rd,dst = dists[new_cut_dim];
+ FT val = *(query_point_it + new_cut_dim);
+ FT diff1 = val - node->upper_low_value();
+ FT diff2 = val - node->lower_high_value();
+ if (diff1 + diff2 < FT(0.0)) {
+ diff1 = val - node->upper_high_value();
+ new_rd=
+ Orthogonal_distance_instance.new_distance(copy_rd,dst,diff1,new_cut_dim);
+ Node_with_distance *Lower_Child =
+ new Node_with_distance(node->lower(), copy_rd, dists);
+ PriorityQueue.push(Lower_Child);
+ N=node->upper();
+ dists[new_cut_dim] = diff1;
+ copy_rd=new_rd;
+
+ }
+ else { // compute new distance
+ diff2 = val - node->lower_low_value();
+ new_rd=Orthogonal_distance_instance.new_distance(copy_rd,dst,diff2,new_cut_dim);
+ Node_with_distance *Upper_Child =
+ new Node_with_distance(node->upper(), copy_rd, dists);
+ PriorityQueue.push(Upper_Child);
+ N=node->lower();
+ dists[new_cut_dim] = diff2;
+ copy_rd=new_rd;
+ }
+ }
+ // n is a leaf
+ typename Tree::Leaf_node_const_handle node =
+ static_cast<typename Tree::Leaf_node_const_handle>(N);
+ number_of_leaf_nodes_visited++;
+ if (node->size() > 0) {
+ for (typename Tree::iterator it=node->begin(); it != node->end(); it++) {
+ number_of_items_visited++;
+ FT distance_to_query_point=
+ Orthogonal_distance_instance.transformed_distance(query_point,*it);
+ Point_with_transformed_distance *NN_Candidate=
+ new Point_with_transformed_distance(*it,distance_to_query_point);
+ Item_PriorityQueue.push(NN_Candidate);
+ }
+ // old top of PriorityQueue has been processed,
+ // hence update rd
+
+ if (!(PriorityQueue.empty())) {
+ rd = CGAL::cpp11::get<1>(*PriorityQueue.top());
+ next_neighbour_found =
+ (multiplication_factor*rd <
+ Item_PriorityQueue.top()->second);
+ }
+ else // priority queue empty => last neighbour found
+ {
+ next_neighbour_found=true;
+ }
+
+ number_of_neighbours_computed++;
+ }
+ } // next_neighbour_found or priority queue is empty
+ // in the latter case also the item priority quee is empty
+ }
+ }; // class Iterator_implementaion
+
+
+
+
+
+
+
+
+
+ public:
+ class iterator;
+ typedef iterator const_iterator;
+
+ // constructor
+ Orthogonal_incremental_neighbor_search(const Tree& tree,
+ const Query_item& q, FT Eps = FT(0.0),
+ bool search_nearest=true, const Distance& tr=Distance())
+ : m_tree(tree),m_query(q),m_dist(tr),m_Eps(Eps),m_search_nearest(search_nearest)
+ {}
+
+ iterator
+ begin() const
+ {
+ return iterator(m_tree,m_query,m_dist,m_Eps,m_search_nearest);
+ }
+
+ iterator
+ end() const
+ {
+ return iterator();
+ }
+
+ std::ostream&
+ statistics(std::ostream& s)
+ {
+ begin()->statistics(s);
+ return s;
+ }
+
+
+
+
+ class iterator {
+
+ public:
+
+ typedef std::input_iterator_tag iterator_category;
+ typedef Point_with_transformed_distance value_type;
+ typedef Point_with_transformed_distance* pointer;
+ typedef const Point_with_transformed_distance& reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef int distance_type;
+
+ //class Iterator_implementation;
+ Iterator_implementation *Ptr_implementation;
+
+
+ public:
+
+ // default constructor
+ iterator()
+ : Ptr_implementation(0)
+ {}
+
+ int
+ the_number_of_items_visited()
+ {
+ return Ptr_implementation->number_of_items_visited;
+ }
+
+ // constructor
+ iterator(const Tree& tree,const Query_item& q, const Distance& tr=Distance(), FT eps=FT(0.0),
+ bool search_nearest=true)
+ : Ptr_implementation(new Iterator_implementation(tree, q, tr, eps, search_nearest))
+ {}
+
+ // copy constructor
+ iterator(const iterator& Iter)
+ {
+ Ptr_implementation = Iter.Ptr_implementation;
+ if (Ptr_implementation != 0) Ptr_implementation->reference_count++;
+ }
+
+ iterator& operator=(const iterator& Iter)
+ {
+ if (Ptr_implementation != Iter.Ptr_implementation){
+ if (Ptr_implementation != 0 && --(Ptr_implementation->reference_count)==0) {
+ delete Ptr_implementation;
+ }
+ Ptr_implementation = Iter.Ptr_implementation;
+ if (Ptr_implementation != 0) Ptr_implementation->reference_count++;
+ }
+ return *this;
+ }
+
+
+ const Point_with_transformed_distance&
+ operator* () const
+ {
+ return *(*Ptr_implementation);
+ }
+
+ // -> operator
+ const Point_with_transformed_distance*
+ operator-> () const
+ {
+ return &*(*Ptr_implementation);
+ }
+
+ // prefix operator
+ iterator&
+ operator++()
+ {
+ ++(*Ptr_implementation);
+ return *this;
+ }
+
+ // postfix operator
+ Object_wrapper<Point_with_transformed_distance>
+ operator++(int)
+ {
+ return (*Ptr_implementation)++;
+ }
+
+
+ bool
+ operator==(const iterator& It) const
+ {
+ if (
+ ((Ptr_implementation == 0) ||
+ Ptr_implementation->Item_PriorityQueue.empty()) &&
+ ((It.Ptr_implementation == 0) ||
+ It.Ptr_implementation->Item_PriorityQueue.empty())
+ )
+ return true;
+ // else
+ return (Ptr_implementation == It.Ptr_implementation);
+ }
+
+ bool
+ operator!=(const iterator& It) const
+ {
+ return !(*this == It);
+ }
+
+ std::ostream&
+ statistics (std::ostream& s)
+ {
+ Ptr_implementation->statistics(s);
+ return s;
+ }
+
+ ~iterator()
+ {
+ if (Ptr_implementation != 0) {
+ Ptr_implementation->reference_count--;
+ if (Ptr_implementation->reference_count==0) {
+ delete Ptr_implementation;
+ Ptr_implementation = 0;
+ }
+ }
+ }
+
+
+ }; // class iterator
+
+ //data members
+ const Tree& m_tree;
+ Query_item m_query;
+ Distance m_dist;
+ FT m_Eps;
+ bool m_search_nearest;
+ }; // class
+
+ template <class Traits, class Query_item, class Distance>
+ void swap (typename Orthogonal_incremental_neighbor_search<Traits,
+ Query_item, Distance>::iterator& x,
+ typename Orthogonal_incremental_neighbor_search<Traits,
+ Query_item, Distance>::iterator& y)
+ {
+ typename Orthogonal_incremental_neighbor_search<Traits,
+ Query_item, Distance>::iterator::Iterator_implementation
+ *tmp = x.Ptr_implementation;
+ x.Ptr_implementation = y.Ptr_implementation;
+ y.Ptr_implementation = tmp;
+ }
+
+} // namespace CGAL
+
+#endif // CGAL_ORTHOGONAL_INCREMENTAL_NEIGHBOR_SEARCH_H
diff --git a/include/gudhi_patches/CGAL/Regular_triangulation.h b/include/gudhi_patches/CGAL/Regular_triangulation.h
new file mode 100644
index 00000000..111c6ac9
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Regular_triangulation.h
@@ -0,0 +1,1169 @@
+// 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_REGULAR_TRIANGULATION_H
+#define CGAL_REGULAR_TRIANGULATION_H
+
+#include <CGAL/Triangulation.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/Default.h>
+#include <CGAL/spatial_sort.h>
+#include <CGAL/Regular_triangulation_traits_adapter.h>
+
+#include <boost/property_map/function_property_map.hpp>
+
+namespace CGAL {
+
+template< typename Traits_, typename TDS_ = Default >
+class Regular_triangulation
+: public Triangulation<
+ Regular_triangulation_traits_adapter<Traits_>,
+ typename Default::Get<
+ TDS_,
+ Triangulation_data_structure<
+ typename Regular_triangulation_traits_adapter<Traits_>::Dimension,
+ Triangulation_vertex<Regular_triangulation_traits_adapter<Traits_> >,
+ Triangulation_full_cell<Regular_triangulation_traits_adapter<Traits_> >
+ >
+ >::type>
+{
+ typedef Regular_triangulation_traits_adapter<Traits_> RTTraits;
+ typedef typename RTTraits::Dimension Maximal_dimension_;
+ typedef typename Default::Get<
+ TDS_,
+ Triangulation_data_structure<
+ Maximal_dimension_,
+ Triangulation_vertex<RTTraits>,
+ Triangulation_full_cell<RTTraits>
+ > >::type TDS;
+ typedef Triangulation<RTTraits, TDS> Base;
+ typedef Regular_triangulation<Traits_, TDS_> Self;
+
+ typedef typename RTTraits::Orientation_d Orientation_d;
+ typedef typename RTTraits::Power_side_of_power_sphere_d Power_side_of_power_sphere_d;
+ typedef typename RTTraits::In_flat_power_side_of_power_sphere_d
+ In_flat_power_side_of_power_sphere_d;
+ typedef typename RTTraits::Flat_orientation_d Flat_orientation_d;
+ typedef typename RTTraits::Construct_flat_orientation_d Construct_flat_orientation_d;
+
+public: // PUBLIC NESTED TYPES
+
+ typedef RTTraits Geom_traits;
+ typedef typename Base::Triangulation_ds Triangulation_ds;
+
+ typedef typename Base::Vertex Vertex;
+ typedef typename Base::Full_cell Full_cell;
+ typedef typename Base::Facet Facet;
+ typedef typename Base::Face Face;
+
+ typedef Maximal_dimension_ Maximal_dimension;
+ typedef typename RTTraits::Bare_point_d Bare_point;
+ typedef typename RTTraits::Weighted_point_d Weighted_point;
+
+ typedef typename Base::Point_const_iterator Point_const_iterator;
+ typedef typename Base::Vertex_handle Vertex_handle;
+ typedef typename Base::Vertex_iterator Vertex_iterator;
+ typedef typename Base::Vertex_const_handle Vertex_const_handle;
+ typedef typename Base::Vertex_const_iterator Vertex_const_iterator;
+
+ typedef typename Base::Full_cell_handle Full_cell_handle;
+ typedef typename Base::Full_cell_iterator Full_cell_iterator;
+ typedef typename Base::Full_cell_const_handle Full_cell_const_handle;
+ typedef typename Base::Full_cell_const_iterator Full_cell_const_iterator;
+ typedef typename Base::Finite_full_cell_const_iterator
+ Finite_full_cell_const_iterator;
+
+ typedef typename Base::size_type size_type;
+ typedef typename Base::difference_type difference_type;
+
+ typedef typename Base::Locate_type Locate_type;
+
+ //Tag to distinguish Delaunay from Regular triangulations
+ typedef Tag_true Weighted_tag;
+
+protected: // DATA MEMBERS
+
+
+public:
+
+ using typename Base::Rotor;
+ using Base::maximal_dimension;
+ using Base::are_incident_full_cells_valid;
+ using Base::coaffine_orientation_predicate;
+ using Base::reset_flat_orientation;
+ using Base::current_dimension;
+ using Base::geom_traits;
+ using Base::index_of_covertex;
+ //using Base::index_of_second_covertex;
+ using Base::rotate_rotor;
+ using Base::infinite_vertex;
+ using Base::insert_in_hole;
+ using Base::is_infinite;
+ using Base::locate;
+ using Base::points_begin;
+ using Base::set_neighbors;
+ using Base::new_full_cell;
+ using Base::number_of_vertices;
+ using Base::orientation;
+ using Base::tds;
+ using Base::reorient_full_cells;
+ using Base::full_cell;
+ using Base::full_cells_begin;
+ using Base::full_cells_end;
+ using Base::finite_full_cells_begin;
+ using Base::finite_full_cells_end;
+ using Base::vertices_begin;
+ using Base::vertices_end;
+
+private:
+
+ // Wrapper
+ struct Power_side_of_power_sphere_for_non_maximal_dim_d
+ {
+ boost::optional<Flat_orientation_d>* fop;
+ Construct_flat_orientation_d cfo;
+ In_flat_power_side_of_power_sphere_d ifpt;
+
+ Power_side_of_power_sphere_for_non_maximal_dim_d(
+ boost::optional<Flat_orientation_d>& x,
+ Construct_flat_orientation_d const&y,
+ In_flat_power_side_of_power_sphere_d const&z)
+ : fop(&x), cfo(y), ifpt(z) {}
+
+ template<class Iter>
+ CGAL::Orientation operator()(Iter a, Iter b, const Weighted_point & p)const
+ {
+ if(!*fop)
+ *fop=cfo(a,b);
+ return ifpt(fop->get(),a,b,p);
+ }
+ };
+
+public:
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS
+
+ Regular_triangulation(int dim, const Geom_traits &k = Geom_traits())
+ : Base(dim, k)
+ {
+ }
+
+ // With this constructor,
+ // the user can specify a Flat_orientation_d object to be used for
+ // orienting simplices of a specific dimension
+ // (= preset_flat_orientation_.first)
+ // It it used by the dark triangulations created by DT::remove
+ Regular_triangulation(
+ int dim,
+ const std::pair<int, const Flat_orientation_d *> &preset_flat_orientation,
+ const Geom_traits &k = Geom_traits())
+ : Base(dim, preset_flat_orientation, k)
+ {
+ }
+
+ ~Regular_triangulation() {}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ACCESS
+
+ // Not Documented
+ Power_side_of_power_sphere_for_non_maximal_dim_d power_side_of_power_sphere_for_non_maximal_dim_predicate() const
+ {
+ return Power_side_of_power_sphere_for_non_maximal_dim_d (
+ flat_orientation_,
+ geom_traits().construct_flat_orientation_d_object(),
+ geom_traits().in_flat_power_side_of_power_sphere_d_object()
+ );
+ }
+
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
+
+ // Warning: these functions are not correct since they do not restore hidden
+ // vertices
+
+ Full_cell_handle remove(Vertex_handle);
+ Full_cell_handle remove(const Weighted_point & p, Full_cell_handle hint = Full_cell_handle())
+ {
+ Locate_type lt;
+ Face f(maximal_dimension());
+ Facet ft;
+ Full_cell_handle s = locate(p, lt, f, ft, hint);
+ if( Base::ON_VERTEX == lt )
+ {
+ return remove(s->vertex(f.index(0)));
+ }
+ return Full_cell_handle();
+ }
+
+ template< typename ForwardIterator >
+ void remove(ForwardIterator start, ForwardIterator end)
+ {
+ while( start != end )
+ remove(*start++);
+ }
+
+ // Not documented
+ void remove_decrease_dimension(Vertex_handle);
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSERTIONS
+
+ template< typename ForwardIterator >
+ std::ptrdiff_t insert(ForwardIterator start, ForwardIterator end)
+ {
+ size_type n = number_of_vertices();
+ typedef std::vector<Weighted_point> WP_vec;
+ WP_vec points(start, end);
+
+ spatial_sort(points.begin(), points.end(), geom_traits());
+
+ Full_cell_handle hint;
+ for(typename WP_vec::const_iterator p = points.begin(); p != points.end(); ++p )
+ {
+ Locate_type lt;
+ Face f(maximal_dimension());
+ Facet ft;
+ Full_cell_handle c = locate (*p, lt, f, ft, hint);
+ Vertex_handle v = insert (*p, lt, f, ft, c);
+
+ hint = v == Vertex_handle() ? c : v->full_cell();
+ }
+ return number_of_vertices() - n;
+ }
+
+ Vertex_handle insert(const Weighted_point &,
+ Locate_type,
+ const Face &,
+ const Facet &,
+ Full_cell_handle);
+
+ Vertex_handle insert(const Weighted_point & p,
+ Full_cell_handle start = Full_cell_handle())
+ {
+ Locate_type lt;
+ Face f(maximal_dimension());
+ Facet ft;
+ Full_cell_handle s = locate(p, lt, f, ft, start);
+ return insert(p, lt, f, ft, s);
+ }
+
+ Vertex_handle insert(const Weighted_point & p, Vertex_handle hint)
+ {
+ CGAL_assertion( Vertex_handle() != hint );
+ return insert(p, hint->full_cell());
+ }
+
+ Vertex_handle insert_outside_affine_hull(const Weighted_point &);
+ Vertex_handle insert_in_conflicting_cell(
+ const Weighted_point &, Full_cell_handle,
+ Vertex_handle only_if_this_vertex_is_in_the_cz = Vertex_handle());
+
+ Vertex_handle insert_if_in_star(const Weighted_point &,
+ Vertex_handle,
+ Locate_type,
+ const Face &,
+ const Facet &,
+ Full_cell_handle);
+
+ Vertex_handle insert_if_in_star(
+ const Weighted_point & p, Vertex_handle star_center,
+ Full_cell_handle start = Full_cell_handle())
+ {
+ Locate_type lt;
+ Face f(maximal_dimension());
+ Facet ft;
+ Full_cell_handle s = locate(p, lt, f, ft, start);
+ return insert_if_in_star(p, star_center, lt, f, ft, s);
+ }
+
+ Vertex_handle insert_if_in_star(
+ const Weighted_point & p, Vertex_handle star_center,
+ Vertex_handle hint)
+ {
+ CGAL_assertion( Vertex_handle() != hint );
+ return insert_if_in_star(p, star_center, hint->full_cell());
+ }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - GATHERING CONFLICTING SIMPLICES
+
+ bool is_in_conflict(const Weighted_point &, Full_cell_const_handle) const;
+
+ template< class OrientationPredicate >
+ Oriented_side perturbed_power_side_of_power_sphere(const Weighted_point &,
+ Full_cell_const_handle, const OrientationPredicate &) const;
+
+ template< typename OutputIterator >
+ Facet compute_conflict_zone(const Weighted_point &, Full_cell_handle, OutputIterator) const;
+
+ template < typename OrientationPredicate, typename PowerTestPredicate >
+ class Conflict_predicate
+ {
+ const Self & rt_;
+ const Weighted_point & p_;
+ OrientationPredicate ori_;
+ PowerTestPredicate power_side_of_power_sphere_;
+ int cur_dim_;
+ public:
+ Conflict_predicate(
+ const Self & rt,
+ const Weighted_point & p,
+ const OrientationPredicate & ori,
+ const PowerTestPredicate & power_side_of_power_sphere)
+ : rt_(rt), p_(p), ori_(ori), power_side_of_power_sphere_(power_side_of_power_sphere), cur_dim_(rt.current_dimension()) {}
+
+ inline
+ bool operator()(Full_cell_const_handle s) const
+ {
+ bool ok;
+ if( ! rt_.is_infinite(s) )
+ {
+ Oriented_side power_side_of_power_sphere = power_side_of_power_sphere_(rt_.points_begin(s), rt_.points_begin(s) + cur_dim_ + 1, p_);
+ if( ON_POSITIVE_SIDE == power_side_of_power_sphere )
+ ok = true;
+ else if( ON_NEGATIVE_SIDE == power_side_of_power_sphere )
+ ok = false;
+ else
+ ok = ON_POSITIVE_SIDE == rt_.perturbed_power_side_of_power_sphere<OrientationPredicate>(p_, s, ori_);
+ }
+ else
+ {
+ typedef typename Full_cell::Vertex_handle_const_iterator VHCI;
+ typedef Substitute_point_in_vertex_iterator<VHCI> F;
+ F spivi(rt_.infinite_vertex(), &p_);
+
+ Orientation o = ori_(
+ boost::make_transform_iterator(s->vertices_begin(), spivi),
+ boost::make_transform_iterator(s->vertices_begin() + cur_dim_ + 1,
+ spivi));
+
+ if( POSITIVE == o )
+ ok = true;
+ else if( o == NEGATIVE )
+ ok = false;
+ else
+ ok = (*this)(s->neighbor( s->index( rt_.infinite_vertex() ) ));
+ }
+ return ok;
+ }
+ };
+
+ template < typename ConflictPredicate >
+ class Conflict_traversal_predicate
+ {
+ const Self & rt_;
+ const ConflictPredicate & pred_;
+ public:
+ Conflict_traversal_predicate(const Self & rt, const ConflictPredicate & pred)
+ : rt_(rt), pred_(pred)
+ {}
+ inline
+ bool operator()(const Facet & f) const
+ {
+ return pred_(rt_.full_cell(f)->neighbor(rt_.index_of_covertex(f)));
+ }
+ };
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
+
+ bool is_valid(bool verbose = false, int level = 0) const;
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MISC
+
+ std::size_t number_of_hidden_vertices() const
+ {
+ return m_hidden_points.size();
+ }
+
+private:
+
+ template<typename InputIterator>
+ bool
+ does_cell_range_contain_vertex(InputIterator cz_begin, InputIterator cz_end,
+ Vertex_handle vh) const
+ {
+ // Check all vertices
+ while(cz_begin != cz_end)
+ {
+ Full_cell_handle fch = *cz_begin;
+ for (int i = 0 ; i <= current_dimension() ; ++i)
+ {
+ if (fch->vertex(i) == vh)
+ return true;
+ }
+ ++cz_begin;
+ }
+ return false;
+ }
+
+ template<typename InputIterator, typename OutputIterator>
+ void
+ process_conflict_zone(InputIterator cz_begin, InputIterator cz_end,
+ OutputIterator vertices_out) const
+ {
+ // Get all vertices
+ while(cz_begin != cz_end)
+ {
+ Full_cell_handle fch = *cz_begin;
+ for (int i = 0 ; i <= current_dimension() ; ++i)
+ {
+ Vertex_handle vh = fch->vertex(i);
+ if (vh->full_cell() != Full_cell_handle())
+ {
+ (*vertices_out++) = vh;
+ vh->set_full_cell(Full_cell_handle());
+ }
+ }
+ ++cz_begin;
+ }
+ }
+
+
+ template<typename InputIterator>
+ void
+ process_cz_vertices_after_insertion(InputIterator vertices_begin,
+ InputIterator vertices_end)
+ {
+ // Get all vertices
+ while(vertices_begin != vertices_end)
+ {
+ Vertex_handle vh = *vertices_begin;
+ if (vh->full_cell() == Full_cell_handle())
+ {
+ m_hidden_points.push_back(vh->point());
+ tds().delete_vertex(vh);
+ }
+ ++vertices_begin;
+ }
+ }
+
+private:
+ // Some internal types to shorten notation
+ using typename Base::Coaffine_orientation_d;
+ using Base::flat_orientation_;
+ typedef Conflict_predicate<Coaffine_orientation_d, Power_side_of_power_sphere_for_non_maximal_dim_d>
+ Conflict_pred_in_subspace;
+ typedef Conflict_predicate<Orientation_d, Power_side_of_power_sphere_d>
+ Conflict_pred_in_fullspace;
+ typedef Conflict_traversal_predicate<Conflict_pred_in_subspace>
+ Conflict_traversal_pred_in_subspace;
+ typedef Conflict_traversal_predicate<Conflict_pred_in_fullspace>
+ Conflict_traversal_pred_in_fullspace;
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MEMBER VARIABLES
+ std::vector<Weighted_point> m_hidden_points;
+
+}; // class Regular_triangulation
+
+
+// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+// FUNCTIONS THAT ARE MEMBER METHODS:
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
+
+
+// Warning: this function is not correct since it does not restore hidden
+// vertices
+template< typename Traits, typename TDS >
+typename Regular_triangulation<Traits, TDS>::Full_cell_handle
+Regular_triangulation<Traits, TDS>
+::remove( Vertex_handle v )
+{
+ CGAL_precondition( ! is_infinite(v) );
+ CGAL_expensive_precondition( is_vertex(v) );
+
+ // THE CASE cur_dim == 0
+ if( 0 == current_dimension() )
+ {
+ remove_decrease_dimension(v);
+ return Full_cell_handle();
+ }
+ else if( 1 == current_dimension() )
+ { // THE CASE cur_dim == 1
+ if( 2 == number_of_vertices() )
+ {
+ remove_decrease_dimension(v);
+ return Full_cell_handle();
+ }
+ Full_cell_handle left = v->full_cell();
+ if( 0 == left->index(v) )
+ left = left->neighbor(1);
+ CGAL_assertion( 1 == left->index(v) );
+ Full_cell_handle right = left->neighbor(0);
+ tds().associate_vertex_with_full_cell(left, 1, right->vertex(1));
+ set_neighbors(left, 0, right->neighbor(0), right->mirror_index(0));
+ tds().delete_vertex(v);
+ tds().delete_full_cell(right);
+ return left;
+ }
+
+ // THE CASE cur_dim >= 2
+ // Gather the finite vertices sharing an edge with |v|
+ typedef typename Base::template Full_cell_set<Full_cell_handle> Simplices;
+ Simplices simps;
+ std::back_insert_iterator<Simplices> out(simps);
+ tds().incident_full_cells(v, out);
+ typedef std::set<Vertex_handle> Vertex_set;
+ Vertex_set verts;
+ Vertex_handle vh;
+ for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
+ for( int i = 0; i <= current_dimension(); ++i )
+ {
+ vh = (*it)->vertex(i);
+ if( is_infinite(vh) )
+ continue;
+ if( vh == v )
+ continue;
+ verts.insert(vh);
+ }
+
+ // After gathering finite neighboring vertices, create their Dark Delaunay triangulation
+ typedef Triangulation_vertex<Geom_traits, Vertex_handle> Dark_vertex_base;
+ typedef Triangulation_full_cell<
+ Geom_traits,
+ internal::Triangulation::Dark_full_cell_data<TDS> > Dark_full_cell_base;
+ typedef Triangulation_data_structure<Maximal_dimension,
+ Dark_vertex_base,
+ Dark_full_cell_base
+ > Dark_tds;
+ typedef Regular_triangulation<Traits, Dark_tds> Dark_triangulation;
+ typedef typename Dark_triangulation::Face Dark_face;
+ typedef typename Dark_triangulation::Facet Dark_facet;
+ typedef typename Dark_triangulation::Vertex_handle Dark_v_handle;
+ typedef typename Dark_triangulation::Full_cell_handle Dark_s_handle;
+
+ // If flat_orientation_ is defined, we give it the Dark triangulation
+ // so that the orientation it uses for "current_dimension()"-simplices is
+ // coherent with the global triangulation
+ Dark_triangulation dark_side(
+ maximal_dimension(),
+ flat_orientation_ ?
+ std::pair<int, const Flat_orientation_d *>(current_dimension(), flat_orientation_.get_ptr())
+ : std::pair<int, const Flat_orientation_d *>(std::numeric_limits<int>::max(), NULL) );
+
+ Dark_s_handle dark_s;
+ Dark_v_handle dark_v;
+ typedef std::map<Vertex_handle, Dark_v_handle> Vertex_map;
+ Vertex_map light_to_dark;
+ typename Vertex_set::iterator vit = verts.begin();
+ while( vit != verts.end() )
+ {
+ dark_v = dark_side.insert((*vit)->point(), dark_s);
+ dark_s = dark_v->full_cell();
+ dark_v->data() = *vit;
+ light_to_dark[*vit] = dark_v;
+ ++vit;
+ }
+
+ if( dark_side.current_dimension() != current_dimension() )
+ {
+ CGAL_assertion( dark_side.current_dimension() + 1 == current_dimension() );
+ // Here, the finite neighbors of |v| span a affine subspace of
+ // dimension one less than the current dimension. Two cases are possible:
+ if( (size_type)(verts.size() + 1) == number_of_vertices() )
+ {
+ remove_decrease_dimension(v);
+ return Full_cell_handle();
+ }
+ else
+ { // |v| is strictly outside the convex hull of the rest of the points. This is an
+ // easy case: first, modify the finite full_cells, then, delete the infinite ones.
+ // We don't even need the Dark triangulation.
+ Simplices infinite_simps;
+ {
+ Simplices finite_simps;
+ for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
+ if( is_infinite(*it) )
+ infinite_simps.push_back(*it);
+ else
+ finite_simps.push_back(*it);
+ simps.swap(finite_simps);
+ } // now, simps only contains finite simplices
+ // First, modify the finite full_cells:
+ for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
+ {
+ int v_idx = (*it)->index(v);
+ tds().associate_vertex_with_full_cell(*it, v_idx, infinite_vertex());
+ }
+ // Make the handles to infinite full cells searchable
+ infinite_simps.make_searchable();
+ // Then, modify the neighboring relation
+ for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
+ {
+ for( int i = 0 ; i <= current_dimension(); ++i )
+ {
+ if (is_infinite((*it)->vertex(i)))
+ continue;
+ (*it)->vertex(i)->set_full_cell(*it);
+ Full_cell_handle n = (*it)->neighbor(i);
+ // Was |n| a finite full cell prior to removing |v| ?
+ if( ! infinite_simps.contains(n) )
+ continue;
+ int n_idx = n->index(v);
+ set_neighbors(*it, i, n->neighbor(n_idx), n->neighbor(n_idx)->index(n));
+ }
+ }
+ Full_cell_handle ret_s;
+ // Then, we delete the infinite full_cells
+ for( typename Simplices::iterator it = infinite_simps.begin(); it != infinite_simps.end(); ++it )
+ tds().delete_full_cell(*it);
+ tds().delete_vertex(v);
+ return simps.front();
+ }
+ }
+ else // From here on, dark_side.current_dimension() == current_dimension()
+ {
+ dark_side.infinite_vertex()->data() = infinite_vertex();
+ light_to_dark[infinite_vertex()] = dark_side.infinite_vertex();
+ }
+
+ // Now, compute the conflict zone of v->point() in
+ // the dark side. This is precisely the set of full_cells
+ // that we have to glue back into the light side.
+ Dark_face dark_f(dark_side.maximal_dimension());
+ Dark_facet dark_ft;
+ typename Dark_triangulation::Locate_type lt;
+ dark_s = dark_side.locate(v->point(), lt, dark_f, dark_ft);
+ CGAL_assertion( lt != Dark_triangulation::ON_VERTEX
+ && lt != Dark_triangulation::OUTSIDE_AFFINE_HULL );
+
+ // |ret_s| is the full_cell that we return
+ Dark_s_handle dark_ret_s = dark_s;
+ Full_cell_handle ret_s;
+
+ typedef typename Base::template Full_cell_set<Dark_s_handle> Dark_full_cells;
+ Dark_full_cells 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);
+ // Make the dark simplices in the conflict zone searchable
+ conflict_zone.make_searchable();
+
+ // THE FOLLOWING SHOULD MAYBE GO IN TDS.
+ // Here is the plan:
+ // 1. Pick any Facet from boundary of the light zone
+ // 2. Find corresponding Facet on boundary of dark zone
+ // 3. stitch.
+
+ // 1. Build a facet on the boudary of the light zone:
+ Full_cell_handle light_s = *simps.begin();
+ Facet light_ft(light_s, light_s->index(v));
+
+ // 2. Find corresponding Dark_facet on boundary of the dark zone
+ Dark_full_cells dark_incident_s;
+ for( int i = 0; i <= current_dimension(); ++i )
+ {
+ if( index_of_covertex(light_ft) == i )
+ continue;
+ Dark_v_handle dark_v = light_to_dark[full_cell(light_ft)->vertex(i)];
+ dark_incident_s.clear();
+ dark_out = std::back_inserter(dark_incident_s);
+ dark_side.tds().incident_full_cells(dark_v, dark_out);
+ for(typename Dark_full_cells::iterator it = dark_incident_s.begin();
+ it != dark_incident_s.end();
+ ++it)
+ {
+ (*it)->data().count_ += 1;
+ }
+ }
+
+ for( typename Dark_full_cells::iterator it = dark_incident_s.begin(); it != dark_incident_s.end(); ++it )
+ {
+ if( current_dimension() != (*it)->data().count_ )
+ continue;
+ if( ! conflict_zone.contains(*it) )
+ continue;
+ // We found a full_cell incident to the dark facet corresponding to the light facet |light_ft|
+ int ft_idx = 0;
+ while( light_s->has_vertex( (*it)->vertex(ft_idx)->data() ) )
+ ++ft_idx;
+ dark_ft = Dark_facet(*it, ft_idx);
+ break;
+ }
+ // Pre-3. Now, we are ready to traverse both boundary and do the stiching.
+
+ // But first, we create the new full_cells in the light triangulation,
+ // with as much adjacency information as possible.
+
+ // Create new full_cells with vertices
+ for( typename Dark_full_cells::iterator it = conflict_zone.begin(); it != conflict_zone.end(); ++it )
+ {
+ Full_cell_handle new_s = new_full_cell();
+ (*it)->data().light_copy_ = new_s;
+ for( int i = 0; i <= current_dimension(); ++i )
+ tds().associate_vertex_with_full_cell(new_s, i, (*it)->vertex(i)->data());
+ if( dark_ret_s == *it )
+ ret_s = new_s;
+ }
+
+ // Setup adjacencies inside the hole
+ for( typename Dark_full_cells::iterator it = conflict_zone.begin(); it != conflict_zone.end(); ++it )
+ {
+ Full_cell_handle new_s = (*it)->data().light_copy_;
+ for( int i = 0; i <= current_dimension(); ++i )
+ if( conflict_zone.contains((*it)->neighbor(i)) )
+ tds().set_neighbors(new_s, i, (*it)->neighbor(i)->data().light_copy_, (*it)->mirror_index(i));
+ }
+
+ // 3. Stitch
+ simps.make_searchable();
+ typedef std::queue<std::pair<Facet, Dark_facet> > Queue;
+ Queue q;
+ q.push(std::make_pair(light_ft, dark_ft));
+ dark_s = dark_side.full_cell(dark_ft);
+ int dark_i = dark_side.index_of_covertex(dark_ft);
+ // mark dark_ft as visited:
+ // TODO try by marking with Dark_v_handle (vertex)
+ dark_s->neighbor(dark_i)->set_neighbor(dark_s->mirror_index(dark_i), Dark_s_handle());
+ while( ! q.empty() )
+ {
+ std::pair<Facet, Dark_facet> p = q.front();
+ q.pop();
+ light_ft = p.first;
+ dark_ft = p.second;
+ light_s = full_cell(light_ft);
+ int light_i = index_of_covertex(light_ft);
+ dark_s = dark_side.full_cell(dark_ft);
+ int dark_i = dark_side.index_of_covertex(dark_ft);
+ Full_cell_handle light_n = light_s->neighbor(light_i);
+ set_neighbors(dark_s->data().light_copy_, dark_i, light_n, light_s->mirror_index(light_i));
+ for( int di = 0; di <= current_dimension(); ++di )
+ {
+ if( di == dark_i )
+ continue;
+ int li = light_s->index(dark_s->vertex(di)->data());
+ Rotor light_r(light_s, li, light_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))) )
+ light_r = rotate_rotor(light_r);
+
+ while( conflict_zone.contains(cpp11::get<0>(dark_r)->neighbor(cpp11::get<1>(dark_r))) )
+ dark_r = dark_side.rotate_rotor(dark_r);
+
+ Dark_s_handle dark_ns = cpp11::get<0>(dark_r);
+ int dark_ni = cpp11::get<1>(dark_r);
+ Full_cell_handle light_ns = cpp11::get<0>(light_r);
+ int light_ni = cpp11::get<1>(light_r);
+ // mark dark_r as visited:
+ // TODO try by marking with Dark_v_handle (vertex)
+ Dark_s_handle outside = dark_ns->neighbor(dark_ni);
+ Dark_v_handle mirror = dark_ns->mirror_vertex(dark_ni, current_dimension());
+ int dn = outside->index(mirror);
+ if( Dark_s_handle() == outside->neighbor(dn) )
+ continue;
+ outside->set_neighbor(dn, Dark_s_handle());
+ q.push(std::make_pair(Facet(light_ns, light_ni), Dark_facet(dark_ns, dark_ni)));
+ }
+ }
+ tds().delete_full_cells(simps.begin(), simps.end());
+ tds().delete_vertex(v);
+ return ret_s;
+}
+
+template< typename Traits, typename TDS >
+void
+Regular_triangulation<Traits, TDS>
+::remove_decrease_dimension(Vertex_handle v)
+{
+ CGAL_precondition( current_dimension() >= 0 );
+ tds().remove_decrease_dimension(v, infinite_vertex());
+ // reset the predicates:
+ reset_flat_orientation();
+ if( 1 <= current_dimension() )
+ {
+ Full_cell_handle inf_v_cell = infinite_vertex()->full_cell();
+ int inf_v_index = inf_v_cell->index(infinite_vertex());
+ Full_cell_handle s = inf_v_cell->neighbor(inf_v_index);
+ Orientation o = orientation(s);
+ CGAL_assertion( ZERO != o );
+ if( NEGATIVE == o )
+ reorient_full_cells();
+ }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSERTIONS
+
+template< typename Traits, typename TDS >
+typename Regular_triangulation<Traits, TDS>::Vertex_handle
+Regular_triangulation<Traits, TDS>
+::insert(const Weighted_point & p, Locate_type lt, const Face & f, const Facet & ft, Full_cell_handle s)
+{
+ switch( lt )
+ {
+ case Base::OUTSIDE_AFFINE_HULL:
+ return insert_outside_affine_hull(p);
+ break;
+ case Base::ON_VERTEX:
+ {
+ Vertex_handle v = s->vertex(f.index(0));
+ typename RTTraits::Compute_weight_d pw =
+ geom_traits().compute_weight_d_object();
+
+ if (pw(p) == pw(v->point()))
+ return v;
+ // If dim == 0 and the new point has a bigger weight,
+ // we just replace the point, and the former point gets hidden
+ else if (current_dimension() == 0)
+ {
+ if (pw(p) > pw(v->point()))
+ {
+ m_hidden_points.push_back(v->point());
+ v->set_point(p);
+ return v;
+ }
+ // Otherwise, the new point is hidden
+ else
+ {
+ m_hidden_points.push_back(p);
+ return Vertex_handle();
+ }
+ }
+ // Otherwise, we apply the "normal" algorithm
+
+ // !NO break here!
+ }
+ default:
+ return insert_in_conflicting_cell(p, s);
+ }
+}
+
+/*
+Inserts the point `p` in the regular triangulation. Returns a handle to the
+newly created vertex at that position.
+\pre The point `p`
+must lie outside the affine hull of the regular triangulation. This implies that
+`rt`.`current_dimension()` must be smaller than `rt`.`maximal_dimension()`.
+*/
+template< typename Traits, typename TDS >
+typename Regular_triangulation<Traits, TDS>::Vertex_handle
+Regular_triangulation<Traits, TDS>
+::insert_outside_affine_hull(const Weighted_point & p)
+{
+ // we don't use Base::insert_outside_affine_hull(...) because here, we
+ // also need to reset the side_of_oriented_subsphere functor.
+ CGAL_precondition( current_dimension() < maximal_dimension() );
+ Vertex_handle v = tds().insert_increase_dimension(infinite_vertex());
+ // reset the predicates:
+ reset_flat_orientation();
+ v->set_point(p);
+ if( current_dimension() >= 1 )
+ {
+ Full_cell_handle inf_v_cell = infinite_vertex()->full_cell();
+ int inf_v_index = inf_v_cell->index(infinite_vertex());
+ Full_cell_handle s = inf_v_cell->neighbor(inf_v_index);
+ Orientation o = orientation(s);
+ CGAL_assertion( ZERO != o );
+ if( NEGATIVE == o )
+ reorient_full_cells();
+
+ // We just inserted the second finite point and the right infinite
+ // cell is like : (inf_v, v), but we want it to be (v, inf_v) to be
+ // consistent with the rest of the cells
+ if (current_dimension() == 1)
+ {
+ // Is "inf_v_cell" the right infinite cell? Then inf_v_index should be 1
+ if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
+ && inf_v_index == 0)
+ {
+ inf_v_cell->swap_vertices(current_dimension() - 1, current_dimension());
+ }
+ else
+ {
+ inf_v_cell = inf_v_cell->neighbor((inf_v_index + 1) % 2);
+ inf_v_index = inf_v_cell->index(infinite_vertex());
+ // Is "inf_v_cell" the right infinite cell? Then inf_v_index should be 1
+ if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
+ && inf_v_index == 0)
+ {
+ inf_v_cell->swap_vertices(current_dimension() - 1, current_dimension());
+ }
+ }
+ }
+ }
+ return v;
+}
+
+template< typename Traits, typename TDS >
+typename Regular_triangulation<Traits, TDS>::Vertex_handle
+Regular_triangulation<Traits, TDS>
+::insert_if_in_star(const Weighted_point & p,
+ Vertex_handle star_center,
+ Locate_type lt,
+ const Face & f,
+ const Facet & ft,
+ Full_cell_handle s)
+{
+ switch( lt )
+ {
+ case Base::OUTSIDE_AFFINE_HULL:
+ return insert_outside_affine_hull(p);
+ break;
+ case Base::ON_VERTEX:
+ {
+ Vertex_handle v = s->vertex(f.index(0));
+ typename RTTraits::Compute_weight_d pw =
+ geom_traits().compute_weight_d_object();
+ if (pw(p) == pw(v->point()))
+ return v;
+ // If dim == 0 and the new point has a bigger weight,
+ // we replace the point
+ else if (current_dimension() == 0)
+ {
+ if (pw(p) > pw(v->point()))
+ v->set_point(p);
+ else
+ return v;
+ }
+ // Otherwise, we apply the "normal" algorithm
+
+ // !NO break here!
+ }
+ default:
+ return insert_in_conflicting_cell(p, s, star_center);
+ }
+
+ return Vertex_handle();
+}
+
+/*
+[Undocumented function]
+
+Inserts the point `p` in the regular triangulation. `p` must be
+in conflict with the second parameter `c`, which is used as a
+starting point for `compute_conflict_zone`.
+The function is faster than the standard `insert` function since
+it does not need to call `locate`.
+
+If this insertion creates a vertex, this vertex is returned.
+
+If `p` coincides with an existing vertex and has a greater weight,
+then the existing weighted point becomes hidden and `p` replaces it as vertex
+of the triangulation.
+
+If `p` coincides with an already existing vertex (both point and
+weights being equal), then this vertex is returned and the triangulation
+remains unchanged.
+
+Otherwise if `p` does not appear as a vertex of the triangulation,
+then it is stored as a hidden point and this method returns the default
+constructed handle.
+
+\pre The point `p` must be in conflict with the full cell `c`.
+*/
+
+template< typename Traits, typename TDS >
+typename Regular_triangulation<Traits, TDS>::Vertex_handle
+Regular_triangulation<Traits, TDS>
+::insert_in_conflicting_cell(const Weighted_point & p,
+ Full_cell_handle s,
+ Vertex_handle only_if_this_vertex_is_in_the_cz)
+{
+ typedef std::vector<Full_cell_handle> Full_cell_h_vector;
+
+ bool in_conflict = is_in_conflict(p, s);
+
+ // If p is not in conflict with s, then p is hidden
+ // => we don't insert it
+ if (!in_conflict)
+ {
+ m_hidden_points.push_back(p);
+ return Vertex_handle();
+ }
+ else
+ {
+ Full_cell_h_vector cs; // for storing conflicting full_cells.
+ cs.reserve(64);
+ std::back_insert_iterator<Full_cell_h_vector> out(cs);
+ Facet ft = compute_conflict_zone(p, s, out);
+
+ // Check if the CZ contains "only_if_this_vertex_is_in_the_cz"
+ if (only_if_this_vertex_is_in_the_cz != Vertex_handle()
+ && !does_cell_range_contain_vertex(cs.begin(), cs.end(),
+ only_if_this_vertex_is_in_the_cz))
+ {
+ return Vertex_handle();
+ }
+
+ // Otherwise, proceed with the insertion
+ std::vector<Vertex_handle> cz_vertices;
+ cz_vertices.reserve(64);
+ process_conflict_zone(cs.begin(), cs.end(),
+ std::back_inserter(cz_vertices));
+
+ Vertex_handle ret = insert_in_hole(p, cs.begin(), cs.end(), ft);
+
+ process_cz_vertices_after_insertion(cz_vertices.begin(), cz_vertices.end());
+
+ return ret;
+ }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GATHERING CONFLICTING SIMPLICES
+
+// NOT DOCUMENTED
+template< typename Traits, typename TDS >
+template< typename OrientationPred >
+Oriented_side
+Regular_triangulation<Traits, TDS>
+::perturbed_power_side_of_power_sphere(const Weighted_point & p, Full_cell_const_handle s,
+ const OrientationPred & ori) const
+{
+ CGAL_precondition_msg( ! is_infinite(s), "full cell must be finite");
+ CGAL_expensive_precondition( POSITIVE == orientation(s) );
+ typedef std::vector<const Weighted_point *> Points;
+ Points points(current_dimension() + 2);
+ int i(0);
+ for( ; i <= current_dimension(); ++i )
+ points[i] = &(s->vertex(i)->point());
+ points[i] = &p;
+ std::sort(points.begin(), points.end(),
+ internal::Triangulation::Compare_points_for_perturbation<Self>(*this));
+ typename Points::const_reverse_iterator cut_pt = points.rbegin();
+ Points test_points;
+ while( cut_pt != points.rend() )
+ {
+ if( &p == *cut_pt )
+ // because the full_cell "s" is assumed to be positively oriented
+ return ON_NEGATIVE_SIDE; // we consider |p| to lie outside the sphere
+ test_points.clear();
+ Point_const_iterator spit = points_begin(s);
+ int adjust_sign = -1;
+ for( i = 0; i < current_dimension(); ++i )
+ {
+ if( &(*spit) == *cut_pt )
+ {
+ ++spit;
+ adjust_sign = (((current_dimension() + i) % 2) == 0) ? -1 : +1;
+ }
+ test_points.push_back(&(*spit));
+ ++spit;
+ }
+ test_points.push_back(&p);
+
+ typedef typename CGAL::Iterator_project<
+ typename Points::iterator,
+ internal::Triangulation::Point_from_pointer<Self>,
+ const Weighted_point &, const Weighted_point *
+ > Point_pointer_iterator;
+
+ Orientation ori_value = ori(
+ Point_pointer_iterator(test_points.begin()),
+ Point_pointer_iterator(test_points.end()));
+
+ if( ZERO != ori_value )
+ return Oriented_side( - adjust_sign * ori_value );
+
+ ++cut_pt;
+ }
+ CGAL_assertion(false); // we should never reach here
+ return ON_NEGATIVE_SIDE;
+}
+
+template< typename Traits, typename TDS >
+bool
+Regular_triangulation<Traits, TDS>
+::is_in_conflict(const Weighted_point & p, Full_cell_const_handle s) const
+{
+ CGAL_precondition( 1 <= current_dimension() );
+ if( current_dimension() < maximal_dimension() )
+ {
+ Conflict_pred_in_subspace c(
+ *this, p,
+ coaffine_orientation_predicate(),
+ power_side_of_power_sphere_for_non_maximal_dim_predicate());
+ return c(s);
+ }
+ else
+ {
+ Orientation_d ori = geom_traits().orientation_d_object();
+ Power_side_of_power_sphere_d side = geom_traits().power_side_of_power_sphere_d_object();
+ Conflict_pred_in_fullspace c(*this, p, ori, side);
+ return c(s);
+ }
+}
+
+template< typename Traits, typename TDS >
+template< typename OutputIterator >
+typename Regular_triangulation<Traits, TDS>::Facet
+Regular_triangulation<Traits, TDS>
+::compute_conflict_zone(const Weighted_point & p, Full_cell_handle s, OutputIterator out) const
+{
+ CGAL_precondition( 1 <= current_dimension() );
+ if( current_dimension() < maximal_dimension() )
+ {
+ Conflict_pred_in_subspace c(
+ *this, p,
+ coaffine_orientation_predicate(),
+ power_side_of_power_sphere_for_non_maximal_dim_predicate());
+ Conflict_traversal_pred_in_subspace tp(*this, c);
+ return tds().gather_full_cells(s, tp, out);
+ }
+ else
+ {
+ Orientation_d ori = geom_traits().orientation_d_object();
+ Power_side_of_power_sphere_d side = geom_traits().power_side_of_power_sphere_d_object();
+ Conflict_pred_in_fullspace c(*this, p, ori, side);
+ Conflict_traversal_pred_in_fullspace tp(*this, c);
+ return tds().gather_full_cells(s, tp, out);
+ }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
+
+template< typename Traits, typename TDS >
+bool
+Regular_triangulation<Traits, TDS>
+::is_valid(bool verbose, int level) const
+{
+ if (!Base::is_valid(verbose, level))
+ return false;
+
+ int dim = current_dimension();
+ if (dim == maximal_dimension())
+ {
+ for (Finite_full_cell_const_iterator cit = finite_full_cells_begin() ;
+ cit != finite_full_cells_end() ; ++cit )
+ {
+ Full_cell_const_handle ch = cit.base();
+ for(int i = 0; i < dim+1 ; ++i )
+ {
+ // If the i-th neighbor is not an infinite cell
+ Vertex_handle opposite_vh =
+ ch->neighbor(i)->vertex(ch->neighbor(i)->index(ch));
+ if (!is_infinite(opposite_vh))
+ {
+ Power_side_of_power_sphere_d side =
+ geom_traits().power_side_of_power_sphere_d_object();
+ if (side(Point_const_iterator(ch->vertices_begin()),
+ Point_const_iterator(ch->vertices_end()),
+ opposite_vh->point()) == ON_POSITIVE_SIDE)
+ {
+ if (verbose)
+ CGAL_warning_msg(false, "Non-empty sphere");
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+} //namespace CGAL
+
+#endif //CGAL_REGULAR_TRIANGULATION_H
diff --git a/include/gudhi_patches/CGAL/Regular_triangulation_traits_adapter.h b/include/gudhi_patches/CGAL/Regular_triangulation_traits_adapter.h
new file mode 100644
index 00000000..78bb95a6
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Regular_triangulation_traits_adapter.h
@@ -0,0 +1,288 @@
+// 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_REGULAR_TRIANGULATION_TRAITS_ADAPTER_H
+#define CGAL_REGULAR_TRIANGULATION_TRAITS_ADAPTER_H
+
+#include <CGAL/basic.h>
+
+#include <boost/iterator/transform_iterator.hpp>
+
+namespace CGAL {
+
+// Wrapper class to make a model of `RegularTriangulationTraits` easily usable
+// by the `Regular_triangulation` class. By using this class:
+// - Point_d (used by `Triangulation` and the TDS) becomes a weighted point
+// - Predicates and functors such as Less_coordinate_d or Orientation_d
+// can be called using weighted points instead of bare points (this is
+// needed because `Weighted_point_d` is not convertible to `Point_d`)
+// This way, `Triangulation` works perfectly well with weighted points.
+
+template <class K>
+class Regular_triangulation_traits_adapter
+ : public K
+{
+public:
+ typedef K Base;
+
+ // Required by TriangulationTraits
+ typedef typename K::Dimension Dimension;
+ typedef typename K::FT FT;
+ typedef typename K::Flat_orientation_d Flat_orientation_d;
+ typedef typename K::Weighted_point_d Point_d;
+
+ // Required by RegularTriangulationTraits
+ typedef typename K::Point_d Bare_point_d;
+ typedef typename K::Weighted_point_d Weighted_point_d;
+ typedef typename K::Construct_point_d Construct_point_d;
+ typedef typename K::Compute_weight_d Compute_weight_d;
+ typedef typename K::Power_side_of_power_sphere_d Power_side_of_power_sphere_d;
+ typedef typename K::In_flat_power_side_of_power_sphere_d
+ In_flat_power_side_of_power_sphere_d;
+
+ //===========================================================================
+ // Custom types
+ //===========================================================================
+
+ // Required by SpatialSortingTraits_d
+ class Less_coordinate_d
+ {
+ const K &m_kernel;
+
+ public:
+ typedef bool result_type;
+
+ Less_coordinate_d(const K &kernel)
+ : m_kernel(kernel) {}
+
+ result_type operator()(
+ Weighted_point_d const& p, Weighted_point_d const& q, int i) const
+ {
+ Construct_point_d cp = m_kernel.construct_point_d_object();
+ return m_kernel.less_coordinate_d_object() (cp(p), cp(q), i);
+ }
+ };
+
+ //===========================================================================
+
+ // Required by TriangulationTraits
+ class Orientation_d
+ {
+ const K &m_kernel;
+
+ public:
+ typedef Orientation result_type;
+
+ Orientation_d(const K &kernel)
+ : m_kernel(kernel) {}
+
+ template <typename ForwardIterator>
+ result_type operator()(ForwardIterator start, ForwardIterator end) const
+ {
+ Construct_point_d cp = m_kernel.construct_point_d_object();
+ return m_kernel.orientation_d_object() (
+ boost::make_transform_iterator(start, cp),
+ boost::make_transform_iterator(end, cp)
+ );
+ }
+ };
+
+ //===========================================================================
+
+ // Required by TriangulationTraits
+ class Construct_flat_orientation_d
+ {
+ const K &m_kernel;
+
+ public:
+ typedef Flat_orientation_d result_type;
+
+ Construct_flat_orientation_d(const K &kernel)
+ : m_kernel(kernel) {}
+
+ template <typename ForwardIterator>
+ result_type operator()(ForwardIterator start, ForwardIterator end) const
+ {
+ Construct_point_d cp = m_kernel.construct_point_d_object();
+ return m_kernel.construct_flat_orientation_d_object() (
+ boost::make_transform_iterator(start, cp),
+ boost::make_transform_iterator(end, cp)
+ );
+ }
+ };
+
+
+ //===========================================================================
+
+ // Required by TriangulationTraits
+ class In_flat_orientation_d
+ {
+ const K &m_kernel;
+
+ public:
+ typedef Orientation result_type;
+
+ In_flat_orientation_d(const K &kernel)
+ : m_kernel(kernel) {}
+
+ template <typename ForwardIterator>
+ result_type operator()(Flat_orientation_d orient,
+ ForwardIterator start, ForwardIterator end) const
+ {
+ Construct_point_d cp = m_kernel.construct_point_d_object();
+ return m_kernel.in_flat_orientation_d_object() (
+ orient,
+ boost::make_transform_iterator(start, cp),
+ boost::make_transform_iterator(end, cp)
+ );
+ }
+ };
+
+ //===========================================================================
+
+ // Required by TriangulationTraits
+ class Contained_in_affine_hull_d
+ {
+ const K &m_kernel;
+
+ public:
+ typedef bool result_type;
+
+ Contained_in_affine_hull_d(const K &kernel)
+ : m_kernel(kernel) {}
+
+ template <typename ForwardIterator>
+ result_type operator()(ForwardIterator start, ForwardIterator end,
+ const Weighted_point_d & p) const
+ {
+ Construct_point_d cp = m_kernel.construct_point_d_object();
+ return m_kernel.contained_in_affine_hull_d_object() (
+ boost::make_transform_iterator(start, cp),
+ boost::make_transform_iterator(end, cp),
+ cp(p)
+ );
+ }
+ };
+
+ //===========================================================================
+
+ // Required by TriangulationTraits
+ class Compare_lexicographically_d
+ {
+ const K &m_kernel;
+
+ public:
+ typedef Comparison_result result_type;
+
+ Compare_lexicographically_d(const K &kernel)
+ : m_kernel(kernel) {}
+
+ result_type operator()(
+ const Weighted_point_d & p, const Weighted_point_d & q) const
+ {
+ Construct_point_d cp = m_kernel.construct_point_d_object();
+ return m_kernel.compare_lexicographically_d_object()(cp(p), cp(q));
+ }
+ };
+
+ //===========================================================================
+
+ // Only for Triangulation_off_ostream.h (undocumented)
+ class Compute_coordinate_d
+ {
+ const K &m_kernel;
+
+ public:
+ typedef FT result_type;
+
+ Compute_coordinate_d(const K &kernel)
+ : m_kernel(kernel) {}
+
+ result_type operator()(
+ const Weighted_point_d & p, const int i) const
+ {
+ Construct_point_d cp = m_kernel.construct_point_d_object();
+ return m_kernel.compute_coordinate_d_object()(cp(p), i);
+ }
+ };
+
+ //===========================================================================
+
+ // To satisfy SpatialSortingTraits_d
+ // and also for Triangulation_off_ostream.h (undocumented)
+ class Point_dimension_d
+ {
+ const K &m_kernel;
+
+ public:
+ typedef int result_type;
+
+ Point_dimension_d(const K &kernel)
+ : m_kernel(kernel) {}
+
+ result_type operator()(
+ const Weighted_point_d & p) const
+ {
+ Construct_point_d cp = m_kernel.construct_point_d_object();
+ return m_kernel.point_dimension_d_object()(cp(p));
+ }
+ };
+
+ //===========================================================================
+ // Object creation
+ //===========================================================================
+
+ Less_coordinate_d less_coordinate_d_object() const
+ {
+ return Less_coordinate_d(*this);
+ }
+ Contained_in_affine_hull_d contained_in_affine_hull_d_object() const
+ {
+ return Contained_in_affine_hull_d(*this);
+ }
+ Orientation_d orientation_d_object() const
+ {
+ return Orientation_d(*this);
+ }
+ Construct_flat_orientation_d construct_flat_orientation_d_object() const
+ {
+ return Construct_flat_orientation_d(*this);
+ }
+ In_flat_orientation_d in_flat_orientation_d_object() const
+ {
+ return In_flat_orientation_d(*this);
+ }
+ Compare_lexicographically_d compare_lexicographically_d_object() const
+ {
+ return Compare_lexicographically_d(*this);
+ }
+ Compute_coordinate_d compute_coordinate_d_object() const
+ {
+ return Compute_coordinate_d(*this);
+ }
+ Point_dimension_d point_dimension_d_object() const
+ {
+ return Point_dimension_d(*this);
+ }
+};
+
+
+} //namespace CGAL
+
+#endif // CGAL_REGULAR_TRIANGULATION_TRAITS_ADAPTER_H
diff --git a/include/gudhi_patches/CGAL/TDS_full_cell_default_storage_policy.h b/include/gudhi_patches/CGAL/TDS_full_cell_default_storage_policy.h
new file mode 100644
index 00000000..9a6030e5
--- /dev/null
+++ b/include/gudhi_patches/CGAL/TDS_full_cell_default_storage_policy.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_TDS_FULL_CELL_DEFAULT_STORAGE_POLICY_H
+#define CGAL_TDS_FULL_CELL_DEFAULT_STORAGE_POLICY_H
+
+#include <CGAL/Dimension.h>
+#include <CGAL/Compact_container.h>
+#include <CGAL/internal/Static_or_dynamic_array.h>
+
+#include <boost/cstdint.hpp>
+
+namespace CGAL {
+
+// POLICY TAG
+
+struct TDS_full_cell_default_storage_policy {}; // stores no additional data. Uses XOR trick.
+
+template< typename V, typename S, typename D, typename StoragePolicy >
+struct TFC_data; // TFC = Triangulation Full Cell
+
+template< typename Vertex_handle, typename Full_cell_handle, typename Dimen >
+struct TFC_data< Vertex_handle, Full_cell_handle, Dimen, TDS_full_cell_default_storage_policy >
+{
+ typedef typename internal::Dimen_plus_one<Dimen>::type Dimen_plus;
+ typedef typename internal::S_or_D_array< Vertex_handle, Dimen_plus, true > Vertex_handle_array;
+ typedef typename internal::S_or_D_array< Full_cell_handle, Dimen_plus > Full_cell_handle_array;
+
+ Vertex_handle_array vertices_;
+ Full_cell_handle_array neighbors_;
+
+ TFC_data(const int dmax)
+ : vertices_(dmax+1), neighbors_(dmax+1)
+ {}
+ void* for_compact_container() const { return vertices_.for_compact_container(); }
+ void* & for_compact_container() { return vertices_.for_compact_container(); }
+ int dimension() const { return ( vertices_.size() - 1 ); }
+ void set_mirror_index(const int, const int) {}
+#ifdef BOOST_NO_INT64_T
+ typedef std::ptrdiff_t Xor_type;
+#else
+ typedef boost::int_least64_t Xor_type;
+#endif
+ Xor_type xor_of_vertices(const int cur_dim) const
+ {
+ Xor_type result(0);
+ for( int i = 0; i <= cur_dim; ++i )
+ result ^= reinterpret_cast<Xor_type>(&(*vertices_[i]));
+ return result;
+ }
+ // ASSUMES |*this| is indeed a neighbor of neighbor(i):
+ // NOT correct when the hole (in insert_in_hole) is doubly covered.
+ int mirror_index(const int i) const
+ {
+ int index = 0;
+ Full_cell_handle n = neighbors_[i];
+ Full_cell_handle o = n->neighbor(index);
+ while( &(o->combinatorics_) != this )
+ o = n->neighbor(++index);
+ return index;
+ }
+ Vertex_handle mirror_vertex(const int i, const int cur_dim) const
+ {
+ Xor_type opp_vertex = xor_of_vertices(cur_dim)
+ ^ neighbors_[i]->xor_of_vertices(cur_dim)
+ ^ reinterpret_cast<Xor_type>(&(*vertices_[i]));
+ Vertex_handle mirror;
+ typedef typename Vertex_handle::pointer pointer;
+ // mirror.set_pointer(reinterpret_cast<pointer>(opp_vertex));
+ mirror = Compact_container<typename Vertex_handle::value_type>
+ ::s_iterator_to(*(reinterpret_cast<pointer>(opp_vertex)));
+ return mirror;
+ }
+ void swap_vertices(const int d1, const int d2)
+ {
+ std::swap(vertices_[d1], vertices_[d2]);
+ std::swap(neighbors_[d1], neighbors_[d2]);
+ }
+};
+
+} //namespace CGAL
+
+#endif // CGAL_TDS_FULL_CELL_DEFAULT_STORAGE_POLICY_H
diff --git a/include/gudhi_patches/CGAL/TDS_full_cell_mirror_storage_policy.h b/include/gudhi_patches/CGAL/TDS_full_cell_mirror_storage_policy.h
new file mode 100644
index 00000000..095dfe68
--- /dev/null
+++ b/include/gudhi_patches/CGAL/TDS_full_cell_mirror_storage_policy.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_TDS_FULL_CELL_MIRROR_STORAGE_POLICY_H
+#define CGAL_TDS_FULL_CELL_MIRROR_STORAGE_POLICY_H
+
+#include <CGAL/TDS_full_cell_default_storage_policy.h>
+
+namespace CGAL {
+
+// POLICY TAGS
+
+struct TDS_full_cell_mirror_storage_policy {}; // Stores the mirror index of all vertices.
+
+template< typename Vertex_handle, typename Full_cell_handle, typename Maximal_dimension >
+struct TFC_data< Vertex_handle, Full_cell_handle, Maximal_dimension, TDS_full_cell_mirror_storage_policy >
+: public TFC_data< Vertex_handle, Full_cell_handle, Maximal_dimension, TDS_full_cell_default_storage_policy >
+{
+ typedef TFC_data< Vertex_handle, Full_cell_handle, Maximal_dimension, TDS_full_cell_default_storage_policy > Base;
+ typedef typename Base::Vertex_handle_array Vertex_handle_array;
+ typedef typename Base::Full_cell_handle_array Full_cell_handle_array;
+ typedef typename internal::S_or_D_array< int, typename Base::Dimen_plus > Int_array;
+
+private:
+ Int_array mirror_vertices_;
+
+public:
+ TFC_data(const int dmax)
+ : Base(dmax), mirror_vertices_(dmax+1)
+ {}
+
+ void set_mirror_index(const int i, const int index)
+ {
+ mirror_vertices_[i] = index;
+ }
+ int mirror_index(const int i) const
+ {
+ return mirror_vertices_[i];
+ }
+ Vertex_handle mirror_vertex(const int i, const int) const
+ {
+ return Base::neighbors_[i]->vertex(mirror_index(i));
+ }
+ void swap_vertices(const int d1, const int d2)
+ {
+ Base::swap_vertices(d1, d2);
+ std::swap(mirror_vertices_[d1], mirror_vertices_[d2]);
+ Base::neighbors_[d1]->set_mirror_index(mirror_vertices_[d1], d1);
+ Base::neighbors_[d2]->set_mirror_index(mirror_vertices_[d2], d2);
+ }
+};
+
+} //namespace CGAL
+
+#endif // CGAL_TDS_FULL_CELL_MIRROR_STORAGE_POLICY_H
diff --git a/include/gudhi_patches/CGAL/Triangulation.h b/include/gudhi_patches/CGAL/Triangulation.h
new file mode 100644
index 00000000..906df92e
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Triangulation.h
@@ -0,0 +1,1424 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_TRIANGULATION_H
+#define CGAL_TRIANGULATION_H
+
+#include <CGAL/internal/Triangulation/utilities.h>
+#include <CGAL/Triangulation_data_structure.h>
+#include <CGAL/Triangulation_full_cell.h>
+#include <CGAL/Triangulation_vertex.h>
+#include <CGAL/Iterator_project.h>
+#include <CGAL/spatial_sort.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/iterator.h>
+#include <CGAL/Default.h>
+#include <CGAL/Random.h>
+
+#include <boost/iterator/filter_iterator.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+
+namespace CGAL {
+
+// Iterator which iterates over vertex_handle's, but returns a point when
+// dereferenced. If the current
+// vertex_handle vh == vh_where_point_should_be_substituted, it returns
+// "subtitute_point", otherwise, it returns vh->point()
+template<class VertexHandleConstIter>
+class Substitute_point_in_vertex_iterator
+{
+ typedef typename std::iterator_traits<VertexHandleConstIter>::value_type Vertex_handle;
+ typedef typename Vertex_handle::value_type Vertex;
+ typedef typename Vertex::Point Point;
+
+public:
+ typedef Point const& result_type; // For result_of
+
+ Substitute_point_in_vertex_iterator(
+ Vertex_handle vh_where_point_should_be_substituted,
+ Point const *subtitute_point)
+ : vh_where_point_should_be_substituted_(vh_where_point_should_be_substituted)
+ , subtitute_point_(subtitute_point)
+ {}
+
+ result_type operator()(Vertex_handle vh) const
+ {
+ if (vh == vh_where_point_should_be_substituted_)
+ return *subtitute_point_;
+ else
+ return vh->point();
+ }
+
+private:
+ Vertex_handle vh_where_point_should_be_substituted_;
+ Point const *subtitute_point_;
+
+};
+
+
+template < class TriangulationTraits, class TDS_ = Default >
+class Triangulation
+{
+ typedef typename TriangulationTraits::Dimension Maximal_dimension_;
+ typedef typename Default::Get<TDS_, Triangulation_data_structure
+ < Maximal_dimension_,
+ Triangulation_vertex<TriangulationTraits>,
+ Triangulation_full_cell<TriangulationTraits> >
+ >::type TDS;
+ typedef Triangulation<TriangulationTraits, TDS_> Self;
+
+protected:
+ typedef typename TriangulationTraits::Flat_orientation_d Flat_orientation_d;
+ typedef typename TriangulationTraits::Construct_flat_orientation_d Construct_flat_orientation_d;
+ typedef typename TriangulationTraits::In_flat_orientation_d In_flat_orientation_d;
+
+ // Wrapper
+ struct Coaffine_orientation_d
+ {
+ boost::optional<Flat_orientation_d>* fop;
+ Construct_flat_orientation_d cfo;
+ In_flat_orientation_d ifo;
+
+ Coaffine_orientation_d(
+ boost::optional<Flat_orientation_d>& x,
+ Construct_flat_orientation_d const&y,
+ In_flat_orientation_d const&z)
+ : fop(&x), cfo(y), ifo(z) {}
+
+ template<class Iter>
+ CGAL::Orientation operator()(Iter a, Iter b) const
+ {
+ if (*fop)
+ return ifo(fop->get(),a,b);
+ *fop = cfo(a,b);
+ CGAL_assertion(ifo(fop->get(),a,b) == CGAL::POSITIVE);
+ return CGAL::POSITIVE;
+ }
+ };
+
+ void reset_flat_orientation()
+ {
+ if (current_dimension() == preset_flat_orientation_.first)
+ {
+ CGAL_assertion(preset_flat_orientation_.second != NULL);
+ flat_orientation_ = *preset_flat_orientation_.second;
+ }
+ else
+ flat_orientation_ = boost::none;
+ }
+
+ typedef typename TriangulationTraits::Orientation_d
+ Orientation_d;
+
+public:
+
+ typedef TriangulationTraits Geom_traits;
+ typedef TDS Triangulation_ds;
+
+ typedef typename TDS::Vertex Vertex;
+ typedef typename TDS::Full_cell Full_cell;
+ typedef typename TDS::Facet Facet;
+ typedef typename TDS::Face Face;
+
+ typedef Maximal_dimension_ Maximal_dimension;
+ typedef typename Geom_traits::Point_d Point;
+
+ typedef typename TDS::Vertex_handle Vertex_handle;
+ typedef typename TDS::Vertex_iterator Vertex_iterator;
+ typedef typename TDS::Vertex_const_handle Vertex_const_handle;
+ typedef typename TDS::Vertex_const_iterator Vertex_const_iterator;
+
+ typedef typename TDS::Full_cell_handle Full_cell_handle;
+ typedef typename TDS::Full_cell_iterator Full_cell_iterator;
+ typedef typename TDS::Full_cell_const_handle Full_cell_const_handle;
+ typedef typename TDS::Full_cell_const_iterator Full_cell_const_iterator;
+
+ typedef typename TDS::Facet_iterator Facet_iterator;
+
+ typedef typename TDS::size_type size_type;
+ typedef typename TDS::difference_type difference_type;
+
+ /// The type of location a new point is found lying on
+ enum Locate_type
+ {
+ ON_VERTEX = 0 // simplex of dimension 0
+ , IN_FACE = 1 // simplex of dimension in [ 1, |current_dimension()| - 2 ]
+ , IN_FACET = 2 // simplex of dimension |current_dimension()| - 1
+ , IN_FULL_CELL = 3 /// simplex of dimension |current_dimension()|
+ , OUTSIDE_CONVEX_HULL = 4
+ , OUTSIDE_AFFINE_HULL = 5
+ };
+
+ // Finite elements iterators
+
+ class Finiteness_predicate;
+
+ typedef boost::filter_iterator<Finiteness_predicate, Vertex_iterator>
+ Finite_vertex_iterator;
+ typedef boost::filter_iterator<Finiteness_predicate, Vertex_const_iterator>
+ Finite_vertex_const_iterator;
+ typedef boost::filter_iterator<Finiteness_predicate, Full_cell_iterator>
+ Finite_full_cell_iterator;
+ typedef boost::filter_iterator<Finiteness_predicate, Full_cell_const_iterator>
+ Finite_full_cell_const_iterator;
+ typedef boost::filter_iterator<Finiteness_predicate, Facet_iterator>
+ Finite_facet_iterator;
+
+protected: // DATA MEMBERS
+
+ Triangulation_ds tds_;
+ const Geom_traits kernel_;
+ Vertex_handle infinity_;
+ mutable std::vector<Oriented_side> orientations_;
+ mutable boost::optional<Flat_orientation_d> flat_orientation_;
+ // The user can specify a Flat_orientation_d object to be used for
+ // orienting simplices of a specific dimension
+ // (= preset_flat_orientation_.first)
+ // preset_flat_orientation_.first = numeric_limits<int>::max() otherwise)
+ std::pair<int, const Flat_orientation_d *> preset_flat_orientation_;
+ // for stochastic walk in the locate() function:
+ mutable Random rng_;
+#ifdef CGAL_TRIANGULATION_STATISTICS
+ mutable unsigned long walk_size_;
+#endif
+
+protected: // HELPER FUNCTIONS
+
+ typedef CGAL::Iterator_project<
+ typename Full_cell::Vertex_handle_const_iterator,
+ internal::Triangulation::Point_from_vertex_handle<Vertex_handle, Point>
+ > Point_const_iterator;
+
+ Point_const_iterator points_begin(Full_cell_const_handle c) const
+ { return Point_const_iterator(c->vertices_begin()); }
+ Point_const_iterator points_end(Full_cell_const_handle c) const
+ { return Point_const_iterator(c->vertices_end()); }
+ Point_const_iterator points_begin(Full_cell_handle c) const
+ { return Point_const_iterator(c->vertices_begin()); }
+ Point_const_iterator points_end(Full_cell_handle c) const
+ { return Point_const_iterator(c->vertices_end()); }
+
+public:
+
+ // FACETS OPERATIONS
+
+ Full_cell_handle full_cell(const Facet & f) const
+ {
+ return tds().full_cell(f);
+ }
+
+ int index_of_covertex(const Facet & f) const
+ {
+ return tds().index_of_covertex(f);
+ }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UTILITIES
+
+ // A co-dimension 2 sub-simplex. called a Rotor because we can rotate
+ // the two "covertices" around the sub-simplex. Useful for traversing the
+ // boundary of a hole. NOT DOCUMENTED
+ typedef cpp11::tuple<Full_cell_handle, int, int> Rotor;
+
+ // Commented out because it was causing "internal compiler error" in MSVC
+ /*Full_cell_handle full_cell(const Rotor & r) const // NOT DOCUMENTED
+ {
+ return cpp11::get<0>(r);
+ }
+ int index_of_covertex(const Rotor & r) const // NOT DOCUMENTED
+ {
+ return cpp11::get<1>(r);
+ }
+ int index_of_second_covertex(const Rotor & r) const // NOT DOCUMENTED
+ {
+ return cpp11::get<2>(r);
+ }*/
+ Rotor rotate_rotor(Rotor & r) // NOT DOCUMENTED...
+ {
+ int opposite = cpp11::get<0>(r)->mirror_index(cpp11::get<1>(r));
+ Full_cell_handle s = cpp11::get<0>(r)->neighbor(cpp11::get<1>(r));
+ int new_second = s->index(cpp11::get<0>(r)->vertex(cpp11::get<2>(r)));
+ return Rotor(s, new_second, opposite);
+ }
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS
+
+ Triangulation(int dim, const Geom_traits &k = Geom_traits())
+ : tds_(dim)
+ , kernel_(k)
+ , infinity_()
+ , preset_flat_orientation_((std::numeric_limits<int>::max)(),
+ (Flat_orientation_d*) NULL)
+ , rng_((long)0)
+#ifdef CGAL_TRIANGULATION_STATISTICS
+ ,walk_size_(0)
+#endif
+ {
+ clear();
+ }
+
+ // With this constructor,
+ // the user can specify a Flat_orientation_d object to be used for
+ // orienting simplices of a specific dimension
+ // (= preset_flat_orientation_.first)
+ // It it used for by dark triangulations created by DT::remove
+ Triangulation(
+ int dim,
+ const std::pair<int, const Flat_orientation_d *> &preset_flat_orientation,
+ const Geom_traits k = Geom_traits())
+ : tds_(dim)
+ , kernel_(k)
+ , infinity_()
+ , preset_flat_orientation_(preset_flat_orientation)
+ , rng_((long)0)
+#ifdef CGAL_TRIANGULATION_STATISTICS
+ ,walk_size_(0)
+#endif
+ {
+ clear();
+ }
+
+ Triangulation(const Triangulation & t2)
+ : tds_(t2.tds_)
+ , kernel_(t2.kernel_)
+ , infinity_()
+ , preset_flat_orientation_((std::numeric_limits<int>::max)(),
+ (Flat_orientation_d*) NULL)
+ , rng_(t2.rng_)
+#ifdef CGAL_TRIANGULATION_STATISTICS
+ ,walk_size_(t2.walk_size_)
+#endif
+ {
+ // We find the vertex at infinity by scanning the vertices of both
+ // triangulations. This works because Compact_container garantees that
+ // the vertices in the copy (*this) are stored in the same order as in
+ // the original triangulation (t2)
+ infinity_ = vertices_begin();
+ Vertex_const_iterator inf2 = t2.vertices_begin();
+ while( inf2 != t2.infinite_vertex() )
+ {
+ ++infinity_;
+ ++inf2;
+ }
+ // A full_cell has at most 1 + maximal_dimension() facets:
+ orientations_.resize(1 + maximal_dimension());
+ // Our coaffine orientation predicates HAS state member variables
+ reset_flat_orientation();
+ }
+
+ ~Triangulation() {}
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ACCESS FUNCTIONS
+
+ /* These three function are no longer needed since we do not use them anymore
+ in the Delaunay_triangulation::remove. *But*, they may reappear in the future
+ if we manage to passe the information that flags/TDS_data is available or not
+ for marking simplices in Delaunay_triangulation::remove. This would be useful
+ to make it a little faster, instead of binary searching if a simplex is marked
+ or not...
+ // NOT DOCUMENTED --
+ bool get_visited(Full_cell_handle s) const
+ {
+ return tds().get_visited(s);
+ }
+ // NOT DOCUMENTED --
+ bool get_visited(Full_cell_const_handle s) const
+ {
+ return tds().get_visited(s);
+ }
+
+ // NOT DOCUMENTED --
+ void set_visited(Full_cell_handle s, bool b) const
+ {
+ tds().set_visited(s, b);
+ } */
+
+ Coaffine_orientation_d coaffine_orientation_predicate() const
+ {
+ return Coaffine_orientation_d (
+ flat_orientation_,
+ geom_traits().construct_flat_orientation_d_object(),
+ geom_traits().in_flat_orientation_d_object()
+ );
+ }
+
+ const Triangulation_ds & tds() const
+ {
+ return tds_;
+ }
+
+ Triangulation_ds & tds()
+ {
+ return tds_;
+ }
+
+ const Geom_traits & geom_traits() const
+ {
+ return kernel_;
+ }
+
+ int maximal_dimension() const { return tds().maximal_dimension(); }
+ int current_dimension() const { return tds().current_dimension(); }
+
+ bool empty() const
+ {
+ return current_dimension() == -1;
+ }
+
+ size_type number_of_vertices() const
+ {
+ return tds().number_of_vertices() - 1;
+ }
+
+ size_type number_of_full_cells() const
+ {
+ return tds().number_of_full_cells();
+ }
+
+ Vertex_handle infinite_vertex() const
+ {
+ return infinity_;
+ }
+
+ Full_cell_handle infinite_full_cell() const
+ {
+ CGAL_assertion(infinite_vertex()->full_cell()->has_vertex(infinite_vertex()));
+ return infinite_vertex()->full_cell();
+ }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - NON CONSTANT-TIME ACCESS FUNCTIONS
+
+ size_type number_of_finite_full_cells() const
+ {
+ Full_cell_const_iterator s = full_cells_begin();
+ size_type result = number_of_full_cells();
+ for( ; s != full_cells_end(); ++s )
+ {
+ if( is_infinite(s) )
+ --result;
+ }
+ return result;
+ }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TRAVERSAL
+
+ Vertex_iterator vertices_begin() { return tds().vertices_begin(); }
+ Vertex_iterator vertices_end() { return tds().vertices_end(); }
+
+ Vertex_const_iterator vertices_begin() const { return tds().vertices_begin(); }
+ Vertex_const_iterator vertices_end() const { return tds().vertices_end(); }
+
+ Finite_vertex_iterator finite_vertices_begin()
+ { return Finite_vertex_iterator(Finiteness_predicate(*this), vertices_begin(), vertices_end()); }
+ Finite_vertex_iterator finite_vertices_end()
+ { return Finite_vertex_iterator(Finiteness_predicate(*this), vertices_end(), vertices_end()); }
+ Finite_vertex_const_iterator finite_vertices_begin() const
+ { return Finite_vertex_const_iterator(Finiteness_predicate(*this), vertices_begin(), vertices_end()); }
+ Finite_vertex_const_iterator finite_vertices_end() const
+ { return Finite_vertex_const_iterator(Finiteness_predicate(*this), vertices_end(), vertices_end()); }
+
+ Full_cell_iterator full_cells_begin() { return tds().full_cells_begin(); }
+ Full_cell_iterator full_cells_end() { return tds().full_cells_end(); }
+
+ Full_cell_const_iterator full_cells_begin() const { return tds().full_cells_begin(); }
+ Full_cell_const_iterator full_cells_end() const { return tds().full_cells_end(); }
+
+ Finite_full_cell_iterator finite_full_cells_begin()
+ { return Finite_full_cell_iterator(Finiteness_predicate(*this), full_cells_begin(), full_cells_end()); }
+ Finite_full_cell_iterator finite_full_cells_end()
+ { return Finite_full_cell_iterator(Finiteness_predicate(*this), full_cells_end(), full_cells_end()); }
+ Finite_full_cell_const_iterator finite_full_cells_begin() const
+ { return Finite_full_cell_const_iterator(Finiteness_predicate(*this), full_cells_begin(), full_cells_end()); }
+ Finite_full_cell_const_iterator finite_full_cells_end() const
+ { return Finite_full_cell_const_iterator(Finiteness_predicate(*this), full_cells_end(), full_cells_end()); }
+
+ Facet_iterator facets_begin() { return tds().facets_begin(); }
+ Facet_iterator facets_end() { return tds().facets_end(); }
+ Facet_iterator finite_facets_begin()
+ { return Finite_facet_iterator(Finiteness_predicate(*this), facets_begin(), facets_end()); }
+ Facet_iterator finite_facets_end()
+ { return Finite_facet_iterator(Finiteness_predicate(*this), facets_end(), facets_end()); }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SOME PREDICATE FUNCTORS
+
+ class Finiteness_predicate
+ {
+ const Self & t_;
+ public:
+ Finiteness_predicate(const Self & t) : t_(t) {}
+ template < class T >
+ bool operator()(const T & t) const
+ {
+ return ! t_.is_infinite(t);
+ }
+ };
+
+ class Point_equality_predicate
+ {
+ const Point & o_;
+ public:
+ Point_equality_predicate(const Point & o) : o_(o) {}
+ bool operator()(const Point & o) const { return (o == o_ );}
+ };
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SIMPLE QUERIES
+/*
+ bool is_vertex(const Point & p, Vertex_handle & v, Full_cell_handle hint = Full_cell_handle()) const
+ {
+ Locate_type lt;
+ Face f(maximal_dimension());
+ Facet ft;
+ Full_cell_handle s = locate(p, lt, f, ft, hint);
+ if( ON_VERTEX == lt )
+ {
+ v = s->vertex(f.index(0));
+ return true;
+ }
+ return false;
+ }
+
+ bool is_vertex(Vertex_const_handle v) const
+ {
+ return tds().is_vertex(v);
+ }
+
+ bool is_full_cell(Full_cell_const_handle s) const
+ {
+ return tds().is_full_cell(s);
+ }
+*/
+
+ bool is_infinite(Vertex_const_handle v) const
+ {
+ CGAL_precondition(Vertex_const_handle() != v);
+ return (infinite_vertex() == v);
+ }
+
+ bool is_infinite(const Vertex & v) const /* internal use, not documented */
+ {
+ return (&(*infinite_vertex()) == &v);
+ }
+
+ bool is_infinite(Full_cell_const_handle s) const
+ {
+ CGAL_precondition(Full_cell_const_handle() != s);
+ return is_infinite(*s);
+ }
+ bool is_infinite(const Full_cell & s) const /* internal use, not documented */
+ {
+ for(int i = 0; i <= current_dimension(); ++i)
+ if( is_infinite(s.vertex(i)) )
+ return true;
+ return false;
+ }
+ bool is_infinite(const Facet & ft) const
+ {
+ Full_cell_const_handle s = full_cell(ft);
+ CGAL_precondition(s != Full_cell_const_handle());
+ if( is_infinite(s) )
+ return (s->vertex(index_of_covertex(ft)) != infinite_vertex());
+ return false;
+ }
+
+ bool is_infinite(const Face & f) const
+ {
+ Full_cell_const_handle s = f.full_cell();
+ CGAL_precondition(s != Full_cell_const_handle());
+ if( is_infinite(s) )
+ {
+ Vertex_handle v;
+ for( int i(0); i<= f.face_dimension(); ++i)
+ if ( is_infinite( f.vertex(i) )) return true;
+ }
+ return false;
+ }
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ELEMENT GATHERING
+
+
+ template< typename OutputIterator >
+ OutputIterator incident_full_cells(const Face & f, OutputIterator out) const
+ {
+ return tds().incident_full_cells(f, out);
+ }
+ template< typename OutputIterator >
+ OutputIterator incident_full_cells(Vertex_const_handle v, OutputIterator out) const
+ {
+ return tds().incident_full_cells(v, out);
+ }
+ template< typename OutputIterator >
+ OutputIterator star(const Face & f, OutputIterator out) const
+ {
+ return tds().star(f, out);
+ }
+
+ template< typename OutputIterator >
+ OutputIterator incident_faces(Vertex_const_handle v, int d, OutputIterator out) const
+ {
+ return tds().incident_faces(v, d, out);
+ }
+ /*
+ template< typename OutputIterator, class Comparator >
+ OutputIterator incident_upper_faces( Vertex_const_handle v, int d,
+ OutputIterator out, Comparator cmp = Comparator())
+ {
+ return tds().incident_upper_faces(v, d, out, cmp);
+ }
+ template< typename OutputIterator >
+ OutputIterator incident_upper_faces( Vertex_const_handle v, int d,
+ OutputIterator out)
+ { // FIXME: uncomment this function, since it uses a comparator specific to
+ // *geometric* triangulation (taking infinite vertex into account)
+ internal::Triangulation::Compare_vertices_for_upper_face<Self> cmp(*this);
+ return tds().incident_upper_faces(v, d, out, cmp);
+ }
+ */
+ Orientation orientation(Full_cell_const_handle s, bool in_is_valid = false) const
+ {
+ if( ! in_is_valid )
+ CGAL_assertion( ! is_infinite(s) );
+ if( 0 == current_dimension() )
+ return POSITIVE;
+ if( current_dimension() == maximal_dimension() )
+ {
+ Orientation_d ori = geom_traits().orientation_d_object();
+ return ori(points_begin(s), points_begin(s) + 1 + current_dimension());
+ }
+ else
+ {
+ return coaffine_orientation_predicate()(points_begin(s), points_begin(s) + 1 + current_dimension());
+ }
+ }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UPDATE OPERATIONS
+
+ void clear()
+ {
+ tds_.clear();
+ infinity_ = tds().insert_increase_dimension();
+ // A full_cell has at most 1 + maximal_dimension() facets:
+ orientations_.resize(1 + maximal_dimension());
+ // Our coaffine orientation predicates HAS state member variables
+ reset_flat_orientation();
+#ifdef CGAL_TRIANGULATION_STATISTICS
+ walk_size_ = 0;
+#endif
+ }
+
+ void set_current_dimension(int d)
+ {
+ tds().set_current_dimension(d);
+ }
+
+ Full_cell_handle new_full_cell()
+ {
+ return tds().new_full_cell();
+ }
+
+ Vertex_handle new_vertex()
+ {
+ return tds().new_vertex();
+ }
+
+ Vertex_handle new_vertex(const Point & p)
+ {
+ return tds().new_vertex(p);
+ }
+
+ void set_neighbors(Full_cell_handle s, int i, Full_cell_handle s1, int j)
+ {
+ tds().set_neighbors(s, i, s1, j);
+ }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
+
+ bool is_valid(bool = false, int = 0) const;
+ bool are_incident_full_cells_valid(Vertex_const_handle, bool = false, int = 0) const;
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - POINT LOCATION
+
+protected:
+ template< typename OrientationPredicate >
+ Full_cell_handle do_locate(const Point &, Locate_type &, Face &, Facet &,
+ Full_cell_handle start,
+ const OrientationPredicate & o) const;
+public:
+ Full_cell_handle locate(const Point &, Locate_type &, Face &, Facet &,
+ Full_cell_handle start = Full_cell_handle()) const;
+ Full_cell_handle locate(const Point &, Locate_type &, Face &, Facet &,
+ Vertex_handle) const;
+ Full_cell_handle locate(const Point & p, Full_cell_handle s = Full_cell_handle()) const;
+ Full_cell_handle locate(const Point & p, Vertex_handle v) const;
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
+
+ Vertex_handle contract_face(const Point &, const Face &);
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - POINT INSERTION
+
+ template< typename ForwardIterator >
+ size_type insert(ForwardIterator start, ForwardIterator end)
+ {
+ size_type n = number_of_vertices();
+ std::vector<Point> points(start, end);
+ spatial_sort(points.begin(), points.end(), geom_traits());
+ Full_cell_handle hint = Full_cell_handle();
+ typename std::vector<Point>::const_iterator s = points.begin();
+ while( s != points.end() )
+ {
+ hint = insert(*s++, hint)->full_cell();
+ }
+ return number_of_vertices() - n;
+ }
+ Vertex_handle insert(const Point &, Locate_type, const Face &, const Facet &, Full_cell_handle);
+ Vertex_handle insert(const Point &, Full_cell_handle start = Full_cell_handle());
+ Vertex_handle insert(const Point &, Vertex_handle);
+ template< typename ForwardIterator >
+ Vertex_handle insert_in_hole(const Point & p, ForwardIterator start, ForwardIterator end, const Facet & ft)
+ {
+ Emptyset_iterator out;
+ return insert_in_hole(p, start, end, ft, out);
+ }
+ template< typename ForwardIterator, typename OutputIterator >
+ Vertex_handle insert_in_hole(const Point & p, ForwardIterator start, ForwardIterator end, const Facet & ft,
+ OutputIterator out)
+ {
+ Vertex_handle v = tds().insert_in_hole(start, end, ft, out);
+ v->set_point(p);
+ return v;
+ }
+ Vertex_handle insert_in_face(const Point &, const Face &);
+ Vertex_handle insert_in_facet(const Point &, const Facet &);
+ Vertex_handle insert_in_full_cell(const Point &, Full_cell_handle);
+ Vertex_handle insert_outside_convex_hull_1(const Point &, Full_cell_handle);
+ Vertex_handle insert_outside_convex_hull(const Point &, Full_cell_handle);
+ Vertex_handle insert_outside_affine_hull(const Point &);
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - FACET-TRAVERSAL PREDICATES
+
+ template< typename OrientationPredicate >
+ class Outside_convex_hull_traversal_predicate
+ {
+ Triangulation & t_;
+ const Point & p_;
+ OrientationPredicate const& ori_;
+ int cur_dim_;
+ public:
+ Outside_convex_hull_traversal_predicate(Triangulation & t, const Point & p,
+ OrientationPredicate const& ori)
+ : t_(t), p_(p), ori_(ori), cur_dim_(t.current_dimension()) {}
+ // FUTURE change parameter to const reference
+ bool operator()(Facet f) const
+ {
+ Full_cell_handle s = t_.full_cell(f);
+ const int i = t_.index_of_covertex(f);
+ Full_cell_handle n = s->neighbor(i);
+ if( ! t_.is_infinite(n) )
+ return false;
+ int inf_v_index = n->index(t_.infinite_vertex());
+ n->vertex(inf_v_index)->set_point(p_);
+ bool ok = (POSITIVE == ori_(t_.points_begin(n), t_.points_begin(n) + cur_dim_ + 1));
+ return ok;
+ }
+ };
+
+ // make sure all full_cells have positive orientation
+ void reorient_full_cells();
+
+protected:
+ // This is used in the |remove(v)| member function to manage sets of Full_cell_handles
+ template< typename FCH >
+ struct Full_cell_set : public std::vector<FCH>
+ {
+ typedef std::vector<FCH> Base_set;
+ using Base_set::begin;
+ using Base_set::end;
+ void make_searchable()
+ { // sort the full cell handles
+ std::sort(begin(), end());
+ }
+ bool contains(const FCH & fch) const
+ {
+ return std::binary_search(begin(), end(), fch);
+ }
+ bool contains_1st_and_not_2nd(const FCH & fst, const FCH & snd) const
+ {
+ return ( ! contains(snd) ) && ( contains(fst) );
+ }
+ };
+
+ void display_all_full_cells__debugging() const
+ {
+ std::cerr << "ALL FULL CELLS:" << std::endl;
+ for (Full_cell_const_iterator cit = full_cells_begin() ;
+ cit != full_cells_end() ; ++cit )
+ {
+ std::cerr << std::hex << &*cit << ": ";
+ for (int jj = 0 ; jj <= current_dimension() ; ++jj)
+ std::cerr << (is_infinite(cit->vertex(jj)) ? 0xFFFFFFFF : (unsigned int)&*cit->vertex(jj)) << " - ";
+ std::cerr << std::dec << std::endl;
+ }
+ std::cerr << std::endl;
+ }
+
+
+}; // Triangulation<...>
+
+// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+
+// CLASS MEMBER FUNCTIONS
+
+template < class TT, class TDS >
+void
+Triangulation<TT, TDS>
+::reorient_full_cells()
+{
+ if( current_dimension() < 1 )
+ return;
+
+ Full_cell_iterator sit = full_cells_begin();
+ Full_cell_iterator send = full_cells_end();
+ for ( ; sit != send ; ++sit)
+ {
+ if( ! (is_infinite(sit) && (1 == current_dimension())) )
+ {
+ sit->swap_vertices(current_dimension() - 1, current_dimension());
+ }
+ }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// - - - - - - - - - - - - - - - - - - - - - - - - THE REMOVAL METHODS
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Vertex_handle
+Triangulation<TT, TDS>
+::contract_face(const Point & p, const Face & f)
+{
+ CGAL_precondition( ! is_infinite(f) );
+ Vertex_handle v = tds().contract_face(f);
+ v->set_point(p);
+ CGAL_expensive_postcondition_msg(are_incident_full_cells_valid(v), "new point is not where it should be");
+ return v;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// - - - - - - - - - - - - - - - - - - - - - - - - THE INSERTION METHODS
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Vertex_handle
+Triangulation<TT, TDS>
+::insert(const Point & p, Locate_type lt, const Face & f, const Facet & ft, Full_cell_handle s)
+{
+ switch( lt )
+ {
+ case IN_FULL_CELL:
+ return insert_in_full_cell(p, s);
+ break;
+ case OUTSIDE_CONVEX_HULL:
+ return insert_outside_convex_hull(p, s);
+ break;
+ case OUTSIDE_AFFINE_HULL:
+ return insert_outside_affine_hull(p);
+ break;
+ case IN_FACET:
+ {
+ return insert_in_facet(p, ft);
+ break;
+ }
+ case IN_FACE:
+ return insert_in_face(p, f);
+ break;
+ case ON_VERTEX:
+ s->vertex(f.index(0))->set_point(p);
+ return s->vertex(f.index(0));
+ break;
+ }
+ CGAL_assertion(false);
+ return Vertex_handle();
+}
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Vertex_handle
+Triangulation<TT, TDS>
+::insert(const Point & p, Full_cell_handle start)
+{
+ Locate_type lt;
+ Face f(maximal_dimension());
+ Facet ft;
+ Full_cell_handle s = locate(p, lt, f, ft, start);
+ return insert(p, lt, f, ft, s);
+}
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Vertex_handle
+Triangulation<TT, TDS>
+::insert(const Point & p, Vertex_handle v)
+{
+ if( Vertex_handle() == v )
+ v = infinite_vertex();
+ return insert(p, v->full_cell());
+}
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Vertex_handle
+Triangulation<TT, TDS>
+::insert_in_face(const Point & p, const Face & f)
+{
+ CGAL_precondition( ! is_infinite(f) );
+ Vertex_handle v = tds().insert_in_face(f);
+ v->set_point(p);
+ return v;
+}
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Vertex_handle
+Triangulation<TT, TDS>
+::insert_in_facet(const Point & p, const Facet & ft)
+{
+ CGAL_precondition( ! is_infinite(ft) );
+ Vertex_handle v = tds().insert_in_facet(ft);
+ v->set_point(p);
+ return v;
+}
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Vertex_handle
+Triangulation<TT, TDS>
+::insert_in_full_cell(const Point & p, Full_cell_handle s)
+{
+ CGAL_precondition( ! is_infinite(s) );
+ Vertex_handle v = tds().insert_in_full_cell(s);
+ v->set_point(p);
+ return v;
+}
+
+// NOT DOCUMENTED...
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Vertex_handle
+Triangulation<TT, TDS>
+::insert_outside_convex_hull_1(const Point & p, Full_cell_handle s)
+{
+ // This is a special case for dimension 1, because in that case, the right
+ // infinite full_cell is not correctly oriented... (sice its first vertex is the
+ // infinite one...
+ CGAL_precondition( is_infinite(s) );
+ CGAL_precondition( 1 == current_dimension() );
+ Vertex_handle v = tds().insert_in_full_cell(s);
+ v->set_point(p);
+ return v;
+}
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Vertex_handle
+Triangulation<TT, TDS>
+::insert_outside_convex_hull(const Point & p, Full_cell_handle s)
+{
+ if( 1 == current_dimension() )
+ {
+ return insert_outside_convex_hull_1(p, s);
+ }
+ CGAL_precondition( is_infinite(s) );
+ CGAL_assertion( current_dimension() >= 2 );
+ std::vector<Full_cell_handle> simps;
+ simps.reserve(64);
+ std::back_insert_iterator<std::vector<Full_cell_handle> > out(simps);
+ if( current_dimension() < maximal_dimension() )
+ {
+ Coaffine_orientation_d ori = coaffine_orientation_predicate();
+ Outside_convex_hull_traversal_predicate<Coaffine_orientation_d>
+ ochtp(*this, p, ori);
+ tds().gather_full_cells(s, ochtp, out);
+ }
+ else
+ {
+ Orientation_d ori = geom_traits().orientation_d_object();
+ Outside_convex_hull_traversal_predicate<Orientation_d>
+ ochtp(*this, p, ori);
+ tds().gather_full_cells(s, ochtp, out);
+ }
+ int inf_v_index = s->index(infinite_vertex());
+ Vertex_handle v = insert_in_hole(
+ p, simps.begin(), simps.end(), Facet(s, inf_v_index));
+ return v;
+}
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Vertex_handle
+Triangulation<TT, TDS>
+::insert_outside_affine_hull(const Point & p)
+{
+ CGAL_precondition( current_dimension() < maximal_dimension() );
+ Vertex_handle v = tds().insert_increase_dimension(infinite_vertex());
+ // reset the orientation predicate:
+ reset_flat_orientation();
+ v->set_point(p);
+ if( current_dimension() >= 1 )
+ {
+ Full_cell_handle inf_v_cell = infinite_vertex()->full_cell();
+ int inf_v_index = inf_v_cell->index(infinite_vertex());
+ Full_cell_handle s = inf_v_cell->neighbor(inf_v_index);
+ Orientation o = orientation(s);
+ CGAL_assertion( COPLANAR != o );
+ if( NEGATIVE == o )
+ reorient_full_cells();
+
+
+ // We just inserted the second finite point and the right infinite
+ // cell is like : (inf_v, v), but we want it to be (v, inf_v) to be
+ // consistent with the rest of the cells
+ if (current_dimension() == 1)
+ {
+ // Is "inf_v_cell" the right infinite cell?
+ // Then inf_v_index should be 1
+ if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
+ && inf_v_index == 0)
+ {
+ inf_v_cell->swap_vertices(
+ current_dimension() - 1, current_dimension());
+ }
+ // Otherwise, let's find the right infinite cell
+ else
+ {
+ inf_v_cell = inf_v_cell->neighbor((inf_v_index + 1) % 2);
+ inf_v_index = inf_v_cell->index(infinite_vertex());
+ // Is "inf_v_cell" the right infinite cell?
+ // Then inf_v_index should be 1
+ if (inf_v_cell->neighbor(inf_v_index)->index(inf_v_cell) == 0
+ && inf_v_index == 0)
+ {
+ inf_v_cell->swap_vertices(
+ current_dimension() - 1, current_dimension());
+ }
+ }
+ }
+ }
+ return v;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// - - - - - - - - - - - - - - - - - - - - THE MAIN LOCATE(...) FUNCTION
+
+template < class TT, class TDS >
+template< typename OrientationPredicate >
+typename Triangulation<TT, TDS>::Full_cell_handle
+Triangulation<TT, TDS>
+::do_locate(const Point & p, // query point
+ Locate_type & loc_type,// type of result (full_cell, face, vertex)
+ Face & face,// the face containing the query in its interior (when appropriate)
+ Facet & facet,// the facet containing the query in its interior (when appropriate)
+ Full_cell_handle start, // starting full_cell for the walk
+ OrientationPredicate const& orientation_pred
+ ) const
+{
+ const int cur_dim = current_dimension();
+
+ if( cur_dim == -1 )
+ {
+ loc_type = OUTSIDE_AFFINE_HULL;
+ return Full_cell_handle();
+ }
+ else if( cur_dim == 0 )
+ {
+ Vertex_handle vit = infinite_full_cell()->neighbor(0)->vertex(0);
+ if( EQUAL != geom_traits().compare_lexicographically_d_object()(p, vit->point()) )
+ {
+ loc_type = OUTSIDE_AFFINE_HULL;
+ return Full_cell_handle();
+ }
+ else
+ {
+ loc_type = ON_VERTEX;
+ face.set_full_cell(vit->full_cell());
+ face.set_index(0, 0);
+ return vit->full_cell();
+ }
+ }
+
+ Full_cell_handle s;
+
+ // if we don't know where to start, we start from any bounded full_cell
+ if( Full_cell_handle() == start )
+ {
+ // THE HACK THAT NOBODY SHOULD DO... BUT DIFFICULT TO WORK AROUND
+ // THIS... TODO: WORK AROUND IT
+ Full_cell_handle inf_c = const_cast<Self*>(this)->infinite_full_cell();
+ int inf_v_index = inf_c->index(infinite_vertex());
+ s = inf_c->neighbor(inf_v_index);
+ }
+ else
+ {
+ s = start;
+ if( is_infinite(s) )
+ {
+ int inf_v_index = s->index(infinite_vertex());
+ s = s->neighbor(inf_v_index);
+ }
+ }
+
+ // Check if query |p| is outside the affine hull
+ if( cur_dim < maximal_dimension() )
+ {
+ if( ! geom_traits().contained_in_affine_hull_d_object()(
+ points_begin(s),
+ points_begin(s) + current_dimension() + 1,
+ p) )
+ {
+ loc_type = OUTSIDE_AFFINE_HULL;
+ return Full_cell_handle();
+ }
+ }
+
+ // we remember the |previous|ly visited full_cell to avoid the evaluation
+ // of one |orientation| predicate
+ Full_cell_handle previous = Full_cell_handle();
+ bool full_cell_not_found = true;
+ while(full_cell_not_found) // we walk until we locate the query point |p|
+ {
+ #ifdef CGAL_TRIANGULATION_STATISTICS
+ ++walk_size_;
+ #endif
+ // For the remembering stochastic walk, we need to start trying
+ // with a random index:
+ int j, i = rng_.get_int(0, cur_dim);
+ // we check |p| against all the full_cell's hyperplanes in turn
+
+ for(j = 0; j <= cur_dim; ++j, i = (i + 1) % (cur_dim + 1) )
+ {
+ Full_cell_handle next = s->neighbor(i);
+ if( previous == next )
+ { // no need to compute the orientation, we already know it
+ orientations_[i] = POSITIVE;
+ continue; // go to next full_cell's facet
+ }
+
+ Substitute_point_in_vertex_iterator<
+ typename Full_cell::Vertex_handle_const_iterator>
+ spivi(s->vertex(i), &p);
+
+ orientations_[i] = orientation_pred(
+ boost::make_transform_iterator(s->vertices_begin(), spivi),
+ boost::make_transform_iterator(s->vertices_begin() + cur_dim + 1,
+ spivi));
+
+ if( orientations_[i] != NEGATIVE )
+ {
+ // from this facet's point of view, we are inside the
+ // full_cell or on its boundary, so we continue to next facet
+ continue;
+ }
+
+ // At this point, we know that we have to jump to the |next|
+ // full_cell because orientation_[i] == NEGATIVE
+ previous = s;
+ s = next;
+ if( is_infinite(next) )
+ { // we have arrived OUTSIDE the convex hull of the triangulation,
+ // so we stop the search
+ full_cell_not_found = false;
+ loc_type = OUTSIDE_CONVEX_HULL;
+ face.set_full_cell(s);
+ }
+ break;
+ } // end of the 'for' loop
+ if( ( cur_dim + 1 ) == j ) // we found the full_cell containing |p|
+ full_cell_not_found = false;
+ }
+ // Here, we know in which full_cell |p| is in.
+ // We now check more precisely where |p| landed:
+ // vertex, facet, face or full_cell.
+ if( ! is_infinite(s) )
+ {
+ face.set_full_cell(s);
+ int num(0);
+ int verts(0);
+ for(int i = 0; i < cur_dim; ++i)
+ {
+ if( orientations_[i] == COPLANAR )
+ {
+ ++num;
+ facet = Facet(s, i);
+ }
+ else
+ face.set_index(verts++, i);
+ }
+ //-- We could put the if{}else{} below in the loop above, but then we would
+ // need to test if (verts < cur_dim) many times... we do it only once
+ // here:
+ if( orientations_[cur_dim] == COPLANAR )
+ {
+ ++num;
+ facet = Facet(s, cur_dim);
+ }
+ else if( verts < cur_dim )
+ face.set_index(verts, cur_dim);
+ //-- end of remark above //
+ if( 0 == num )
+ {
+ loc_type = IN_FULL_CELL;
+ face.clear();
+ }
+ else if( cur_dim == num )
+ loc_type = ON_VERTEX;
+ else if( 1 == num )
+ loc_type = IN_FACET;
+ else
+ loc_type = IN_FACE;
+ }
+ return s;
+}
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Full_cell_handle
+Triangulation<TT, TDS>
+::locate( const Point & p, // query point
+ Locate_type & loc_type,// type of result (full_cell, face, vertex)
+ Face & face,// the face containing the query in its interior (when appropriate)
+ Facet & facet,// the facet containing the query in its interior (when appropriate)
+ Full_cell_handle start// starting full_cell for the walk
+ ) const
+{
+ if( current_dimension() == maximal_dimension() )
+ {
+ Orientation_d ori = geom_traits().orientation_d_object();
+ return do_locate(p, loc_type, face, facet, start, ori);
+ }
+ else
+ return do_locate(p, loc_type, face, facet, start, coaffine_orientation_predicate());
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// - - - - - - - - - - - - - - - - - - - - the locate(...) variants
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Full_cell_handle
+Triangulation<TT, TDS>
+::locate( const Point & p,
+ Locate_type & loc_type,
+ Face & face,
+ Facet & facet,
+ Vertex_handle start) const
+{
+ if( Vertex_handle() == start )
+ start = infinite_vertex();
+ return locate(p, loc_type, face, facet, start->full_cell());
+}
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Full_cell_handle
+Triangulation<TT, TDS>
+::locate(const Point & p, Full_cell_handle s) const
+{
+ Locate_type lt;
+ Face face(maximal_dimension());
+ Facet facet;
+ return locate(p, lt, face, facet, s);
+}
+
+template < class TT, class TDS >
+typename Triangulation<TT, TDS>::Full_cell_handle
+Triangulation<TT, TDS>
+::locate(const Point & p, Vertex_handle v) const
+{
+ if( Vertex_handle() != v )
+ v = infinite_vertex();
+ return this->locate(p, v->full_cell());
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY
+
+template < class TT, class TDS >
+bool
+Triangulation<TT, TDS>
+::is_valid(bool verbose, int level) const
+{
+ if( ! tds().is_valid(verbose, level) )
+ return false;
+
+ Full_cell_const_iterator c;
+ if( current_dimension() < 0 )
+ return true;
+ Orientation o;
+ for( c = full_cells_begin(); c != full_cells_end(); ++c )
+ {
+ if( is_infinite(c) )
+ {
+ if( current_dimension() > 1 )
+ {
+ int i = c->index( infinite_vertex() );
+ Full_cell_handle n = c->neighbor(i);
+ infinite_vertex()->set_point(n->vertex(c->mirror_index(i))->point());
+ o = - orientation(c, true);
+ }
+ else
+ o = POSITIVE;
+ }
+ else
+ o = orientation(c, true);
+ if( NEGATIVE == o )
+ {
+ if( verbose ) CGAL_warning_msg(false, "full_cell is not correctly oriented");
+ return false;
+ }
+ if( COPLANAR == o )
+ {
+ if( verbose ) CGAL_warning_msg(false, "full_cell is flat");
+ return false;
+ }
+ }
+ return true;
+}
+
+template < class TT, class TDS >
+bool Triangulation<TT, TDS>::are_incident_full_cells_valid(Vertex_const_handle v, bool verbose, int) const
+{
+ if( current_dimension() <= 0 )
+ return true;
+ typedef std::vector<Full_cell_const_handle> Simps;
+ Simps simps;
+ simps.reserve(64);
+ std::back_insert_iterator<Simps> out(simps);
+ incident_full_cells(v, out);
+ typename Simps::const_iterator sit = simps.begin();
+ for( ; sit != simps.end(); ++sit )
+ {
+ if( is_infinite(*sit) )
+ continue;
+ Orientation o = orientation(*sit);
+ if( NEGATIVE == o )
+ {
+ if( verbose ) CGAL_warning_msg(false, "full_cell is not correctly oriented");
+ return false;
+ }
+ if( COPLANAR == o )
+ {
+ if( verbose ) CGAL_warning_msg(false, "full_cell is flat");
+ return false;
+ }
+ }
+ return true;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+// FUNCTIONS THAT ARE NOT MEMBER FUNCTIONS:
+
+template < class TT, class TDS >
+std::istream &
+operator>>(std::istream & is, Triangulation<TT, TDS> & tr)
+ // reads :
+ // - the dimensions (maximal and current)
+ // - the number of finite vertices
+ // - the non combinatorial information on vertices (point, etc)
+ // - the number of full_cells
+ // - the full_cells by the indices of their vertices in the preceding list
+ // of vertices, plus the non combinatorial information on each full_cell
+ // - the neighbors of each full_cell by their index in the preceding list
+{
+ typedef Triangulation<TT, TDS> T;
+ typedef typename T::Vertex_handle Vertex_handle;
+
+ // read current dimension and number of vertices
+ size_t n;
+ int cd;
+ if( is_ascii(is) )
+ is >> cd >> n;
+ else
+ {
+ read(is, cd);
+ read(is, n, io_Read_write());
+ }
+
+ CGAL_assertion_msg( cd <= tr.maximal_dimension(), "input Triangulation has too high dimension");
+
+ tr.clear();
+ tr.set_current_dimension(cd);
+
+ if( n == 0 )
+ return is;
+
+ std::vector<Vertex_handle> vertices;
+ vertices.resize(n+1);
+ vertices[0] = tr.infinite_vertex();
+ is >> (*vertices[0]);
+
+ // read the vertices:
+ size_t i(1);
+ while( i <= n )
+ {
+ vertices[i] = tr.new_vertex();
+ is >> (*vertices[i]); // read a vertex
+ ++i;
+ }
+
+ // now, read the combinatorial information
+ return tr.tds().read_full_cells(is, vertices);
+}
+
+template < class TT, class TDS >
+std::ostream &
+operator<<(std::ostream & os, const Triangulation<TT, TDS> & tr)
+ // writes :
+ // - the dimensions (maximal and current)
+ // - the number of finite vertices
+ // - the non combinatorial information on vertices (point, etc)
+ // - the number of full_cells
+ // - the full_cells by the indices of their vertices in the preceding list
+ // of vertices, plus the non combinatorial information on each full_cell
+ // - the neighbors of each full_cell by their index in the preceding list
+{
+ typedef Triangulation<TT, TDS> T;
+ typedef typename T::Vertex_const_handle Vertex_handle;
+ typedef typename T::Vertex_const_iterator Vertex_iterator;
+
+ // outputs dimensions and number of vertices
+ size_t n = tr.number_of_vertices();
+ if( is_ascii(os) )
+ os << tr.current_dimension() << std::endl << n << std::endl;
+ else
+ {
+ write(os, tr.current_dimension());
+ write(os, n, io_Read_write());
+ }
+
+ if( n == 0 )
+ return os;
+
+ size_t i(0);
+ // write the vertices
+ std::map<Vertex_handle, int> index_of_vertex;
+
+ // infinite vertex has index 0 (among all the vertices)
+ index_of_vertex[tr.infinite_vertex()] = i++;
+ os << *tr.infinite_vertex();
+ for( Vertex_iterator it = tr.vertices_begin(); it != tr.vertices_end(); ++it )
+ {
+ if( tr.is_infinite(it) )
+ continue;
+ os << *it; // write the vertex
+ index_of_vertex[it] = i++;
+ }
+ CGAL_assertion( i == n+1 );
+
+ // output the combinatorial information
+ return tr.tds().write_full_cells(os, index_of_vertex);
+}
+
+} //namespace CGAL
+
+#endif // CGAL_TRIANGULATION_H
diff --git a/include/gudhi_patches/CGAL/Triangulation_data_structure.h b/include/gudhi_patches/CGAL/Triangulation_data_structure.h
new file mode 100644
index 00000000..2493c712
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Triangulation_data_structure.h
@@ -0,0 +1,1603 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_TRIANGULATION_DATA_STRUCTURE_H
+#define CGAL_TRIANGULATION_DATA_STRUCTURE_H
+
+#include <CGAL/basic.h>
+#include <CGAL/Default.h>
+#include <CGAL/iterator.h>
+#include <CGAL/Compact_container.h>
+#include <CGAL/Triangulation_face.h>
+#include <CGAL/Triangulation_ds_vertex.h>
+#include <CGAL/Triangulation_ds_full_cell.h>
+#include <CGAL/internal/Combination_enumerator.h>
+#include <CGAL/internal/Triangulation/utilities.h>
+#include <CGAL/internal/Triangulation/Triangulation_ds_iterators.h>
+
+#include <algorithm>
+#include <vector>
+#include <queue>
+#include <set>
+
+namespace CGAL {
+
+template< class Dimen,
+ class Vb = Default,
+ class Fcb = Default >
+class Triangulation_data_structure
+{
+ typedef Triangulation_data_structure<Dimen, Vb, Fcb> Self;
+ typedef typename Default::Get<Vb, Triangulation_ds_vertex<> >::type V_base;
+ typedef typename Default::Get<Fcb, Triangulation_ds_full_cell<> >::type FC_base;
+
+public:
+ typedef typename V_base::template Rebind_TDS<Self>::Other Vertex; /* Concept */
+ typedef typename FC_base::template Rebind_TDS<Self>::Other Full_cell; /* Concept */
+
+ // Tools to change the Vertex and Cell types of the TDS.
+ template < typename Vb2 >
+ struct Rebind_vertex {
+ typedef Triangulation_data_structure<Dimen, Vb2, Fcb> Other;
+ };
+
+ template < typename Fcb2 >
+ struct Rebind_full_cell {
+ typedef Triangulation_data_structure<Dimen, Vb, Fcb2> Other;
+ };
+
+
+
+ // we want to store an object of this class in every Full_cell:
+ class Full_cell_data
+ {
+ unsigned char bits_;
+ public:
+ Full_cell_data() : bits_(0) {}
+ Full_cell_data(const Full_cell_data & fcd) : bits_(fcd.bits_) {}
+
+ void clear() { bits_ = 0; }
+ void mark_visited() { bits_ = 1; }
+ void clear_visited() { bits_ = 0; }
+
+ bool is_clear() const { return bits_ == 0; }
+ bool is_visited() const { return bits_ == 1; }
+ // WARNING: if we use more bits and several bits can be set at once,
+ // then make sure to use bitwise operation above, instead of direct
+ // affectation.
+ };
+
+protected:
+ typedef Compact_container<Vertex> Vertex_container;
+ typedef Compact_container<Full_cell> Full_cell_container;
+
+public:
+ typedef Dimen Maximal_dimension;
+
+ typedef typename Vertex_container::size_type size_type; /* Concept */
+ typedef typename Vertex_container::difference_type difference_type; /* Concept */
+
+ typedef typename Vertex_container::iterator Vertex_handle; /* Concept */
+ typedef typename Vertex_container::iterator Vertex_iterator; /* Concept */
+ typedef typename Vertex_container::const_iterator Vertex_const_handle;
+ typedef typename Vertex_container::const_iterator Vertex_const_iterator;
+
+ typedef typename Full_cell_container::iterator Full_cell_handle; /* Concept */
+ typedef typename Full_cell_container::iterator Full_cell_iterator; /* Concept */
+ typedef typename Full_cell_container::const_iterator Full_cell_const_handle;
+ typedef typename Full_cell_container::const_iterator Full_cell_const_iterator;
+
+ typedef internal::Triangulation::
+ Triangulation_ds_facet_iterator<Self> Facet_iterator; /* Concept */
+
+ /* The 2 types defined below, |Facet| and |Rotor| are used when traversing
+ the boundary `B' of the union of a set of full cells. |Rotor| makes it
+ easy to rotate around itself, in the search of neighbors in `B' (see
+ |rotate_rotor| and |insert_in_tagged_hole|) */
+
+ // A co-dimension 1 sub-simplex.
+ class Facet /* Concept */
+ {
+ Full_cell_handle full_cell_;
+ int index_of_covertex_;
+ public:
+ Facet() : full_cell_(), index_of_covertex_(0) {}
+ Facet(Full_cell_handle f, int i) : full_cell_(f), index_of_covertex_(i) {}
+ Full_cell_handle full_cell() const { return full_cell_; }
+ int index_of_covertex() const { return index_of_covertex_; }
+ };
+
+ // A co-dimension 2 sub-simplex. called a Rotor because we can rotate
+ // the two "covertices" around the sub-simplex. Useful for traversing the
+ // boundary of a hole. NOT DOCUMENTED
+ class Rotor : public Facet
+ {
+ int index_of_second_covertex_;
+ public:
+ Rotor() : Facet(), index_of_second_covertex_(0) {}
+ Rotor(Full_cell_handle f, int first, int second) : Facet(f, first), index_of_second_covertex_(second) {}
+ int index_of_second_covertex() const { return index_of_second_covertex_; }
+ };
+
+ typedef Triangulation_face<Self> Face; /* Concept */
+
+protected: // DATA MEMBERS
+
+ int dmax_, dcur_; // dimension of the current triangulation
+ Vertex_container vertices_; // list of all vertices
+ Full_cell_container full_cells_; // list of all full cells
+
+private:
+
+ void clean_dynamic_memory()
+ {
+ vertices_.clear();
+ full_cells_.clear();
+ }
+
+ template < class Dim_tag >
+ struct get_maximal_dimension
+ {
+ static int value(int D) { return D; }
+ };
+ // specialization
+ template < int D >
+ struct get_maximal_dimension<Dimension_tag<D> >
+ {
+ static int value(int) { return D; }
+ };
+
+public:
+ Triangulation_data_structure( int dim=0) /* Concept */
+ : dmax_(get_maximal_dimension<Dimen>::value(dim)), dcur_(-2),
+ vertices_(), full_cells_()
+ {
+ CGAL_assertion_msg(dmax_ > 0, "maximal dimension must be positive.");
+ }
+
+ ~Triangulation_data_structure()
+ {
+ clean_dynamic_memory();
+ }
+
+ Triangulation_data_structure(const Triangulation_data_structure & tds)
+ : dmax_(tds.dmax_), dcur_(tds.dcur_),
+ vertices_(tds.vertices_), full_cells_(tds.full_cells_)
+ {
+ typedef std::map<Vertex_const_handle, Vertex_handle> V_map;
+ typedef std::map<Full_cell_const_handle, Full_cell_handle> C_map;
+ V_map vmap;
+ C_map cmap;
+ Vertex_const_iterator vfrom = tds.vertices_begin();
+ Vertex_iterator vto = vertices_begin();
+ Full_cell_const_iterator cfrom = tds.full_cells_begin();
+ Full_cell_iterator cto = full_cells_begin();
+ while( vfrom != tds.vertices_end() )
+ vmap[vfrom++] = vto++;
+ while( cfrom != tds.full_cells_end() )
+ cmap[cfrom++] = cto++;
+ cto = full_cells_begin();
+ while( cto != full_cells_end() )
+ {
+ for( int i = 0; i <= (std::max)(0, current_dimension()); ++i )
+ {
+ associate_vertex_with_full_cell(cto, i, vmap[cto->vertex(i)]);
+ cto->set_neighbor(i, cmap[cto->neighbor(i)]);
+ }
+ ++cto;
+ }
+ }
+
+ // QUERIES
+
+protected:
+
+ bool check_range(int i) const
+ {
+ if( current_dimension() < 0 )
+ {
+ return (0 == i);
+ }
+ return ( (0 <= i) && (i <= current_dimension()) );
+ }
+
+public:
+
+ /* returns the current dimension of the full cells in the triangulation. */
+ int maximal_dimension() const { return dmax_; } /* Concept */
+ int current_dimension() const { return dcur_; } /* Concept */
+
+ size_type number_of_vertices() const /* Concept */
+ {
+ return this->vertices_.size();
+ }
+ size_type number_of_full_cells() const /* Concept */
+ {
+ return this->full_cells_.size();
+ }
+
+ bool empty() const /* Concept */
+ {
+ return current_dimension() == -2;
+ }
+
+ Vertex_container & vertices() { return vertices_; }
+ const Vertex_container & vertices() const { return vertices_; }
+ Full_cell_container & full_cells() { return full_cells_; }
+ const Full_cell_container & full_cells() const { return full_cells_; }
+
+ Vertex_handle vertex(Full_cell_handle s, int i) const /* Concept */
+ {
+ CGAL_precondition(s != Full_cell_handle() && check_range(i));
+ return s->vertex(i);
+ }
+
+ Vertex_const_handle vertex(Full_cell_const_handle s, int i) const /* Concept */
+ {
+ CGAL_precondition(s != Full_cell_handle() && check_range(i));
+ return s->vertex(i);
+ }
+
+ bool is_vertex(Vertex_const_handle v) const /* Concept */
+ {
+ if( Vertex_const_handle() == v )
+ return false;
+ Vertex_const_iterator vit = vertices_begin();
+ while( vit != vertices_end() && ( v != vit ) )
+ ++vit;
+ return v == vit;
+ }
+
+ bool is_full_cell(Full_cell_const_handle s) const /* Concept */
+ {
+ if( Full_cell_const_handle() == s )
+ return false;
+ Full_cell_const_iterator sit = full_cells_begin();
+ while( sit != full_cells_end() && ( s != sit ) )
+ ++sit;
+ return s == sit;
+ }
+
+ Full_cell_handle full_cell(Vertex_handle v) const /* Concept */
+ {
+ CGAL_precondition(v != Vertex_handle());
+ return v->full_cell();
+ }
+
+ Full_cell_const_handle full_cell(Vertex_const_handle v) const /* Concept */
+ {
+ CGAL_precondition(Vertex_const_handle() != v);
+ return v->full_cell();
+ }
+
+ Full_cell_handle neighbor(Full_cell_handle s, int i) const /* Concept */
+ {
+ CGAL_precondition(Full_cell_handle() != s && check_range(i));
+ return s->neighbor(i);
+ }
+
+ Full_cell_const_handle neighbor(Full_cell_const_handle s, int i) const/* Concept */
+ {
+ CGAL_precondition(Full_cell_const_handle() != s && check_range(i));
+ return s->neighbor(i);
+ }
+
+ int mirror_index(Full_cell_handle s, int i) const /* Concept */
+ {
+ CGAL_precondition(Full_cell_handle() != s && check_range(i));
+ return s->mirror_index(i);
+ }
+
+ int mirror_index(Full_cell_const_handle s, int i) const
+ {
+ CGAL_precondition(Full_cell_const_handle() != s && check_range(i)); /* Concept */
+ return s->mirror_index(i);
+ }
+
+ int mirror_vertex(Full_cell_handle s, int i) const /* Concept */
+ {
+ CGAL_precondition(Full_cell_handle() != s && check_range(i));
+ return s->mirror_vertex(i);
+ }
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FACETS OPERATIONS
+
+ // works for Face_ = Facet and Face_ = Rotor.
+ // NOT DOCUMENTED for the Rotor case...
+ template< typename Face_ >
+ Full_cell_handle full_cell(const Face_ & f) const /* Concept */
+ {
+ return f.full_cell();
+ }
+
+ // works for Face_ = Facet and Face_ = Rotor.
+ // NOT DOCUMENTED for the Rotor case...
+ template< class Face_ >
+ int index_of_covertex(const Face_ & f) const /* Concept */
+ {
+ return f.index_of_covertex();
+ }
+
+ // NOT DOCUMENTED
+ // A Rotor has two covertices
+ int index_of_second_covertex(const Rotor & f) const
+ {
+ return f.index_of_second_covertex();
+ }
+
+ // works for Face_ = Facet and Face_ = Rotor.
+ // NOT DOCUMENTED...
+ template< class Face_ >
+ bool is_boundary_facet(const Face_ & f) const
+ {
+ if( get_visited(neighbor(full_cell(f), index_of_covertex(f))) )
+ return false;
+ if( ! get_visited(full_cell(f)) )
+ return false;
+ return true;
+ }
+
+ // NOT DOCUMENTED...
+ Rotor rotate_rotor(Rotor & f)
+ {
+ int opposite = mirror_index(full_cell(f), index_of_covertex(f));
+ Full_cell_handle s = neighbor(full_cell(f), index_of_covertex(f));
+ int new_second = s->index(vertex(full_cell(f), index_of_second_covertex(f)));
+ return Rotor(s, new_second, opposite);
+ }
+
+ // NICE UPDATE OPERATIONS
+
+protected:
+ void do_insert_increase_dimension(Vertex_handle, Vertex_handle);
+public:
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS
+
+ Vertex_handle collapse_face(const Face &); /* Concept */
+ void remove_decrease_dimension(Vertex_handle, Vertex_handle); /* Concept */
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSERTIONS
+
+ Vertex_handle insert_in_full_cell(Full_cell_handle); /* Concept */
+ Vertex_handle insert_in_face(const Face &); /* Concept */
+ Vertex_handle insert_in_facet(const Facet &); /* Concept */
+ template< typename Forward_iterator >
+ Vertex_handle insert_in_hole(Forward_iterator, Forward_iterator, Facet); /* Concept */
+ template< typename Forward_iterator, typename OutputIterator >
+ Vertex_handle insert_in_hole(Forward_iterator, Forward_iterator, Facet, OutputIterator); /* Concept */
+
+ template< typename OutputIterator >
+ Full_cell_handle insert_in_tagged_hole(Vertex_handle, Facet, OutputIterator);
+
+ Vertex_handle insert_increase_dimension(Vertex_handle=Vertex_handle()); /* Concept */
+
+private:
+
+ // Used by insert_in_tagged_hole
+ struct IITH_task
+ {
+ IITH_task(
+ Facet boundary_facet_,
+ int index_of_inside_cell_in_outside_cell_,
+ Full_cell_handle future_neighbor_ = Full_cell_handle(),
+ int new_cell_index_in_future_neighbor_ = -1,
+ int index_of_future_neighbor_in_new_cell_ = -1)
+ : boundary_facet(boundary_facet_),
+ index_of_inside_cell_in_outside_cell(index_of_inside_cell_in_outside_cell_),
+ future_neighbor(future_neighbor_),
+ new_cell_index_in_future_neighbor(new_cell_index_in_future_neighbor_),
+ index_of_future_neighbor_in_new_cell(index_of_future_neighbor_in_new_cell_)
+ {}
+
+ // "new_cell" is the cell about to be created
+ Facet boundary_facet;
+ int index_of_inside_cell_in_outside_cell;
+ Full_cell_handle future_neighbor;
+ int new_cell_index_in_future_neighbor;
+ int index_of_future_neighbor_in_new_cell;
+ };
+
+ // NOT DOCUMENTED
+ void clear_visited_marks(Full_cell_handle) const;
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DANGEROUS UPDATE OPERATIONS
+
+private:
+
+ // NOT DOCUMENTED
+ template< typename FCH > // FCH = Full_cell_[const_]handle
+ bool get_visited(FCH c) const
+ {
+ return c->tds_data().is_visited();
+ }
+
+ // NOT DOCUMENTED
+ template< typename FCH > // FCH = Full_cell_[const_]handle
+ void set_visited(FCH c, bool m) const
+ {
+ if( m )
+ c->tds_data().mark_visited();
+ else
+ c->tds_data().clear_visited();
+ }
+
+public:
+
+ void clear() /* Concept */
+ {
+ clean_dynamic_memory();
+ dcur_ = -2;
+ }
+
+ void set_current_dimension(int d) /* Concept */
+ {
+ CGAL_precondition(-2<=d && d<=maximal_dimension());
+ dcur_ = d;
+ }
+
+ Full_cell_handle new_full_cell(Full_cell_handle s)
+ {
+ return full_cells_.emplace(*s);
+ }
+
+ Full_cell_handle new_full_cell() /* Concept */
+ {
+ return full_cells_.emplace(dmax_);
+ }
+
+ void delete_full_cell(Full_cell_handle s) /* Concept */
+ {
+ CGAL_precondition(Full_cell_handle() != s);
+ // CGAL_expensive_precondition(is_full_cell(s));
+ full_cells_.erase(s);
+ }
+
+ template< typename Forward_iterator >
+ void delete_full_cells(Forward_iterator start, Forward_iterator end) /* Concept */
+ {
+ Forward_iterator s = start;
+ while( s != end )
+ full_cells_.erase(*s++);
+ }
+
+ template< class T >
+ Vertex_handle new_vertex( const T & t )
+ {
+ return vertices_.emplace(t);
+ }
+
+ Vertex_handle new_vertex() /* Concept */
+ {
+ return vertices_.emplace();
+ }
+
+ void delete_vertex(Vertex_handle v) /* Concept */
+ {
+ CGAL_precondition( Vertex_handle() != v );
+ vertices_.erase(v);
+ }
+
+ void associate_vertex_with_full_cell(Full_cell_handle s, int i, Vertex_handle v) /* Concept */
+ {
+ CGAL_precondition(check_range(i));
+ CGAL_precondition(s != Full_cell_handle());
+ CGAL_precondition(v != Vertex_handle());
+ s->set_vertex(i, v);
+ v->set_full_cell(s);
+ }
+
+ void set_neighbors(Full_cell_handle s, int i, Full_cell_handle s1, int j) /* Concept */
+ {
+ CGAL_precondition(check_range(i));
+ CGAL_precondition(check_range(j));
+ CGAL_precondition(s != Full_cell_handle());
+ CGAL_precondition(s1 != Full_cell_handle());
+ s->set_neighbor(i, s1);
+ s1->set_neighbor(j, s);
+ s->set_mirror_index(i, j);
+ s1->set_mirror_index(j, i);
+ }
+
+ // SANITY CHECKS
+
+ bool is_valid(bool = true, int = 0) const; /* Concept */
+
+ // NOT DOCUMENTED
+ template< class OutStream> void write_graph(OutStream &);
+
+ Vertex_iterator vertices_begin() { return vertices_.begin(); } /* Concept */
+ Vertex_iterator vertices_end() { return vertices_.end(); } /* Concept */
+ Full_cell_iterator full_cells_begin() { return full_cells_.begin(); } /* Concept */
+ Full_cell_iterator full_cells_end() { return full_cells_.end(); } /* Concept */
+
+ Vertex_const_iterator vertices_begin() const { return vertices_.begin(); } /* Concept */
+ Vertex_const_iterator vertices_end() const { return vertices_.end(); } /* Concept */
+ Full_cell_const_iterator full_cells_begin() const { return full_cells_.begin(); } /* Concept */
+ Full_cell_const_iterator full_cells_end() const { return full_cells_.end(); } /* Concept */
+
+ Facet_iterator facets_begin() /* Concept */
+ {
+ if( current_dimension() <= 0 )
+ return facets_end();
+ return Facet_iterator(*this);
+ }
+ Facet_iterator facets_end() /* Concept */
+ {
+ return Facet_iterator(*this, 0);
+ }
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - FULL CELL GATHERING
+
+ // a traversal predicate for gathering full_cells incident to a given face
+ // ``incident'' means that the given face is a subface of the full_cell
+ class Incident_full_cell_traversal_predicate
+ {
+ const Face & f_;
+ int dim_;
+ const Triangulation_data_structure & tds_;
+ public:
+ Incident_full_cell_traversal_predicate(const Triangulation_data_structure & tds,
+ const Face & f)
+ : f_(f), tds_(tds)
+ {
+ dim_ = f.face_dimension();
+ }
+ bool operator()(const Facet & facet) const
+ {
+ Vertex_handle v = tds_.full_cell(facet)->vertex(tds_.index_of_covertex(facet));
+ for( int i = 0; i <= dim_; ++i )
+ {
+ if( v == f_.vertex(i) )
+ return false;
+ }
+ return true;
+ }
+ };
+
+ // a traversal predicate for gathering full_cells having a given face as subface
+ class Star_traversal_predicate
+ {
+ const Face & f_;
+ int dim_;
+ const Triangulation_data_structure & tds_;
+ public:
+ Star_traversal_predicate(const Triangulation_data_structure & tds,
+ const Face & f)
+ : f_(f), tds_(tds)
+ {
+ dim_ = f.face_dimension();
+ }
+ bool operator()(const Facet & facet) const
+ {
+ Full_cell_handle s = tds_.full_cell(facet)->neighbor(tds_.index_of_covertex(facet));
+ for( int j = 0; j <= tds_.current_dimension(); ++j )
+ {
+ for( int i = 0; i <= dim_; ++i )
+ if( s->vertex(j) == f_.vertex(i) )
+ return true;
+ }
+ return false;
+ }
+ };
+
+ template< typename TraversalPredicate, typename OutputIterator >
+ Facet gather_full_cells(Full_cell_handle, TraversalPredicate &, OutputIterator &) const; /* Concept */
+ template< typename OutputIterator >
+ OutputIterator incident_full_cells(const Face &, OutputIterator) const; /* Concept */
+ template< typename OutputIterator >
+ OutputIterator incident_full_cells(Vertex_const_handle, OutputIterator) const; /* Concept */
+ template< typename OutputIterator >
+ OutputIterator star(const Face &, OutputIterator) const; /* Concept */
+#ifndef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES
+ template< typename OutputIterator, typename Comparator = std::less<Vertex_const_handle> >
+ OutputIterator incident_upper_faces(Vertex_const_handle v, int dim, OutputIterator out, Comparator cmp = Comparator())
+ {
+ return incident_faces(v, dim, out, cmp, true);
+ }
+ template< typename OutputIterator, typename Comparator = std::less<Vertex_const_handle> >
+ OutputIterator incident_faces(Vertex_const_handle, int, OutputIterator, Comparator = Comparator(), bool = false) const;
+#else
+ template< typename OutputIterator, typename Comparator >
+ OutputIterator incident_upper_faces(Vertex_const_handle v, int dim, OutputIterator out, Comparator cmp = Comparator())
+ {
+ return incident_faces(v, dim, out, cmp, true);
+ }
+ template< typename OutputIterator >
+ OutputIterator incident_upper_faces(Vertex_const_handle v, int dim, OutputIterator out)
+ {
+ return incident_faces(v, dim, out, std::less<Vertex_const_handle>(), true);
+ }
+ template< typename OutputIterator, typename Comparator >
+ OutputIterator incident_faces(Vertex_const_handle, int, OutputIterator, Comparator = Comparator(), bool = false) const;
+ template< typename OutputIterator >
+ OutputIterator incident_faces(Vertex_const_handle, int, OutputIterator,
+ std::less<Vertex_const_handle> = std::less<Vertex_const_handle>(), bool = false) const;
+#endif
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INPUT / OUTPUT
+
+ std::istream & read_full_cells(std::istream &, const std::vector<Vertex_handle> &);
+ std::ostream & write_full_cells(std::ostream &, std::map<Vertex_const_handle, int> &) const;
+
+}; // end of ``declaration/definition'' of Triangulation_data_structure<...>
+
+// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+
+// FUNCTIONS THAT ARE MEMBER FUNCTIONS:
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// - - - - - - - - - - - - - - - - - - - - - - - - THE GATHERING METHODS
+
+template< class Dim, class Vb, class Fcb >
+template< typename OutputIterator >
+OutputIterator
+Triangulation_data_structure<Dim, Vb, Fcb>
+::incident_full_cells(const Face & f, OutputIterator out) const /* Concept */
+{
+ // CGAL_expensive_precondition_msg(is_full_cell(f.full_cell()), "the facet does not belong to the Triangulation");
+ Incident_full_cell_traversal_predicate tp(*this, f);
+ gather_full_cells(f.full_cell(), tp, out);
+ return out;
+}
+
+template< class Dim, class Vb, class Fcb >
+template< typename OutputIterator >
+OutputIterator
+Triangulation_data_structure<Dim, Vb, Fcb>
+::incident_full_cells(Vertex_const_handle v, OutputIterator out) const /* Concept */
+{
+// CGAL_expensive_precondition(is_vertex(v));
+ CGAL_precondition(Vertex_handle() != v);
+ Face f(v->full_cell());
+ f.set_index(0, v->full_cell()->index(v));
+ return incident_full_cells(f, out);
+}
+
+template< class Dim, class Vb, class Fcb >
+template< typename OutputIterator >
+OutputIterator
+Triangulation_data_structure<Dim, Vb, Fcb>
+::star(const Face & f, OutputIterator out) const /* Concept */
+{
+ // CGAL_precondition_msg(is_full_cell(f.full_cell()), "the facet does not belong to the Triangulation");
+ Star_traversal_predicate tp(*this, f);
+ gather_full_cells(f.full_cell(), tp, out);
+ return out;
+}
+
+template< class Dim, class Vb, class Fcb >
+template< typename TraversalPredicate, typename OutputIterator >
+typename Triangulation_data_structure<Dim, Vb, Fcb>::Facet
+Triangulation_data_structure<Dim, Vb, Fcb>
+::gather_full_cells(Full_cell_handle start,
+ TraversalPredicate & tp,
+ OutputIterator & out) const /* Concept */
+{
+ std::queue<Full_cell_handle> queue;
+ set_visited(start, true);
+ queue.push(start);
+ const int cur_dim = current_dimension();
+ Facet ft;
+ while( ! queue.empty() )
+ {
+ Full_cell_handle s = queue.front();
+ queue.pop();
+ *out = s;
+ ++out;
+ for( int i = 0; i <= cur_dim; ++i )
+ {
+ Full_cell_handle n = s->neighbor(i);
+ if( ! get_visited(n) )
+ {
+ set_visited(n, true);
+ if( tp(Facet(s, i)) )
+ queue.push(n);
+ else
+ ft = Facet(s, i);
+ }
+ }
+ }
+ clear_visited_marks(start);
+ return ft;
+}
+
+#ifdef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES
+template< class Dim, class Vb, class Fcb >
+template< typename OutputIterator >
+OutputIterator
+Triangulation_data_structure<Dim, Vb, Fcb>
+::incident_faces(Vertex_const_handle v, int dim, OutputIterator out,
+ std::less<Vertex_const_handle> cmp, bool upper_faces) const
+{
+ return incident_faces<OutputIterator, std::less<Vertex_const_handle> >(v, dim, out, cmp, upper_faces);
+}
+#endif
+
+template< class Dim, class Vb, class Fcb >
+template< typename OutputIterator, typename Comparator >
+OutputIterator
+Triangulation_data_structure<Dim, Vb, Fcb>
+::incident_faces(Vertex_const_handle v, int dim, OutputIterator out, Comparator cmp, bool upper_faces) const
+{
+ CGAL_precondition( 0 < dim );
+ if( dim >= current_dimension() )
+ return out;
+ typedef std::vector<Full_cell_handle> Simplices;
+ Simplices simps;
+ simps.reserve(64);
+ // gather incident full_cells
+ std::back_insert_iterator<Simplices> sout(simps);
+ incident_full_cells(v, sout);
+ // for storing the handles to the vertices of a full_cell
+ typedef std::vector<Vertex_const_handle> Vertices;
+ typedef std::vector<int> Indices;
+ Vertices vertices(1 + current_dimension());
+ Indices sorted_idx(1 + current_dimension());
+ // setup Face comparator and Face_set
+ typedef internal::Triangulation::Compare_faces_with_common_first_vertex<Self>
+ Upper_face_comparator;
+ Upper_face_comparator ufc(dim);
+ typedef std::set<Face, Upper_face_comparator> Face_set;
+ Face_set face_set(ufc);
+ for( typename Simplices::const_iterator s = simps.begin(); s != simps.end(); ++s )
+ {
+ int v_idx(0); // the index of |v| in the sorted full_cell
+ // get the vertices of the full_cell and sort them
+ for( int i = 0; i <= current_dimension(); ++i )
+ vertices[i] = (*s)->vertex(i);
+ if( upper_faces )
+ {
+ std::sort(vertices.begin(), vertices.end(), cmp);
+ while( vertices[v_idx] != v )
+ ++v_idx;
+ }
+ else
+ {
+ while( vertices[v_idx] != v )
+ ++v_idx;
+ if( 0 != v_idx )
+ std::swap(vertices[0], vertices[v_idx]);
+ v_idx = 0;
+ typename Vertices::iterator vbegin(vertices.begin());
+ ++vbegin;
+ std::sort(vbegin, vertices.end(), cmp);
+ }
+ if( v_idx + dim > current_dimension() )
+ continue; // |v| is too far to the right
+ // stores the index of the vertices of s in the same order
+ // as in |vertices|:
+ for( int i = 0; i <= current_dimension(); ++i )
+ sorted_idx[i] = (*s)->index(vertices[i]);
+ // init state for enumerating all candidate faces:
+ internal::Combination_enumerator f_idx(dim, v_idx + 1, current_dimension());
+ Face f(*s);
+ f.set_index(0, sorted_idx[v_idx]);
+ while( ! f_idx.end() )
+ {
+ for( int i = 0; i < dim; ++i )
+ f.set_index(1 + i, sorted_idx[f_idx[i]]);
+ face_set.insert(f); // checks if face has already been found
+
+ // compute next sorted face (lexicographic enumeration)
+ ++f_idx;
+ }
+ }
+ typename Face_set::iterator fit = face_set.begin();
+ while( fit != face_set.end() )
+ *out++ = *fit++;
+ return out;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// - - - - - - - - - - - - - - - - - - - - - - - - THE REMOVAL METHODS
+
+template <class Dim, class Vb, class Fcb>
+typename Triangulation_data_structure<Dim, Vb, Fcb>::Vertex_handle
+Triangulation_data_structure<Dim, Vb, Fcb>
+::collapse_face(const Face & f) /* Concept */
+{
+ const int fd = f.face_dimension();
+ CGAL_precondition( (1 <= fd ) && (fd < current_dimension()));
+ std::vector<Full_cell_handle> simps;
+ // save the Face's vertices:
+ Full_cell s;
+ for( int i = 0; i <= fd; ++i )
+ s.set_vertex(i, f.vertex(i));
+ // compute the star of f
+ simps.reserve(64);
+ std::back_insert_iterator<std::vector<Full_cell_handle> > out(simps);
+ star(f, out);
+ Vertex_handle v = insert_in_hole(simps.begin(), simps.end(), Facet(f.full_cell(), f.index(0)));
+ for( int i = 0; i <= fd; ++i )
+ delete_vertex(s.vertex(i));
+ return v;
+}
+
+template <class Dim, class Vb, class Fcb>
+void
+Triangulation_data_structure<Dim, Vb, Fcb>
+::remove_decrease_dimension(Vertex_handle v, Vertex_handle star) /* Concept */
+{
+ CGAL_assertion( current_dimension() >= -1 );
+ if( -1 == current_dimension() )
+ {
+ clear();
+ return;
+ }
+ else if( 0 == current_dimension() )
+ {
+ delete_full_cell(v->full_cell());
+ delete_vertex(v);
+ star->full_cell()->set_neighbor(0, Full_cell_handle());
+ set_current_dimension(-1);
+ return;
+ }
+ else if( 1 == current_dimension() )
+ {
+ Full_cell_handle s = v->full_cell();
+ int star_index;
+ if( s->has_vertex(star, star_index) )
+ s = s->neighbor(star_index);
+ // Here, |star| is not a vertex of |s|, so it's the only finite
+ // full_cell
+ Full_cell_handle inf1 = s->neighbor(0);
+ Full_cell_handle inf2 = s->neighbor(1);
+ Vertex_handle v2 = s->vertex(1 - s->index(v));
+ delete_vertex(v);
+ delete_full_cell(s);
+ inf1->set_vertex(1, Vertex_handle());
+ inf1->set_vertex(1, Vertex_handle());
+ inf2->set_neighbor(1, Full_cell_handle());
+ inf2->set_neighbor(1, Full_cell_handle());
+ associate_vertex_with_full_cell(inf1, 0, star);
+ associate_vertex_with_full_cell(inf2, 0, v2);
+ set_neighbors(inf1, 0, inf2, 0);
+ set_current_dimension(0);
+ return;
+ }
+ typedef std::vector<Full_cell_handle> Simplices;
+ Simplices simps;
+ incident_full_cells(v, std::back_inserter(simps));
+ for( typename Simplices::iterator it = simps.begin(); it != simps.end(); ++it )
+ {
+ int v_idx = (*it)->index(v);
+ if( ! (*it)->has_vertex(star) )
+ {
+ delete_full_cell((*it)->neighbor(v_idx));
+ for( int i = 0; i <= current_dimension(); ++i )
+ (*it)->vertex(i)->set_full_cell(*it);
+ }
+ else
+ star->set_full_cell(*it);
+ if( v_idx != current_dimension() )
+ {
+ (*it)->swap_vertices(v_idx, current_dimension());
+ (*it)->swap_vertices(current_dimension() - 2, current_dimension() - 1);
+ }
+ (*it)->set_vertex(current_dimension(), Vertex_handle());
+ (*it)->set_neighbor(current_dimension(), Full_cell_handle());
+ }
+ set_current_dimension(current_dimension()-1);
+ delete_vertex(v);
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// - - - - - - - - - - - - - - - - - - - - - - - - THE INSERTION METHODS
+
+template <class Dim, class Vb, class Fcb>
+typename Triangulation_data_structure<Dim, Vb, Fcb>::Vertex_handle
+Triangulation_data_structure<Dim, Vb, Fcb>
+::insert_in_full_cell(Full_cell_handle s) /* Concept */
+{
+ CGAL_precondition(0 < current_dimension());
+ CGAL_precondition(Full_cell_handle() != s);
+ // CGAL_expensive_precondition(is_full_cell(s));
+
+ const int cur_dim = current_dimension();
+ Vertex_handle v = new_vertex();
+ // the full_cell 'fc' is just used to store the handle to all the new full_cells.
+ Full_cell fc(maximal_dimension());
+ for( int i = 1; i <= cur_dim; ++i )
+ {
+ Full_cell_handle new_s = new_full_cell(s);
+ fc.set_neighbor(i, new_s);
+ associate_vertex_with_full_cell(new_s, i, v);
+ s->vertex(i-1)->set_full_cell(new_s);
+ set_neighbors(new_s, i, neighbor(s, i), mirror_index(s, i));
+ }
+ fc.set_neighbor(0, s);
+ associate_vertex_with_full_cell(s, 0, v);
+ for( int i = 0; i <= cur_dim; ++i )
+ for( int j = 0; j <= cur_dim; ++j )
+ {
+ if( j == i ) continue;
+ set_neighbors(fc.neighbor(i), j, fc.neighbor(j), i);
+ }
+ return v;
+}
+
+template <class Dim, class Vb, class Fcb >
+typename Triangulation_data_structure<Dim, Vb, Fcb>::Vertex_handle
+Triangulation_data_structure<Dim, Vb, Fcb>
+::insert_in_face(const Face & f) /* Concept */
+{
+ std::vector<Full_cell_handle> simps;
+ simps.reserve(64);
+ std::back_insert_iterator<std::vector<Full_cell_handle> > out(simps);
+ incident_full_cells(f, out);
+ return insert_in_hole(simps.begin(), simps.end(), Facet(f.full_cell(), f.index(0)));
+}
+template <class Dim, class Vb, class Fcb >
+typename Triangulation_data_structure<Dim, Vb, Fcb>::Vertex_handle
+Triangulation_data_structure<Dim, Vb, Fcb>
+::insert_in_facet(const Facet & ft) /* Concept */
+{
+ Full_cell_handle s[2];
+ s[0] = full_cell(ft);
+ int i = index_of_covertex(ft);
+ s[1] = s[0]->neighbor(i);
+ i = ( i + 1 ) % current_dimension();
+ return insert_in_hole(s, s+2, Facet(s[0], i));
+}
+
+template <class Dim, class Vb, class Fcb >
+template < typename OutputIterator >
+typename Triangulation_data_structure<Dim, Vb, Fcb>::Full_cell_handle
+Triangulation_data_structure<Dim, Vb, Fcb>
+::insert_in_tagged_hole(Vertex_handle v, Facet f,
+ OutputIterator new_full_cells)
+{
+ CGAL_assertion_msg(is_boundary_facet(f), "starting facet should be on the hole boundary");
+
+ const int cur_dim = current_dimension();
+ Full_cell_handle new_s;
+
+ std::queue<IITH_task> task_queue;
+ task_queue.push(
+ IITH_task(f, mirror_index(full_cell(f), index_of_covertex(f))) );
+
+ while (!task_queue.empty())
+ {
+ IITH_task task = task_queue.front();
+ task_queue.pop();
+
+ Full_cell_handle old_s = full_cell(task.boundary_facet);
+ const int facet_index = index_of_covertex(task.boundary_facet);
+
+ Full_cell_handle outside_neighbor = neighbor(old_s, facet_index);
+ // Here, "new_s" might actually be a new cell, but it might also be "old_s"
+ // if it has not been treated already in the meantime
+ new_s = neighbor(outside_neighbor, task.index_of_inside_cell_in_outside_cell);
+ // If the cell has not been treated yet
+ if (old_s == new_s)
+ {
+ new_s = new_full_cell();
+
+ int i(0);
+ for ( ; i < facet_index ; ++i)
+ associate_vertex_with_full_cell(new_s, i, old_s->vertex(i));
+ ++i; // skip facet_index
+ for ( ; i <= cur_dim ; ++i)
+ associate_vertex_with_full_cell(new_s, i, old_s->vertex(i));
+ associate_vertex_with_full_cell(new_s, facet_index, v);
+ set_neighbors(new_s,
+ facet_index,
+ outside_neighbor,
+ mirror_index(old_s, facet_index));
+
+ // add the new full_cell to the list of new full_cells
+ *new_full_cells++ = new_s;
+
+ // check all of |Facet f|'s neighbors
+ for (i = 0 ; i <= cur_dim ; ++i)
+ {
+ if (facet_index == i)
+ continue;
+ // we define a |Rotor| because it makes it easy to rotate around
+ // in a self contained fashion. The corresponding potential
+ // boundary facet is Facet(full_cell(rot), index_of_covertex(rot))
+ Rotor rot(old_s, i, facet_index);
+ // |rot| on line above, stands for Candidate Facet
+ while (!is_boundary_facet(rot))
+ rot = rotate_rotor(rot);
+
+ // we did find the |i|-th neighbor of Facet(old_s, facet_index)...
+ // has it already been extruded to center point |v| ?
+ Full_cell_handle inside = full_cell(rot);
+ Full_cell_handle outside = neighbor(inside, index_of_covertex(rot));
+ // "m" is the vertex of outside which is not on the boundary
+ Vertex_handle m = inside->mirror_vertex(index_of_covertex(rot), current_dimension()); // CJTODO: use mirror_index?
+ // "index" is the index of m in "outside"
+ int index = outside->index(m);
+ // new_neighbor is the inside cell which is registered as the neighbor
+ // of the outside cell => it's either a newly created inside cell or an
+ // old inside cell which we are about to delete
+ Full_cell_handle new_neighbor = outside->neighbor(index);
+
+ // Is new_neighbor still the old neighbor?
+ if (new_neighbor == inside)
+ {
+ task_queue.push(IITH_task(
+ Facet(inside, index_of_covertex(rot)), // boundary facet
+ index, // index_of_inside_cell_in_outside_cell
+ new_s, // future_neighbor
+ i, // new_cell_index_in_future_neighbor
+ index_of_second_covertex(rot) // index_of_future_neighbor_in_new_cell
+ ));
+ }
+ }
+ }
+
+ // If there is some neighbor stories to fix
+ if (task.future_neighbor != Full_cell_handle())
+ {
+ // now the new neighboring full_cell exists, we link both
+ set_neighbors(new_s,
+ task.index_of_future_neighbor_in_new_cell,
+ task.future_neighbor,
+ task.new_cell_index_in_future_neighbor);
+ }
+ }
+
+ return new_s;
+}
+
+template< class Dim, class Vb, class Fcb >
+template< typename Forward_iterator, typename OutputIterator >
+typename Triangulation_data_structure<Dim, Vb, Fcb>::Vertex_handle
+Triangulation_data_structure<Dim, Vb, Fcb>
+::insert_in_hole(Forward_iterator start, Forward_iterator end, Facet f,
+ OutputIterator out) /* Concept */
+{
+ CGAL_expensive_precondition(
+ ( std::distance(start, end) == 1 )
+ || ( current_dimension() > 1 ) );
+ Forward_iterator sit = start;
+ while( end != sit )
+ set_visited(*sit++, true);
+ Vertex_handle v = new_vertex();
+ insert_in_tagged_hole(v, f, out);
+ delete_full_cells(start, end);
+ return v;
+}
+
+template< class Dim, class Vb, class Fcb >
+template< typename Forward_iterator >
+typename Triangulation_data_structure<Dim, Vb, Fcb>::Vertex_handle
+Triangulation_data_structure<Dim, Vb, Fcb>
+::insert_in_hole(Forward_iterator start, Forward_iterator end, Facet f) /* Concept */
+{
+ Emptyset_iterator out;
+ return insert_in_hole(start, end, f, out);
+}
+
+template <class Dim, class Vb, class Fcb>
+void
+Triangulation_data_structure<Dim, Vb, Fcb>
+::clear_visited_marks(Full_cell_handle start) const // NOT DOCUMENTED
+{
+ CGAL_precondition(start != Full_cell_handle());
+
+ std::queue<Full_cell_handle> queue;
+ set_visited(start, false);
+ queue.push(start);
+ const int cur_dim = current_dimension();
+ while( ! queue.empty() )
+ {
+ Full_cell_handle s = queue.front();
+ queue.pop();
+ for( int i = 0; i <= cur_dim; ++i )
+ {
+ if( get_visited(s->neighbor(i)) )
+ {
+ set_visited(s->neighbor(i), false);
+ queue.push(s->neighbor(i));
+ }
+ }
+ }
+}
+
+template <class Dim, class Vb, class Fcb>
+void Triangulation_data_structure<Dim, Vb, Fcb>
+::do_insert_increase_dimension(Vertex_handle x, Vertex_handle star)
+{
+ Full_cell_handle start = full_cells_begin();
+ Full_cell_handle swap_me;
+ const int cur_dim = current_dimension();
+ for( Full_cell_iterator S = full_cells_begin(); S != full_cells_end(); ++S )
+ {
+ if( Vertex_handle() != S->vertex(cur_dim) )
+ continue;
+ set_visited(S, true);
+ // extends full_cell |S| to include the new vertex as the
+ // current_dimension()-th vertex
+ associate_vertex_with_full_cell(S, cur_dim, x);
+ if( ! S->has_vertex(star) )
+ { // S is bounded, we create its unbounded "twin" full_cell
+ Full_cell_handle S_new = new_full_cell();
+ set_neighbors(S, cur_dim, S_new, 0);
+ associate_vertex_with_full_cell(S_new, 0, star);
+ // here, we could be clever so as to get consistent orientation
+ for( int k = 1; k <= cur_dim; ++k )
+ associate_vertex_with_full_cell(S_new, k, vertex(S, k - 1));
+ }
+ }
+ // now we setup the neighbors
+ set_visited(start, false);
+ std::queue<Full_cell_handle> queue;
+ queue.push(start);
+ while( ! queue.empty() )
+ {
+ Full_cell_handle S = queue.front();
+ queue.pop();
+ // here, the first visit above ensured that all neighbors exist now.
+ // Now we need to connect them with adjacency relation
+ int star_index;
+ if( S->has_vertex(star, star_index) )
+ {
+ set_neighbors( S, cur_dim, neighbor(neighbor(S, star_index), cur_dim),
+ // this is tricky :-) :
+ mirror_index(S, star_index) + 1);
+ }
+ else
+ {
+ Full_cell_handle S_new = neighbor(S, cur_dim);
+ for( int k = 0 ; k < cur_dim ; ++k )
+ {
+ Full_cell_handle S_opp = neighbor(S, k);
+ if( ! S_opp->has_vertex(star) )
+ set_neighbors(S_new, k + 1, neighbor(S_opp, cur_dim), mirror_index(S, k) + 1);
+ // neighbor of S_new opposite to v is S_new'
+ // the vertex opposite to v remains the same but ...
+ // remember the shifting of the vertices one step to the right
+ }
+ }
+ for( int k = 0 ; k < cur_dim ; ++k )
+ if( get_visited(neighbor(S, k)) )
+ {
+ set_visited(neighbor(S, k), false);
+ queue.push(neighbor(S, k));
+ }
+ }
+ if( ( ( cur_dim % 2 ) == 0 ) && ( cur_dim > 1 ) )
+ {
+ for( Full_cell_iterator S = full_cells_begin(); S != full_cells_end(); ++S )
+ {
+ if( x != S->vertex(cur_dim) )
+ S->swap_vertices(cur_dim - 1, cur_dim);
+ }
+ }
+ if( Full_cell_handle() != swap_me )
+ swap_me->swap_vertices(1, 2);
+}
+
+template <class Dim, class Vb, class Fcb>
+typename Triangulation_data_structure<Dim, Vb, Fcb>::Vertex_handle
+Triangulation_data_structure<Dim, Vb, Fcb>
+::insert_increase_dimension(Vertex_handle star) /* Concept */
+{
+ const int prev_cur_dim = current_dimension();
+ CGAL_precondition(prev_cur_dim < maximal_dimension());
+ if( -2 != current_dimension() )
+ {
+ CGAL_precondition( Vertex_handle() != star );
+ CGAL_expensive_precondition(is_vertex(star));
+ }
+
+ set_current_dimension(prev_cur_dim + 1);
+ Vertex_handle v = new_vertex();
+ switch( prev_cur_dim )
+ {
+ case -2:
+ { // insertion of the first vertex
+ // ( geometrically : infinite vertex )
+ Full_cell_handle s = new_full_cell();
+ associate_vertex_with_full_cell(s, 0, v);
+ break;
+ }
+ case -1:
+ { // insertion of the second vertex
+ // ( geometrically : first finite vertex )
+ //we create a triangulation of the 0-sphere, with
+ // vertices |star| and |v|
+ Full_cell_handle infinite_full_cell = star->full_cell();
+ Full_cell_handle finite_full_cell = new_full_cell();
+ associate_vertex_with_full_cell(finite_full_cell, 0, v);
+ set_neighbors(infinite_full_cell, 0, finite_full_cell, 0);
+ break;
+ }
+ default:
+ do_insert_increase_dimension(v, star);
+ break;
+ }
+ return v;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY CHECKS
+
+template <class Dimen, class Vb, class Fcb>
+bool Triangulation_data_structure<Dimen, Vb, Fcb>
+::is_valid(bool verbose, int /* level */) const /* Concept */
+{
+ Full_cell_const_handle s, t;
+ Vertex_const_handle v;
+ int i, j, k;
+
+ if( current_dimension() == -2 )
+ {
+ if( ! vertices_.empty() || ! full_cells_.empty() )
+ {
+ if( verbose ) CGAL_warning_msg(false, "current dimension is -2 but there are vertices or full_cells");
+ return false;
+ }
+ }
+
+ if( current_dimension() == -1 )
+ {
+ if ( (number_of_vertices() != 1) || (number_of_full_cells() != 1) )
+ {
+ if( verbose ) CGAL_warning_msg(false, "current dimension is -1 but there isn't one vertex and one full_cell");
+ return false;
+ }
+ }
+
+ for( v = vertices_begin(); v != vertices_end(); ++v )
+ {
+ if( ! v->is_valid(verbose) )
+ return false;
+ }
+
+ // FUTURE: for each vertex v, gather incident full_cells. then, check that
+ // any full_cell containing v is among those gathered full_cells...
+
+ if( current_dimension() < 0 )
+ return true;
+
+ for( s = full_cells_begin(); s != full_cells_end(); ++s )
+ {
+ if( ! s->is_valid(verbose) )
+ return false;
+ // check that the full cell has no duplicate vertices
+ for( i = 0; i <= current_dimension(); ++i )
+ for( j = i + 1; j <= current_dimension(); ++j )
+ if( vertex(s,i) == vertex(s,j) )
+ {
+ CGAL_warning_msg(false, "a full_cell has two equal vertices");
+ return false;
+ }
+ }
+
+ for( s = full_cells_begin(); s != full_cells_end(); ++s )
+ {
+ for( i = 0; i <= current_dimension(); ++i )
+ if( (t = neighbor(s,i)) != Full_cell_const_handle() )
+ {
+ int l = mirror_index(s,i);
+ if( s != neighbor(t,l) || i != mirror_index(t,l) )
+ {
+ if( verbose ) CGAL_warning_msg(false, "neighbor relation is not symmetric");
+ return false;
+ }
+ for( j = 0; j <= current_dimension(); ++j )
+ if( j != i )
+ {
+ // j must also occur as a vertex of t
+ for( k = 0; k <= current_dimension() && ( vertex(s,j) != vertex(t,k) || k == l); ++k )
+ ;
+ if( k > current_dimension() )
+ {
+ if( verbose ) CGAL_warning_msg(false, "too few shared vertices between neighbors full_cells.");
+ return false;
+ }
+ }
+ }
+ else
+ {
+ if( verbose ) CGAL_warning_msg(false, "full_cell has a NULL neighbor");
+ return false;
+ }
+ }
+ return true;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// - - - - - - - - - - - - - - - - - - - - - - - - INPUT / OUTPUT
+
+// NOT DOCUMENTED
+template <class Dim, class Vb, class Fcb>
+template <class OutStream>
+void Triangulation_data_structure<Dim, Vb, Fcb>
+::write_graph(OutStream & os)
+{
+ std::vector<std::set<int> > edges;
+ os << number_of_vertices() + 1; // add the vertex at infinity
+ int count(1);
+ for( Vertex_iterator vit = vertices_begin(); vit != vertices_end(); ++vit )
+ vit->idx_ = count++;
+ edges.resize(number_of_vertices()+1);
+ for( Full_cell_iterator sit = full_cells_begin(); sit != full_cells_end(); ++sit )
+ {
+ int v1 = 0;
+ while( v1 < current_dimension() )
+ {
+ int v2 = v1 + 1;
+ while( v2 <= current_dimension() )
+ {
+ int i1, i2;
+ if( Vertex_handle() != sit-> vertex(v1) )
+ i1 = sit->vertex(v1)->idx_;
+ else
+ i1 = 0;
+ if( Vertex_handle() != sit-> vertex(v2) )
+ i2 = sit->vertex(v2)->idx_;
+ else
+ i2 = 0;
+ edges[i1].insert(i2);
+ edges[i2].insert(i1);
+ ++v2;
+ }
+ ++v1;
+ }
+ }
+ for( std::size_t i = 0; i < edges.size(); ++i )
+ {
+ os << std::endl << edges[i].size();
+ for( std::set<int>::const_iterator nit = edges[i].begin();
+ nit != edges[i].end(); ++nit )
+ {
+ os << ' ' << (*nit);
+ }
+ }
+}
+
+// NOT DOCUMENTED...
+template<class Dimen, class Vb, class Fcb>
+std::istream &
+Triangulation_data_structure<Dimen, Vb, Fcb>
+::read_full_cells(std::istream & is, const std::vector<Vertex_handle> & vertices)
+{
+ std::size_t m; // number of full_cells
+ int index;
+ const int cd = current_dimension();
+ if( is_ascii(is) )
+ is >> m;
+ else
+ read(is, m, io_Read_write());
+
+ std::vector<Full_cell_handle> full_cells;
+ full_cells.reserve(m);
+ // read the vertices of each full_cell
+ std::size_t i = 0;
+ while( i < m )
+ {
+ Full_cell_handle s = new_full_cell();
+ full_cells.push_back(s);
+ for( int j = 0; j <= cd; ++j )
+ {
+ if( is_ascii(is) )
+ is >> index;
+ else
+ read(is, index);
+ s->set_vertex(j, vertices[index]);
+ }
+ // read other non-combinatorial information for the full_cells
+ is >> (*s);
+ ++i;
+ }
+
+ // read the neighbors of each full_cell
+ i = 0;
+ if( is_ascii(is) )
+ while( i < m )
+ {
+ for( int j = 0; j <= cd; ++j )
+ {
+ is >> index;
+ full_cells[i]->set_neighbor(j, full_cells[index]);
+ }
+ ++i;
+ }
+ else
+ while( i < m )
+ {
+ for( int j = 0; j <= cd; ++j )
+ {
+ read(is, index);
+ full_cells[i]->set_neighbor(j, full_cells[index]);
+ }
+ ++i;
+ }
+
+ // compute the mirror indices
+ for( i = 0; i < m; ++i )
+ {
+ Full_cell_handle s = full_cells[i];
+ for( int j = 0; j <= cd; ++j )
+ {
+ if( -1 != s->mirror_index(j) )
+ continue;
+ Full_cell_handle n = s->neighbor(j);
+ int k = 0;
+ Full_cell_handle nn = n->neighbor(k);
+ while( s != nn )
+ nn = n->neighbor(++k);
+ s->set_mirror_index(j,k);
+ n->set_mirror_index(k,j);
+ }
+ }
+ return is;
+}
+
+// NOT DOCUMENTED...
+template<class Dimen, class Vb, class Fcb>
+std::ostream &
+Triangulation_data_structure<Dimen, Vb, Fcb>
+::write_full_cells(std::ostream & os, std::map<Vertex_const_handle, int> & index_of_vertex) const
+{
+ std::map<Full_cell_const_handle, int> index_of_full_cell;
+
+ std::size_t m = number_of_full_cells();
+
+ if( is_ascii(os) )
+ os << std::endl << m;
+ else
+ write(os, m, io_Read_write());
+
+ const int cur_dim = current_dimension();
+ // write the vertex indices of each full_cell
+ int i = 0;
+ for( Full_cell_const_iterator it = full_cells_begin(); it != full_cells_end(); ++it )
+ {
+ index_of_full_cell[it] = i++;
+ if( is_ascii(os) )
+ os << std::endl;
+ for( int j = 0; j <= cur_dim; ++j )
+ {
+ if( is_ascii(os) )
+ os << ' ' << index_of_vertex[it->vertex(j)];
+ else
+ write(os, index_of_vertex[it->vertex(j)]);
+ }
+ // write other non-combinatorial information for the full_cells
+ os << (*it);
+ }
+
+ CGAL_assertion( (std::size_t) i == m );
+
+ // write the neighbors of each full_cell
+ if( is_ascii(os) )
+ for( Full_cell_const_iterator it = full_cells_begin(); it != full_cells_end(); ++it )
+ {
+ os << std::endl;
+ for( int j = 0; j <= cur_dim; ++j )
+ os << ' ' << index_of_full_cell[it->neighbor(j)];
+ }
+ else
+ for( Full_cell_const_iterator it = full_cells_begin(); it != full_cells_end(); ++it )
+ {
+ for( int j = 0; j <= cur_dim; ++j )
+ write(os, index_of_full_cell[it->neighbor(j)]);
+ }
+
+ return os;
+}
+
+// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+
+// FUNCTIONS THAT ARE NOT MEMBER FUNCTIONS:
+
+template<class Dimen, class Vb, class Fcb>
+std::istream &
+operator>>(std::istream & is, Triangulation_data_structure<Dimen, Vb, Fcb> & tr)
+ // reads :
+ // - the dimensions (maximal and current)
+ // - the number of finite vertices
+ // - the non combinatorial information on vertices (point, etc)
+ // - the number of full_cells
+ // - the full_cells by the indices of their vertices in the preceding list
+ // of vertices, plus the non combinatorial information on each full_cell
+ // - the neighbors of each full_cell by their index in the preceding list
+{
+ typedef Triangulation_data_structure<Dimen, Vb, Fcb> TDS;
+ typedef typename TDS::Vertex_handle Vertex_handle;
+
+ // read current dimension and number of vertices
+ std::size_t n;
+ int cd;
+ if( is_ascii(is) )
+ is >> cd >> n;
+ else
+ {
+ read(is, cd);
+ read(is, n, io_Read_write());
+ }
+
+ CGAL_assertion_msg( cd <= tr.maximal_dimension(), "input Triangulation_data_structure has too high dimension");
+
+ tr.clear();
+ tr.set_current_dimension(cd);
+
+ if( n == 0 )
+ return is;
+
+ std::vector<Vertex_handle> vertices;
+ vertices.resize(n);
+
+ // read the vertices:
+ std::size_t i(0);
+ while( i < n )
+ {
+ vertices[i] = tr.new_vertex();
+ is >> (*vertices[i]); // read a vertex
+ ++i;
+ }
+
+ // now, read the combinatorial information
+ return tr.read_full_cells(is, vertices);
+}
+
+template<class Dimen, class Vb, class Fcb>
+std::ostream &
+operator<<(std::ostream & os, const Triangulation_data_structure<Dimen, Vb, Fcb> & tr)
+ // writes :
+ // - the dimensions (maximal and current)
+ // - the number of finite vertices
+ // - the non combinatorial information on vertices (point, etc)
+ // - the number of full cells
+ // - the full cells by the indices of their vertices in the preceding list
+ // of vertices, plus the non combinatorial information on each full_cell
+ // - the neighbors of each full_cell by their index in the preceding list
+{
+ typedef Triangulation_data_structure<Dimen, Vb, Fcb> TDS;
+ typedef typename TDS::Vertex_const_handle Vertex_handle;
+ typedef typename TDS::Vertex_const_iterator Vertex_iterator;
+
+ // outputs dimension and number of vertices
+ std::size_t n = tr.number_of_vertices();
+ if( is_ascii(os) )
+ os << tr.current_dimension() << std::endl << n;
+ else
+ {
+ write(os, tr.current_dimension());
+ write(os, n, io_Read_write());
+ }
+
+ if( n == 0 )
+ return os;
+
+ // write the vertices
+ std::map<Vertex_handle, int> index_of_vertex;
+ int i = 0;
+ for( Vertex_iterator it = tr.vertices_begin(); it != tr.vertices_end(); ++it, ++i )
+ {
+ os << *it; // write the vertex
+ if (is_ascii(os))
+ os << std::endl;
+ index_of_vertex[it] = i;
+ }
+ CGAL_assertion( (std::size_t) i == n );
+
+ // output the combinatorial information
+ return tr.write_full_cells(os, index_of_vertex);
+}
+
+} //namespace CGAL
+
+#endif // CGAL_TRIANGULATION_DATA_STRUCTURE_H
diff --git a/include/gudhi_patches/CGAL/Triangulation_ds_full_cell.h b/include/gudhi_patches/CGAL/Triangulation_ds_full_cell.h
new file mode 100644
index 00000000..541a6a85
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Triangulation_ds_full_cell.h
@@ -0,0 +1,311 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_TRIANGULATION_DS_FULL_CELL_H
+#define CGAL_TRIANGULATION_DS_FULL_CELL_H
+
+#include <CGAL/TDS_full_cell_default_storage_policy.h>
+#include <CGAL/TDS_full_cell_mirror_storage_policy.h>
+#include <CGAL/internal/Triangulation/Dummy_TDS.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/Default.h>
+#include <CGAL/array.h>
+
+namespace CGAL {
+
+template< class TDS = void, typename FullCellStoragePolicy = Default >
+class Triangulation_ds_full_cell
+{
+ typedef typename Default::Get<FullCellStoragePolicy, TDS_full_cell_default_storage_policy>::type
+ Storage_policy;
+ typedef Triangulation_ds_full_cell<TDS> Self;
+ typedef typename TDS::Maximal_dimension Maximal_dimension;
+
+public:
+ typedef TDS Triangulation_data_structure;
+ typedef typename TDS::Face Face;
+ typedef typename TDS::Vertex_handle Vertex_handle; /* Concept */
+ typedef typename TDS::Vertex_const_handle Vertex_const_handle;
+ typedef typename TDS::Full_cell_handle Full_cell_handle; /* Concept */
+ typedef typename TDS::Full_cell_const_handle Full_cell_const_handle;
+ typedef typename TDS::Full_cell_data TDS_data; /* data that the TDS wants to be stored here */
+ template< typename TDS2 >
+ struct Rebind_TDS /* Concept */
+ {
+ typedef Triangulation_ds_full_cell<TDS2, FullCellStoragePolicy> Other;
+ };
+
+private: // STORAGE
+ typedef TFC_data< Vertex_handle, Full_cell_handle,
+ Maximal_dimension, Storage_policy > Combinatorics;
+ friend struct TFC_data< Vertex_handle, Full_cell_handle,
+ Maximal_dimension, Storage_policy >;
+ // array of vertices
+ typedef typename Combinatorics::Vertex_handle_array Vertex_handle_array;
+ // neighbor simplices
+ typedef typename Combinatorics::Full_cell_handle_array Full_cell_handle_array;
+
+ // NOT DOCUMENTED...
+ typename Combinatorics::Xor_type xor_of_vertices(const int cur_dim) const
+ {
+ return combinatorics_.xor_of_vertices(cur_dim);
+ }
+
+public:
+ typedef typename Vertex_handle_array::const_iterator Vertex_handle_const_iterator;
+ typedef Vertex_handle_const_iterator Vertex_handle_iterator; /* Concept */
+
+ Triangulation_ds_full_cell(const int dmax) /* Concept */
+ : combinatorics_(dmax), tds_data_()
+ {
+ CGAL_assertion( dmax > 0 );
+ for( int i = 0; i <= dmax; ++i )
+ {
+ set_neighbor(i, Full_cell_handle());
+ set_vertex(i, Vertex_handle());
+ set_mirror_index(i, -1);
+ }
+ }
+
+ Triangulation_ds_full_cell(const Triangulation_ds_full_cell & s) /* Concept */
+ : combinatorics_(s.combinatorics_), tds_data_(s.tds_data_)
+ {}
+
+ ~Triangulation_ds_full_cell() {}
+
+ int maximal_dimension() const /* Concept */
+ {
+ return static_cast<int>(vertices().size() - 1);
+ }
+
+ Vertex_handle_const_iterator vertices_begin() const /* Concept */
+ {
+ return vertices().begin();
+ }
+
+ Vertex_handle_const_iterator vertices_end() const /* Concept */
+ {
+ return vertices().end();
+ }
+
+ Vertex_handle vertex(const int i) const /* Concept */
+ {
+ CGAL_precondition(0<=i && i<=maximal_dimension());
+ return vertices()[i];
+ }
+
+ Full_cell_handle neighbor(const int i) const /* Concept */
+ {
+ CGAL_precondition(0<=i && i<=maximal_dimension());
+ return neighbors()[i];
+ }
+
+ int mirror_index(const int i) const /* Concept */
+ {
+ CGAL_precondition(0<=i && i<=maximal_dimension());
+ return combinatorics_.mirror_index(i);
+ }
+
+ // Advanced...
+ Vertex_handle mirror_vertex(const int i, const int cur_dim) const /* Concept */
+ {
+ CGAL_precondition(0<=i && i<=maximal_dimension());
+ return combinatorics_.mirror_vertex(i, cur_dim);
+ }
+
+ int index(Full_cell_const_handle s) const /* Concept */
+ {
+ // WE ASSUME THE FULL CELL WE ARE LOOKING FOR INDEED EXISTS !
+ CGAL_precondition(has_neighbor(s));
+ int index(0);
+ while( neighbor(index) != s )
+ ++index;
+ return index;
+ }
+
+ int index(Vertex_const_handle v) const /* Concept */
+ {
+ // WE ASSUME THE VERTEX WE ARE LOOKING FOR INDEED EXISTS !
+ CGAL_precondition(has_vertex(v));
+ int index(0);
+ while( vertex(index) != v )
+ ++index;
+ return index;
+ }
+
+ void set_vertex(const int i, Vertex_handle v) /* Concept */
+ {
+ CGAL_precondition(0<=i && i<=maximal_dimension());
+ vertices()[i] = v;
+ }
+
+ void set_neighbor(const int i, Full_cell_handle s) /* Concept */
+ {
+ CGAL_precondition(0<=i && i<=maximal_dimension());
+ neighbors()[i] = s;
+ }
+
+ void set_mirror_index(const int i, const int index) /* Concept */
+ {
+ CGAL_precondition(0<=i && i<=maximal_dimension());
+ combinatorics_.set_mirror_index(i, index);
+ }
+
+ bool has_vertex(Vertex_const_handle v) const /* Concept */
+ {
+ int index;
+ return has_vertex(v, index);
+ }
+
+ bool has_vertex(Vertex_const_handle v, int & index) const /* Concept */
+ {
+ const int d = maximal_dimension();
+ index = 0;
+ while( (index <= d) && (vertex(index) != v) )
+ ++index;
+ return (index <= d);
+ }
+
+ bool has_neighbor(Full_cell_const_handle s) const /* Concept */
+ {
+ int index;
+ return has_neighbor(s, index);
+ }
+
+ bool has_neighbor(Full_cell_const_handle s, int & index) const /* Concept */
+ {
+ const int d = maximal_dimension();
+ index = 0;
+ while( (index <= d) && (neighbor(index) != s) )
+ ++index;
+ return (index <= d);
+ }
+
+ void swap_vertices(const int d1, const int d2) /* Concept */
+ {
+ CGAL_precondition(0 <= d1 && d1<=maximal_dimension());
+ CGAL_precondition(0 <= d2 && d2<=maximal_dimension());
+ combinatorics_.swap_vertices(d1, d2);
+ }
+
+ const TDS_data & tds_data() const { return tds_data_; } /* Concept */
+ TDS_data & tds_data() { return tds_data_; } /* Concept */
+
+ void* for_compact_container() const { return combinatorics_.for_compact_container(); }
+ void* & for_compact_container() { return combinatorics_.for_compact_container(); }
+
+ bool is_valid(bool verbose = false, int = 0) const /* Concept */
+ {
+ const int d = maximal_dimension();
+ int i(0);
+ // test that the non-null Vertex_handles come first, before all null ones
+ while( i <= d && vertex(i) != Vertex_handle() ) ++i;
+ while( i <= d && vertex(i) == Vertex_handle() ) ++i;
+ if( i <= d )
+ {
+ if( verbose ) CGAL_warning_msg(false, "full cell has garbage handles to vertices.");
+ return false;
+ }
+ for( i = 0; i <= d; ++i )
+ {
+ if( Vertex_handle() == vertex(i) )
+ break; // there are no more vertices
+ Full_cell_handle n(neighbor(i));
+ if( Full_cell_handle() != n )
+ {
+ int mirror_idx(mirror_index(i));
+ if( n->neighbor(mirror_idx) == Full_cell_handle() )
+ {
+ if( verbose ) CGAL_warning_msg(false, "neighbor has no back-neighbor.");
+ return false;
+ }
+ if( &(*(n->neighbor(mirror_idx))) != this )
+ {
+ if( verbose ) CGAL_warning_msg(false, "neighbor does not point back to correct full cell.");
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+private:
+ // access to data members:
+ Full_cell_handle_array & neighbors() {return combinatorics_.neighbors_; }
+ const Full_cell_handle_array & neighbors() const {return combinatorics_.neighbors_; }
+ Vertex_handle_array & vertices() {return combinatorics_.vertices_; }
+ const Vertex_handle_array & vertices() const {return combinatorics_.vertices_; }
+
+ // DATA MEMBERS
+ Combinatorics combinatorics_;
+ mutable TDS_data tds_data_;
+};
+
+// FUNCTIONS THAT ARE NOT MEMBER FUNCTIONS:
+
+template < typename TDS, typename SSP >
+std::ostream &
+operator<<(std::ostream & O, const Triangulation_ds_full_cell<TDS,SSP> &) /* Concept */
+{
+ /*if( is_ascii(O) )
+ {
+ // os << '\n';
+ }
+ else {}*/
+ return O;
+}
+
+template < typename TDS, typename SSP >
+std::istream &
+operator>>(std::istream & I, Triangulation_ds_full_cell<TDS,SSP> &) /* Concept */
+{
+ /*if( is_ascii(I) )
+ {}
+ else {}*/
+ return I;
+}
+
+// Special case: specialization when template parameter is void.
+
+// we must declare it for each possible full_cell storage policy because :
+// (GCC error:) default template arguments may not be used in partial specializations
+template< typename StoragePolicy >
+class Triangulation_ds_full_cell<void, StoragePolicy>
+{
+public:
+ typedef internal::Triangulation::Dummy_TDS TDS;
+ typedef TDS Triangulation_data_structure;
+ typedef TDS::Vertex_handle Vertex_handle;
+ typedef TDS::Vertex_const_handle Vertex_const_handle;
+ typedef TDS::Full_cell_handle Full_cell_handle;
+ typedef TDS::Full_cell_const_handle Full_cell_const_handle;
+ typedef TDS::Vertex_handle_const_iterator Vertex_handle_const_iterator;
+ typedef TDS::Full_cell_data TDS_data;
+ template <typename TDS2>
+ struct Rebind_TDS
+ {
+ typedef Triangulation_ds_full_cell<TDS2, StoragePolicy> Other;
+ };
+ Vertex_handle_const_iterator vertices_begin();
+ Vertex_handle_const_iterator vertices_end();
+};
+
+} //namespace CGAL
+
+#endif // CGAL_TRIANGULATION_DS_FULL_CELL_H
diff --git a/include/gudhi_patches/CGAL/Triangulation_ds_vertex.h b/include/gudhi_patches/CGAL/Triangulation_ds_vertex.h
new file mode 100644
index 00000000..381b97e1
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Triangulation_ds_vertex.h
@@ -0,0 +1,154 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_TRIANGULATION_DS_VERTEX_H
+#define CGAL_TRIANGULATION_DS_VERTEX_H
+
+#include <CGAL/Compact_container.h>
+#include <CGAL/internal/Triangulation/Dummy_TDS.h>
+
+namespace CGAL {
+
+/* The template parameter TDS must be a model of the concept
+ * 'TriangulationDataStructure' that stores vertices of type
+ * 'Triangulation_ds_vertex<TDS>'
+ */
+template< class TDS = void >
+class Triangulation_ds_vertex
+{
+ typedef Triangulation_ds_vertex<TDS> Self;
+
+public:
+ typedef TDS Triangulation_data_structure;
+ typedef typename TDS::Full_cell_handle Full_cell_handle; /* Concept */
+
+ template <typename TDS2>
+ struct Rebind_TDS /* Concept */
+ {
+ typedef Triangulation_ds_vertex<TDS2> Other;
+ };
+
+protected: // DATA MEMBERS
+ Full_cell_handle full_cell_; // A handle to an incident full_cell
+
+public:
+ // Constructs a vertex with incident full_cell 's'
+ Triangulation_ds_vertex(Full_cell_handle s) : full_cell_(s) /* Concept */
+ {
+ CGAL_assertion( Full_cell_handle() != s );
+ }
+ // Constructs a vertex with no incident full_cell
+ Triangulation_ds_vertex() : full_cell_() {} /* Concept */
+
+ ~Triangulation_ds_vertex() {}
+
+ /// Set 's' as an incident full_cell
+ void set_full_cell(Full_cell_handle s) /* Concept */
+ {
+ full_cell_ = s;
+ }
+
+ /// Returns a full_cell incident to the vertex
+ Full_cell_handle full_cell() const /* Concept */
+ {
+ return full_cell_;
+ }
+
+ bool is_valid(bool verbose = false, int /* level */ = 0) const /* Concept */
+ {
+ if( Full_cell_handle() == full_cell() )
+ {
+ if( verbose )
+ CGAL_warning_msg(false, "vertex has no incident full cell.");
+ return false;
+ }
+ bool found(false);
+ // These two typename below are OK because TDS fullfils the
+ // TriangulationDataStructure concept.
+ typename TDS::Full_cell::Vertex_handle_iterator vit(full_cell()->vertices_begin());
+ typedef typename TDS::Vertex_handle Vertex_handle;
+ while( vit != full_cell()->vertices_end() )
+ {
+ if( Vertex_handle() == *vit )
+ break; // The full cell has no more vertices
+ if( this == &(**vit) )
+ {
+ found = true;
+ break;
+ }
+ ++vit;
+ }
+ if( ! found )
+ {
+ if( verbose )
+ CGAL_warning_msg(false, "vertex's adjacent full cell does not contain that vertex.");
+ return false;
+ }
+ return true;
+ }
+
+public: // FOR MEMORY MANAGEMENT
+
+ void* for_compact_container() const { return full_cell_.for_compact_container(); }
+ void* & for_compact_container() { return full_cell_.for_compact_container(); }
+
+}; // end of Triangulation_ds_vertex
+
+// FUNCTIONS THAT ARE NOT MEMBER FUNCTIONS:
+
+template < class TDS >
+std::istream &
+operator>>(std::istream & is, Triangulation_ds_vertex<TDS> &) /* Concept */
+{
+ /*if( is_ascii(is) )
+ {}
+ else {}*/
+ return is;
+}
+
+template< class TDS >
+std::ostream &
+operator<<(std::ostream & os, const Triangulation_ds_vertex<TDS> &) /* Concept */
+{
+ /*if( is_ascii(os) )
+ {
+ os << '\n';
+ }
+ else {}*/
+ return os;
+}
+
+// Special case: specialization when template parameter is void.
+
+template<>
+class Triangulation_ds_vertex<void>
+{
+public:
+ typedef internal::Triangulation::Dummy_TDS Triangulation_data_structure;
+ typedef Triangulation_data_structure::Full_cell_handle Full_cell_handle; /* Concept */
+ template <typename TDS2>
+ struct Rebind_TDS /* Concept */
+ {
+ typedef Triangulation_ds_vertex<TDS2> Other;
+ };
+};
+
+} //namespace CGAL
+
+#endif // CGAL_TRIANGULATION_DS_VERTEX_H
diff --git a/include/gudhi_patches/CGAL/Triangulation_face.h b/include/gudhi_patches/CGAL/Triangulation_face.h
new file mode 100644
index 00000000..bc9c1781
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Triangulation_face.h
@@ -0,0 +1,111 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_TRIANGULATION_FACE_H
+#define CGAL_TRIANGULATION_FACE_H
+
+#include <CGAL/basic.h>
+#include <CGAL/internal/Static_or_dynamic_array.h>
+
+namespace CGAL {
+
+template< typename TDS >
+class Triangulation_face
+{
+ typedef typename internal::Dimen_plus_one<typename TDS::Maximal_dimension>::type Dimen_plus;
+public:
+ typedef TDS Triangulation_data_structure;
+ typedef typename TDS::Full_cell_handle Full_cell_handle; /* Concept */
+ typedef typename TDS::Vertex_handle Vertex_handle; /* Concept */
+ typedef internal::S_or_D_array<int, Dimen_plus> Indices;
+
+protected:
+ Full_cell_handle full_cell_;
+ Indices indices_;
+
+public:
+ explicit Triangulation_face(Full_cell_handle s) /* Concept */
+ : full_cell_(s), indices_(s->maximal_dimension()+2)
+ {
+ CGAL_assertion( Full_cell_handle() != s );
+ clear();
+ }
+
+ explicit Triangulation_face(const int maximal_dim) /* Concept */
+ : full_cell_(), indices_(maximal_dim+2)
+ {
+ clear();
+ }
+
+ Triangulation_face(const Triangulation_face & f) /* Concept */
+ : full_cell_(f.full_cell_), indices_(f.indices_)
+ {}
+
+ int face_dimension() const /* Concept */
+ {
+ int i(0);
+ while( -1 != indices_[i] ) ++i;
+ return (i-1);
+ }
+
+ Full_cell_handle full_cell() const /* Concept */
+ {
+ return full_cell_;
+ }
+
+ int index(const int i) const /* Concept */
+ {
+ CGAL_precondition( (0 <= i) && (i <= face_dimension()) );
+ return indices_[i];
+ }
+
+ Vertex_handle vertex(const int i) const /* Concept */
+ {
+ int j = index(i);
+ if( j == -1 )
+ return Vertex_handle();
+ return full_cell()->vertex(j);
+ }
+
+// - - - - - - - - - - - - - - - - - - UPDATE FUNCTIONS
+
+ void clear() /* Concept */
+ {
+ const std::size_t d = indices_.size();
+ for(std::size_t i = 0; i < d; ++i )
+ indices_[i] = -1;
+ }
+
+ void set_full_cell(Full_cell_handle s) /* Concept */
+ {
+ CGAL_precondition( Full_cell_handle() != s );
+ full_cell_ = s;
+ }
+
+ void set_index(const int i, const int idx) /* Concept */
+ {
+ CGAL_precondition( (0 <= i) && ((size_t)i+1 < indices_.size()) );
+ CGAL_precondition( (0 <= idx) && ((size_t)idx < indices_.size()) );
+ indices_[i] = idx;
+ }
+};
+
+} //namespace CGAL
+
+#endif // CGAL_TRIANGULATION_FACE_H
diff --git a/include/gudhi_patches/CGAL/Triangulation_full_cell.h b/include/gudhi_patches/CGAL/Triangulation_full_cell.h
new file mode 100644
index 00000000..a0c5246f
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Triangulation_full_cell.h
@@ -0,0 +1,148 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_TRIANGULATION_SIMPLEX_H
+#define CGAL_TRIANGULATION_SIMPLEX_H
+
+#include <CGAL/Triangulation_ds_full_cell.h>
+#include <CGAL/internal/Triangulation/utilities.h>
+#include <CGAL/Iterator_project.h>
+#include <CGAL/Default.h>
+
+namespace CGAL {
+
+struct No_full_cell_data {};
+
+template< class TriangulationTraits, typename Data_ = No_full_cell_data, class TDSFullCell = Default >
+class Triangulation_full_cell : public Default::Get<TDSFullCell, Triangulation_ds_full_cell<> >::type
+{
+ // The default type for TDSFullCell is Triangulation_ds_full_cell<> :
+ typedef typename Default::Get<TDSFullCell, Triangulation_ds_full_cell<> >::type
+ Base;
+ typedef Triangulation_full_cell<TriangulationTraits, Data_, TDSFullCell> Self;
+public:
+ typedef Data_ Data;
+ typedef typename Base::Vertex_handle Vertex_handle;
+ typedef typename Base::Vertex_const_handle Vertex_const_handle;
+ typedef typename Base::Vertex_handle_const_iterator Vertex_handle_const_iterator;
+ typedef typename Base::Full_cell_const_handle Full_cell_const_handle;
+ typedef typename TriangulationTraits::Point_d Point;
+ typedef typename TriangulationTraits::Point_d Point_d;
+
+private: // DATA MEMBERS
+ Data data_;
+
+public:
+
+ using Base::vertices_begin;
+ using Base::vertices_end;
+
+ template< class TDS2 >
+ struct Rebind_TDS
+ {
+ typedef typename Base::template Rebind_TDS<TDS2>::Other TDSFullCell2;
+ typedef Triangulation_full_cell<TriangulationTraits, Data_, TDSFullCell2> Other;
+ };
+
+ Triangulation_full_cell(const int d)
+ : Base(d), data_() {}
+
+ Triangulation_full_cell(const Self & s)
+ : Base(s), data_(s.data_) {}
+
+ const Data & data() const
+ {
+ return data_;
+ }
+
+ Data & data()
+ {
+ return data_;
+ }
+
+ struct Point_from_vertex_handle
+ {
+ typedef Vertex_handle argument_type;
+ typedef Point result_type;
+ result_type & operator()(argument_type & x) const
+ {
+ return x->point();
+ }
+ const result_type & operator()(const argument_type & x) const
+ {
+ return x->point();
+ }
+ };
+
+protected:
+
+ typedef CGAL::Iterator_project<
+ Vertex_handle_const_iterator,
+ internal::Triangulation::Point_from_vertex_handle<Vertex_handle, Point>
+ > Point_const_iterator;
+
+ Point_const_iterator points_begin() const
+ { return Point_const_iterator(Base::vertices_begin()); }
+ Point_const_iterator points_end() const
+ { return Point_const_iterator(Base::vertices_end()); }
+};
+
+// FUNCTIONS THAT ARE NOT MEMBER FUNCTIONS:
+
+inline
+std::istream &
+operator>>(std::istream & is, No_full_cell_data &)
+{
+ return is;
+}
+
+inline
+std::ostream &
+operator<<(std::ostream & os, const No_full_cell_data &)
+{
+ return os;
+}
+
+template < typename TDS, typename Data, typename SSP >
+std::ostream &
+operator<<(std::ostream & O, const Triangulation_full_cell<TDS, Data, SSP> & s)
+{
+ /*if( is_ascii(O) )
+ {
+ // os << '\n';
+ }
+ else {}*/
+ O << s.data();
+ return O;
+}
+
+template < typename TDS, typename Data, typename SSP >
+std::istream &
+operator>>(std::istream & I, Triangulation_full_cell<TDS, Data, SSP> & s)
+{
+ /*if( is_ascii(I) )
+ {}
+ else {}*/
+ I >> s.data();
+ return I;
+}
+
+} //namespace CGAL
+
+#endif // CGAL_TRIANGULATION_SIMPLEX_H
diff --git a/include/gudhi_patches/CGAL/Triangulation_vertex.h b/include/gudhi_patches/CGAL/Triangulation_vertex.h
new file mode 100644
index 00000000..f364717f
--- /dev/null
+++ b/include/gudhi_patches/CGAL/Triangulation_vertex.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_TRIANGULATION_VERTEX_H
+#define CGAL_TRIANGULATION_VERTEX_H
+
+#include <CGAL/Triangulation_ds_vertex.h>
+#include <CGAL/Default.h>
+
+namespace CGAL {
+
+struct No_vertex_data {};
+
+template< class TriangulationTraits, typename Data_ = No_vertex_data, class TDSVertex = Default >
+class Triangulation_vertex : public Default::Get<TDSVertex, Triangulation_ds_vertex<> >::type
+{
+ // The default type for TDSVertex is Triangulation_ds_vertex<> :
+ typedef typename Default::Get<TDSVertex, Triangulation_ds_vertex<> >::type
+ Base;
+ typedef Triangulation_vertex<TriangulationTraits, Data_, TDSVertex> Self;
+public:
+ typedef Data_ Data;
+ typedef typename TriangulationTraits::Point_d Point;
+ typedef typename TriangulationTraits::Point_d Point_d;
+ typedef typename Base::Full_cell_handle Full_cell_handle;
+
+ template <typename TDS2>
+ struct Rebind_TDS
+ {
+ typedef typename Base::template Rebind_TDS<TDS2>::Other TDSVertex2;
+ typedef Triangulation_vertex<TriangulationTraits, Data_, TDSVertex2> Other;
+ };
+
+private: // DATA MEMBERS
+ Point point_;
+ Data data_;
+
+public:
+ template< typename T >
+ Triangulation_vertex(Full_cell_handle s, const Point & p, const T & t)
+ : Base(s), point_(p), data_(t) {}
+ Triangulation_vertex(Full_cell_handle s, const Point & p)
+ : Base(s), point_(p), data_() {}
+ template< typename T >
+ Triangulation_vertex(const Point & p, const T & t)
+ : Base(), point_(p), data_(t) {}
+ Triangulation_vertex(const Point & p)
+ : Base(), point_(p), data_() {}
+ Triangulation_vertex() : Base(), point_(), data_() {}
+
+ ~Triangulation_vertex() {}
+
+ /// Set the position in space of the vertex to 'p'
+ void set_point(const Point & p)
+ {
+ point_ = p;
+ }
+
+ /// Returns the position in space of the vertex
+ const Point & point() const
+ {
+ return point_;
+ }
+
+ const Data & data() const
+ {
+ return data_;
+ }
+
+ Data & data()
+ {
+ return data_;
+ }
+
+}; // end of Triangulation_vertex
+
+// NON CLASS-MEMBER FUNCTIONS
+
+inline
+std::istream &
+operator>>(std::istream & is, No_vertex_data &)
+{
+ return is;
+}
+
+inline
+std::ostream &
+operator<<(std::ostream & os, const No_vertex_data &)
+{
+ return os;
+}
+
+template < class A, typename Data, class B >
+std::istream &
+operator>>(std::istream & is, Triangulation_vertex<A, Data, B> & v)
+{
+ is >> v.point();
+ return (is >> v.data());
+}
+
+template< class A, typename Data, class B >
+std::ostream &
+operator<<(std::ostream & os, const Triangulation_vertex<A, Data, B> & v)
+{
+ os << v.point();
+ os << v.data();
+ return os;
+}
+
+} //namespace CGAL
+
+#endif // CGAL_TRIANGULATION_VERTEX_H
diff --git a/include/gudhi_patches/CGAL/argument_swaps.h b/include/gudhi_patches/CGAL/argument_swaps.h
new file mode 100644
index 00000000..aa16f29b
--- /dev/null
+++ b/include/gudhi_patches/CGAL/argument_swaps.h
@@ -0,0 +1,88 @@
+// 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_ARGUMENT_SWAPS_H
+#define CGAL_ARGUMENT_SWAPS_H
+
+#include <CGAL/config.h>
+#include <utility>
+
+#ifndef CGAL_CXX11
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/utility/result_of.hpp>
+#endif
+
+namespace CGAL {
+
+#ifdef CGAL_CXX11
+
+namespace internal {
+
+template<int,class...> struct Apply_to_last_then_rest_;
+
+template<int d,class F,class T,class... U>
+struct Apply_to_last_then_rest_<d,F,T,U...> {
+ typedef typename Apply_to_last_then_rest_<d-1,F,U...,T>::result_type result_type;
+ inline result_type operator()(F&&f,T&&t,U&&...u)const{
+ return Apply_to_last_then_rest_<d-1,F,U...,T>()(
+ std::forward<F>(f),
+ std::forward<U>(u)...,
+ std::forward<T>(t));
+ }
+};
+
+template<class F,class T,class... U>
+struct Apply_to_last_then_rest_<0,F,T,U...> {
+ typedef decltype(std::declval<F>()(std::declval<T>(), std::declval<U>()...)) result_type;
+ inline result_type operator()(F&&f,T&&t,U&&...u)const{
+ return std::forward<F>(f)(std::forward<T>(t), std::forward<U>(u)...);
+ }
+};
+
+} // namespace internal
+
+
+struct Apply_to_last_then_rest {
+ template<class F,class T,class...U> inline
+ typename internal::Apply_to_last_then_rest_<sizeof...(U),F,T,U...>::result_type
+ operator()(F&&f,T&&t,U&&...u)const{
+ return internal::Apply_to_last_then_rest_<sizeof...(U),F,T,U...>()(
+ std::forward<F>(f),
+ std::forward<T>(t),
+ std::forward<U>(u)...);
+ }
+};
+
+#else // CGAL_CXX11
+
+struct Apply_to_last_then_rest {
+#define CGAL_CODE(Z,N,_) template<class F,class T,BOOST_PP_ENUM_PARAMS(N,class T)> \
+ typename boost::result_of<F(T,BOOST_PP_ENUM_PARAMS(N,T))>::type \
+ operator()(F const&f, BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t), T const&t) const { \
+ return f(t,BOOST_PP_ENUM_PARAMS(N,t)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_)
+#undef CGAL_CODE
+};
+
+#endif // CGAL_CXX11
+
+} // namespace CGAL
+
+#endif // CGAL_ARGUMENT_SWAPS_H
diff --git a/include/gudhi_patches/CGAL/determinant_of_vectors.h b/include/gudhi_patches/CGAL/determinant_of_vectors.h
new file mode 100644
index 00000000..e1bad64e
--- /dev/null
+++ b/include/gudhi_patches/CGAL/determinant_of_vectors.h
@@ -0,0 +1,117 @@
+// 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_DETVEC_H
+#define CGAL_DETVEC_H
+#include <CGAL/determinant.h>
+#include <CGAL/predicates/sign_of_determinant.h>
+
+namespace CGAL {
+ // TODO: determine whether it is better to pass them by lines or columns.
+
+ template <class NT, class Vector> inline
+ NT determinant_of_vectors(Vector const&a, Vector const&b){
+ return determinant<NT>(a[0],a[1],b[0],b[1]);
+ }
+ template <class NT, class Vector> inline
+ typename Sgn<NT>::result_type
+ sign_of_determinant_of_vectors(Vector const&a, Vector const&b){
+ return sign_of_determinant<NT>(a[0],a[1],b[0],b[1]);
+ }
+
+ template <class NT, class Vector>
+ NT determinant_of_vectors(Vector const&a, Vector const&b,
+ Vector const&c){
+ return determinant<NT>(a[0],a[1],a[2],b[0],b[1],b[2],c[0],c[1],c[2]);
+ }
+ template <class NT, class Vector>
+ typename Sgn<NT>::result_type
+ sign_of_determinant_of_vectors(Vector const&a, Vector const&b,
+ Vector const&c){
+ return sign_of_determinant<NT>(a[0],a[1],a[2],b[0],b[1],b[2],c[0],c[1],c[2]);
+ }
+
+ template <class NT, class Vector>
+ NT determinant_of_vectors(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d){
+ return determinant<NT>(
+ a[0],a[1],a[2],a[3],
+ b[0],b[1],b[2],b[3],
+ c[0],c[1],c[2],c[3],
+ d[0],d[1],d[2],d[3]);
+ }
+ template <class NT, class Vector>
+ typename Sgn<NT>::result_type
+ sign_of_determinant_of_vectors(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d){
+ return sign_of_determinant<NT>(
+ a[0],a[1],a[2],a[3],
+ b[0],b[1],b[2],b[3],
+ c[0],c[1],c[2],c[3],
+ d[0],d[1],d[2],d[3]);
+ }
+
+ template <class NT, class Vector>
+ NT determinant_of_vectors(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e){
+ return determinant<NT>(
+ a[0],a[1],a[2],a[3],a[4],
+ b[0],b[1],b[2],b[3],b[4],
+ c[0],c[1],c[2],c[3],c[4],
+ d[0],d[1],d[2],d[3],d[4],
+ e[0],e[1],e[2],e[3],e[4]);
+ }
+ template <class NT, class Vector>
+ typename Sgn<NT>::result_type
+ sign_of_determinant_of_vectors(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e){
+ return sign_of_determinant<NT>(
+ a[0],a[1],a[2],a[3],a[4],
+ b[0],b[1],b[2],b[3],b[4],
+ c[0],c[1],c[2],c[3],c[4],
+ d[0],d[1],d[2],d[3],d[4],
+ e[0],e[1],e[2],e[3],e[4]);
+ }
+
+ template <class NT, class Vector>
+ NT determinant_of_vectors(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e, Vector const&f){
+ return determinant<NT>(
+ a[0],a[1],a[2],a[3],a[4],a[5],
+ b[0],b[1],b[2],b[3],b[4],b[5],
+ c[0],c[1],c[2],c[3],c[4],c[5],
+ d[0],d[1],d[2],d[3],d[4],d[5],
+ e[0],e[1],e[2],e[3],e[4],e[5],
+ f[0],f[1],f[2],f[3],f[4],f[5]);
+ }
+ template <class NT, class Vector>
+ typename Sgn<NT>::result_type
+ sign_of_determinant_of_vectors(Vector const&a, Vector const&b,
+ Vector const&c, Vector const&d, Vector const&e, Vector const&f){
+ return sign_of_determinant<NT>(
+ a[0],a[1],a[2],a[3],a[4],a[5],
+ b[0],b[1],b[2],b[3],b[4],b[5],
+ c[0],c[1],c[2],c[3],c[4],c[5],
+ d[0],d[1],d[2],d[3],d[4],d[5],
+ e[0],e[1],e[2],e[3],e[4],e[5],
+ f[0],f[1],f[2],f[3],f[4],f[5]);
+ }
+
+}
+#endif
diff --git a/include/gudhi_patches/CGAL/internal/Combination_enumerator.h b/include/gudhi_patches/CGAL/internal/Combination_enumerator.h
new file mode 100644
index 00000000..f411e827
--- /dev/null
+++ b/include/gudhi_patches/CGAL/internal/Combination_enumerator.h
@@ -0,0 +1,148 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_INTERNAL_COMBINATION_ENUMERATOR_H
+#define CGAL_INTERNAL_COMBINATION_ENUMERATOR_H
+
+#include <CGAL/basic.h>
+#include <vector>
+
+namespace CGAL {
+
+namespace internal {
+
+class Combination_enumerator
+{
+ // types and member data
+ typedef std::vector<int> Combination;
+ Combination combi_;
+ const int k_;
+ const int min_;
+ const int max_;
+ const int max_at_pos_0_;
+
+public:
+
+ // For generating all the combinations of |k| distinct elements in the
+ // interval [min, max] (both included)
+ Combination_enumerator(const int k, const int min, const int max)
+ : combi_(k), k_(k), min_(min), max_(max), max_at_pos_0_(max + 1 - k)
+ {
+ CGAL_assertion_msg( min <= max, "min is larger than max");
+ CGAL_assertion_msg( 1 <= k && k <= ( max - min + 1 ), "wrong value of k");
+ init();
+ }
+
+ Combination_enumerator(const Combination_enumerator & c)
+ : combi_(c.combi_), k_(c.k_), min_(c.min_), max_(c.max_), max_at_pos_0_(c.max_at_pos_0_)
+ {}
+
+ int number_of_elements()
+ {
+ return k_;
+ }
+
+ void init()
+ {
+ combi_.resize(k_);
+ for( int i = 0; i < k_; ++i )
+ element(i) = min_ + i;
+ }
+
+ bool end() const
+ {
+ return ( element(0) > max_at_pos_0_ );
+ }
+
+ int element(const int i) const
+ {
+ CGAL_assertion( 0 <= i && i < k_ );
+ return combi_[i];
+ }
+
+ int & element(const int i)
+ {
+ CGAL_assertion( 0 <= i && i < k_ );
+ return combi_[i];
+ }
+
+ int operator[](const int i) const
+ {
+ return element(i);
+ }
+
+ int & operator[](const int i)
+ {
+ return element(i);
+ }
+
+ void operator++()
+ {
+ int i = k_ - 1;
+ int max_at_pos_i(max_);
+ while( ( i >= 0 ) && ( element(i) >= max_at_pos_i ) )
+ {
+ --i;
+ --max_at_pos_i;
+ }
+ if( -1 == i )
+ {
+ if( element(0) == max_at_pos_0_ )
+ ++element(0); // mark then end of the enumeration with an impossible value
+ // Note than when we have arrived at the end of the enumeration, applying
+ // operator++() again does not change anything, so it is safe to
+ // apply it too many times.
+ }
+ else
+ {
+ ++element(i);
+ for( int j = i + 1; j < k_; ++j )
+ element(j) = element(i) + j - i;
+ }
+ }
+
+ Combination_enumerator operator++(int)
+ {
+ Combination_enumerator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - TESTING
+#if 0
+ void test()
+ {
+ std::cerr << '\n';
+ while( ! end() )
+ {
+ std::cerr << '\n';
+ for( int i = 0; i < k_; ++i )
+ std::cerr << element(i) << ' ';
+ ++(*this);
+ }
+ init();
+ }
+#endif
+};
+
+} // end of namespace internal
+
+} // end of namespace CGAL
+
+#endif // CGAL_INTERNAL_COMBINATION_ENUMERATOR_H
diff --git a/include/gudhi_patches/CGAL/internal/Static_or_dynamic_array.h b/include/gudhi_patches/CGAL/internal/Static_or_dynamic_array.h
new file mode 100644
index 00000000..ee6195d9
--- /dev/null
+++ b/include/gudhi_patches/CGAL/internal/Static_or_dynamic_array.h
@@ -0,0 +1,116 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_INTERNAL_STATIC_OR_DYNAMIC_ARRAY_H
+#define CGAL_INTERNAL_STATIC_OR_DYNAMIC_ARRAY_H
+
+#include <CGAL/Compact_container.h>
+#include <CGAL/Dimension.h>
+#include <CGAL/array.h>
+#include <vector>
+
+namespace CGAL {
+
+namespace internal {
+
+// Utility for adding one to an Dimension_tag:
+
+template<typename D>
+struct Dimen_plus_one;
+
+template<>
+struct Dimen_plus_one<Dynamic_dimension_tag>
+{
+ typedef Dynamic_dimension_tag type;
+};
+
+template<int D>
+struct Dimen_plus_one<Dimension_tag<D> >
+{
+ typedef Dimension_tag<D+1> type;
+};
+
+// A SMALL CONTAINER UTILITY FOR DYNAMIC/STATIC MEMORY MANAGEMENT
+
+// stores an array of static or dynamic size, depending on template parameter <B>.
+
+template< typename Containee, typename D, bool WithCompactContainerHelper = false>
+ struct S_or_D_array; // S = static, D = dynamic
+
+// The case of static size:
+template< typename Containee, int D, bool WithCompactContainerHelper >
+struct S_or_D_array< Containee, Dimension_tag< D >, WithCompactContainerHelper >
+: public array<Containee, D>
+{
+ typedef array<Containee, D> Base;
+ S_or_D_array(const int)
+ : Base()
+ {}
+ S_or_D_array(const int, const Containee & c)
+ : Base()
+ {
+ assign(c);
+ }
+ void* for_compact_container() const
+ {
+ return (*this)[0].for_compact_container();
+ }
+ void* & for_compact_container()
+ {
+ return (*this)[0].for_compact_container();
+ }
+};
+
+// The case of dynamic size
+template< typename Containee >
+struct S_or_D_array< Containee, Dynamic_dimension_tag, false >
+: public std::vector<Containee>
+{
+ typedef std::vector<Containee> Base;
+ // TODO: maybe we should use some "small-vector-optimized" class.
+ S_or_D_array(const int d)
+ : Base(d)
+ {}
+ S_or_D_array(const int d, const Containee & c)
+ : Base(d, c)
+ {}
+};
+
+// The case of dynamic size with for_compact_container
+template< typename Containee >
+struct S_or_D_array< Containee, Dynamic_dimension_tag, true >
+: public std::vector<Containee>
+{
+ typedef std::vector<Containee> Base;
+ S_or_D_array(const int d)
+ : Base(d), fcc_(NULL)
+ {}
+ S_or_D_array(const int d, const Containee & c)
+ : Base(d, c), fcc_(NULL)
+ {}
+ void* fcc_;
+ void* for_compact_container() const { return fcc_; }
+ void* & for_compact_container() { return fcc_; }
+};
+
+} // end of namespace internal
+
+} // end of namespace CGAL
+
+#endif // CGAL_INTERNAL_STATIC_OR_DYNAMIC_ARRAY_H
diff --git a/include/gudhi_patches/CGAL/internal/Triangulation/Dummy_TDS.h b/include/gudhi_patches/CGAL/internal/Triangulation/Dummy_TDS.h
new file mode 100644
index 00000000..b3a0ec98
--- /dev/null
+++ b/include/gudhi_patches/CGAL/internal/Triangulation/Dummy_TDS.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_INTERNAL_TRIANGULATION_DUMMY_TDS_H
+#define CGAL_INTERNAL_TRIANGULATION_DUMMY_TDS_H
+
+namespace CGAL {
+
+namespace internal {
+namespace Triangulation {
+
+struct Dummy_TDS
+{
+ struct Vertex {};
+ struct Vertex_handle {};
+ struct Vertex_iterator {};
+ struct Vertex_const_handle {};
+ struct Vertex_const_iterator {};
+ struct Full_cell {};
+ struct Full_cell_handle {};
+ struct Full_cell_iterator {};
+ struct Full_cell_const_handle {};
+ struct Full_cell_const_iterator {};
+ struct Vertex_handle_const_iterator {};
+ struct Full_cell_data {};
+};
+
+} // namespace Triangulation
+} // namespace internal
+
+} //namespace CGAL
+
+#endif // CGAL_INTERNAL_TRIANGULATION_DUMMY_TDS_H
diff --git a/include/gudhi_patches/CGAL/internal/Triangulation/Triangulation_ds_iterators.h b/include/gudhi_patches/CGAL/internal/Triangulation/Triangulation_ds_iterators.h
new file mode 100644
index 00000000..7e360026
--- /dev/null
+++ b/include/gudhi_patches/CGAL/internal/Triangulation/Triangulation_ds_iterators.h
@@ -0,0 +1,154 @@
+// Copyright (c) 2009-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) : Samuel Hornus (Well... `copy, paste and hack' of Monique Teillaud's work)
+
+#ifndef CGAL_INTERNAL_TRIANGULATION_TRIANGULATION_DS_ITERATORS_H
+#define CGAL_INTERNAL_TRIANGULATION_TRIANGULATION_DS_ITERATORS_H
+
+namespace CGAL {
+
+namespace internal {
+namespace Triangulation {
+
+template< typename TDS >
+class Triangulation_ds_facet_iterator
+{
+ typedef typename TDS::Full_cell_handle Full_cell_handle;
+ typedef typename TDS::Facet Facet;
+
+ typedef Facet value_type;
+ typedef const Facet * pointer;
+ typedef const Facet & reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ typedef Triangulation_ds_facet_iterator<TDS> Facet_iterator;
+
+ TDS & tds_;
+ Facet ft_;
+ const int cur_dim_;
+
+public:
+ Triangulation_ds_facet_iterator(TDS & tds)
+ : tds_(tds), ft_(tds.full_cells_begin(), 0), cur_dim_(tds.current_dimension())
+ {
+ CGAL_assertion( cur_dim_ > 0 );
+ while( ! canonical() )
+ raw_increment();
+ }
+
+ Triangulation_ds_facet_iterator(TDS & tds, int)
+ : tds_(tds), ft_(tds.full_cells_end(), 0), cur_dim_(tds.current_dimension())
+ {
+ CGAL_assertion( cur_dim_ > 0 );
+ CGAL_assertion( canonical() );
+ }
+
+ Facet_iterator & operator++()
+ {
+ increment();
+ return (*this);
+ }
+
+ Facet_iterator operator++(int)
+ {
+ Facet_iterator tmp(*this);
+ increment();
+ return tmp;
+ }
+
+ Facet_iterator & operator--()
+ {
+ decrement();
+ return (*this);
+ }
+
+ Facet_iterator operator--(int)
+ {
+ Facet_iterator tmp(*this);
+ decrement();
+ return tmp;
+ }
+
+ bool operator==(const Facet_iterator & fi) const
+ {
+ return (&tds_ == &fi.tds_) &&
+ (tds_.index_of_covertex(ft_) == fi.tds_.index_of_covertex(fi.ft_)) &&
+ (tds_.full_cell(ft_) == fi.tds_.full_cell(fi.ft_));
+ }
+
+ bool operator!=(const Facet_iterator & fi) const
+ {
+ return !(*this == fi);
+ }
+
+ reference operator*() const
+ {
+ return ft_;
+ }
+
+ pointer operator->() const
+ {
+ return &ft_;
+ }
+
+private:
+ bool canonical()
+ {
+ if( tds_.full_cells_end() == tds_.full_cell(ft_) )
+ return ( 0 == tds_.index_of_covertex(ft_) );
+ return ( tds_.full_cell(ft_) <
+ tds_.full_cell(ft_)->neighbor(tds_.index_of_covertex(ft_)) );
+ }
+
+ void raw_decrement()
+ {
+ int i = tds_.index_of_covertex(ft_);
+ if( i == 0 )
+ ft_ = Facet(--tds_.full_cell(ft_), cur_dim_);
+ else
+ ft_ = Facet(tds_.full_cell(ft_), i - 1);
+ }
+
+ void raw_increment()
+ {
+ int i = tds_.index_of_covertex(ft_);
+ if( i == cur_dim_ )
+ ft_ = Facet(++tds_.full_cell(ft_), 0);
+ else
+ ft_ = Facet(tds_.full_cell(ft_), i + 1);
+ }
+
+ void decrement()
+ {
+ do { raw_decrement(); } while( ! canonical() );
+ }
+
+ void increment()
+ {
+ do { raw_increment(); } while( ! canonical() );
+ }
+};
+
+} // namespace Triangulation
+} // namespace internal
+
+} //namespace CGAL
+
+#endif // CGAL_INTERNAL_TRIANGULATION_TRIANGULATION_DS_ITERATORS_H
diff --git a/include/gudhi_patches/CGAL/internal/Triangulation/utilities.h b/include/gudhi_patches/CGAL/internal/Triangulation/utilities.h
new file mode 100644
index 00000000..a1ffc775
--- /dev/null
+++ b/include/gudhi_patches/CGAL/internal/Triangulation/utilities.h
@@ -0,0 +1,154 @@
+// Copyright (c) 2009-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) : Samuel Hornus
+
+#ifndef CGAL_INTERNAL_TRIANGULATION_UTILITIES_H
+#define CGAL_INTERNAL_TRIANGULATION_UTILITIES_H
+
+#include <CGAL/basic.h>
+
+namespace CGAL {
+
+namespace internal {
+namespace Triangulation {
+
+template< class TDS >
+struct Dark_full_cell_data
+{
+ typedef typename TDS::Full_cell_handle Full_cell_handle;
+ Full_cell_handle light_copy_;
+ int count_;
+ Dark_full_cell_data() : light_copy_(), count_(0) {}
+};
+
+template< class TDS >
+struct Compare_faces_with_common_first_vertex
+{
+ typedef typename TDS::Face Face;
+
+ const int d_;
+
+public:
+
+ Compare_faces_with_common_first_vertex(const int d)
+ : d_(d)
+ {
+ CGAL_assertion( 0 < d );
+ }
+
+ explicit Compare_faces_with_common_first_vertex();
+
+ bool operator()(const Face & left, const Face & right) const
+ {
+ CGAL_assertion( d_ == left.face_dimension() );
+ CGAL_assertion( d_ == right.face_dimension() );
+ for( int i = 1; i <= d_; ++i )
+ {
+ if( left.vertex(i) < right.vertex(i) )
+ return true;
+ if( right.vertex(i) < left.vertex(i) )
+ return false;
+ }
+ return false;
+ }
+};
+
+template< class T >
+struct Compare_vertices_for_upper_face
+{
+ typedef typename T::Vertex_const_handle VCH;
+
+ const T & t_;
+
+public:
+
+ Compare_vertices_for_upper_face(const T & t)
+ : t_(t)
+ {}
+
+ explicit Compare_vertices_for_upper_face();
+
+ bool operator()(const VCH & left, const VCH & right) const
+ {
+ if( left == right )
+ return false;
+ if( t_.is_infinite(left) )
+ return true;
+ if( t_.is_infinite(right) )
+ return false;
+ return left < right;
+ }
+};
+
+template< class T >
+struct Compare_points_for_perturbation
+{
+ typedef typename T::Geom_traits::Point_d Point;
+
+ const T & t_;
+
+public:
+
+ Compare_points_for_perturbation(const T & t)
+ : t_(t)
+ {}
+
+ explicit Compare_points_for_perturbation();
+
+ bool operator()(const Point * left, const Point * right) const
+ {
+ return (SMALLER == t_.geom_traits().compare_lexicographically_d_object()(*left, *right));
+ }
+};
+
+template< class T >
+struct Point_from_pointer
+{
+ typedef const typename T::Geom_traits::Point_d * argument_type;
+ typedef const typename T::Geom_traits::Point_d result_type;
+ result_type & operator()(argument_type & x) const
+ {
+ return (*x);
+ }
+ const result_type & operator()(const argument_type & x) const
+ {
+ return (*x);
+ }
+};
+
+template< typename Vertex_handle, typename Point >
+struct Point_from_vertex_handle
+{
+ typedef Vertex_handle argument_type;
+ typedef Point result_type;
+ result_type & operator()(argument_type & x) const
+ {
+ return x->point();
+ }
+ const result_type & operator()(const argument_type & x) const
+ {
+ return x->point();
+ }
+};
+
+} // namespace Triangulation
+} // namespace internal
+
+} //namespace CGAL
+
+#endif // CGAL_INTERNAL_TRIANGULATION_UTILITIES_H
diff --git a/include/gudhi_patches/CGAL/iterator_from_indices.h b/include/gudhi_patches/CGAL/iterator_from_indices.h
new file mode 100644
index 00000000..110bb4be
--- /dev/null
+++ b/include/gudhi_patches/CGAL/iterator_from_indices.h
@@ -0,0 +1,75 @@
+// 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_ITERATOR_FROM_INDICES_H
+#define CGAL_ITERATOR_FROM_INDICES_H
+#include <CGAL/config.h>
+#include <boost/iterator/iterator_facade.hpp>
+namespace CGAL {
+template <class Ref_>
+struct Default_coordinate_access {
+ typedef Ref_ result_type;
+ template<class T> Ref_ operator()(T const& t, std::ptrdiff_t i)const{
+ return t[i];
+ }
+};
+
+//TODO: default type for Value_: typename same_cv<Container_,typename remove_cv<Container_>::type::value_type>::type
+template <class Container_, class Value_, class Ref_=
+#ifdef CGAL_CXX11
+ decltype(std::declval<Container_>()[0])
+#else
+ Value_&
+#endif
+ , class Coord_access = Default_coordinate_access<Ref_>
+ >
+class Iterator_from_indices
+: public boost::iterator_facade<Iterator_from_indices<Container_,Value_,Ref_,Coord_access>,
+ Value_, std::bidirectional_iterator_tag, Ref_>
+{
+ friend class boost::iterator_core_access;
+ //FIXME: use int to save space
+ //TODO: use a tuple to save space when Coord_access is empty
+ typedef std::ptrdiff_t index_t;
+ Container_* cont;
+ index_t index;
+ Coord_access ca;
+ void increment(){ ++index; }
+ void decrement(){ --index; }
+ void advance(std::ptrdiff_t n){ index+=n; }
+ ptrdiff_t distance_to(Iterator_from_indices const& other)const{
+ return other.index-index;
+ }
+ bool equal(Iterator_from_indices const& other)const{
+ return index==other.index;
+ }
+ Ref_ dereference()const{
+ //FIXME: use the functor properly
+ //Uh, and what did I mean by that?
+ return ca(*cont,index);
+ }
+ public:
+ Iterator_from_indices(Container_& cont_,std::size_t n)
+ : cont(&cont_), index(n) {}
+ template<class T>
+ Iterator_from_indices(Container_& cont_,std::size_t n,T const&t)
+ : cont(&cont_), index(n), ca(t) {}
+};
+}
+#endif // CGAL_ITERATOR_FROM_INDICES_H
diff --git a/include/gudhi_patches/CGAL/transforming_iterator.h b/include/gudhi_patches/CGAL/transforming_iterator.h
new file mode 100644
index 00000000..15ea19a5
--- /dev/null
+++ b/include/gudhi_patches/CGAL/transforming_iterator.h
@@ -0,0 +1,123 @@
+// 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_TRANSFORMING_ITERATOR_H
+#define CGAL_TRANSFORMING_ITERATOR_H
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/is_empty.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+#include <CGAL/Default.h>
+#include <utility>
+
+// Inspired by the boost version, but more compact and
+// without any iterator_category games.
+
+namespace CGAL {
+namespace internal {
+
+// non-empty case
+template<class T,bool=boost::is_empty<T>::value> struct Functor_as_base {
+ Functor_as_base(){}
+ Functor_as_base(T const& t):f(t){}
+ //template<class T2> Functor_as_base(Functor_as_base<T2> const&g):f(g.functor()){}
+ T const& functor()const{return f;}
+ T & functor() {return f;}
+ private:
+ T f;
+};
+
+// empty case
+template<class T> struct Functor_as_base<T,true> : public T {
+ Functor_as_base(){}
+ Functor_as_base(T const& t):T(t){}
+ //template<class T2> Functor_as_base(Functor_as_base<T2> const&g):T(g.functor()){}
+ T const& functor()const{return *this;}
+ T & functor() {return *this;}
+};
+
+template <typename Derived, typename F, typename Iter, typename Ref, typename Val>
+class transforming_iterator_helper
+{
+ typedef std::iterator_traits<Iter> Iter_traits;
+ typedef typename Iter_traits::reference Iter_ref;
+ typedef typename Default::Get<Ref,
+#ifdef CGAL_CXX11
+ decltype(std::declval<F>()(std::declval<Iter_ref>()))
+#else
+ typename boost::result_of<F(typename Iter_traits::value_type)>::type
+ // should be reference instead of value_type
+#endif
+ >::type reference_;
+
+ typedef typename Default::Get<Val,typename boost::remove_cv<typename boost::remove_reference<reference_>::type>::type>::type value_type;
+
+ // Crappy heuristic. If we have *it that returns a Weighted_point and F that returns a reference to the Point contained in the Weighted_point it takes as argument, we do NOT want the transformed iterator to return a reference to the temporary *it. On the other hand, if *it returns an int n, and F returns a reference to array[n] it is not so good to lose the reference. This probably should be done elsewhere and should at least be made optional...
+ typedef typename boost::mpl::if_<
+ boost::mpl::or_<boost::is_reference<Iter_ref>,
+ boost::is_integral<Iter_ref> >,
+ reference_, value_type>::type reference;
+
+ public:
+ typedef boost::iterator_adaptor<
+ Derived,
+ Iter,
+ value_type,
+ typename Iter_traits::iterator_category,
+ reference
+ > type;
+};
+}
+
+template <typename F, typename Iter, typename Ref=Default, typename Val=Default>
+class transforming_iterator
+: public internal::transforming_iterator_helper<transforming_iterator<F,Iter,Ref,Val>,F,Iter,Ref,Val>::type,
+private internal::Functor_as_base<F>
+{
+ friend class boost::iterator_core_access;
+ typedef typename internal::transforming_iterator_helper<transforming_iterator,F,Iter,Ref,Val>::type Base;
+ typedef internal::Functor_as_base<F> Functor_base;
+ typename Base::reference dereference()const{
+ return functor()(*this->base_reference());
+ }
+ public:
+ using Functor_base::functor;
+ transforming_iterator(){}
+ explicit transforming_iterator(Iter i,F const& f=F())
+ :Base(i),Functor_base(f){}
+ template<class F2,class I2,class R2,class V2>
+ transforming_iterator(
+ transforming_iterator<F2,I2,R2,V2> const&i,
+ typename boost::enable_if_convertible<I2, Iter>::type* = 0,
+ typename boost::enable_if_convertible<F2, F>::type* = 0)
+ : Base(i.base()),Functor_base(i.functor()) {}
+
+};
+
+template <typename F, typename Iter> inline
+transforming_iterator<F,Iter> make_transforming_iterator(Iter i, F const&f=F()) {
+ return transforming_iterator<F,Iter>(i,f);
+}
+
+}
+
+#endif // CGAL_TRANSFORMING_ITERATOR_H
diff --git a/include/gudhi_patches/CGAL/transforming_pair_iterator.h b/include/gudhi_patches/CGAL/transforming_pair_iterator.h
new file mode 100644
index 00000000..48dac132
--- /dev/null
+++ b/include/gudhi_patches/CGAL/transforming_pair_iterator.h
@@ -0,0 +1,127 @@
+// 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_TRANSFORMING_PAIR_ITERATOR_H
+#define CGAL_TRANSFORMING_PAIR_ITERATOR_H
+// Should be a combination of transform_iterator and zip_iterator,
+// but boost's iterator_category games are a pain.
+
+#include <CGAL/transforming_iterator.h>
+#include <CGAL/assertions.h>
+#include <boost/type_traits/is_convertible.hpp>
+
+
+
+
+namespace CGAL {
+namespace internal {
+template <class Cat1, class Cat2, bool=boost::is_convertible<Cat1,Cat2>::value>
+struct Min_category {
+ CGAL_static_assertion((boost::is_convertible<Cat2,Cat1>::value));
+ typedef Cat1 type;
+};
+
+template <class Cat1, class Cat2>
+struct Min_category<Cat1,Cat2,true> {
+ typedef Cat2 type;
+};
+
+
+template <typename Derived, typename F, typename It1, typename It2, typename Ref, typename Val>
+class transforming_pair_iterator_helper
+{
+ typedef typename Min_category<
+ typename std::iterator_traits<It1>::iterator_category,
+ typename std::iterator_traits<It1>::iterator_category>
+ ::type iterator_category;
+
+ typedef typename Default::Get<Ref,
+#ifdef CGAL_CXX11
+ decltype(std::declval<F>()(std::declval<typename std::iterator_traits<It1>::reference>(),std::declval<typename std::iterator_traits<It2>::reference>()))
+#else
+ typename boost::result_of<F(typename std::iterator_traits<It1>::value_type,typename std::iterator_traits<It2>::value_type)>::type
+ // should be reference instead of value_type
+#endif
+ >::type reference;
+
+ typedef typename Default::Get<Val,typename boost::remove_cv<typename boost::remove_reference<reference>::type>::type>::type value_type;
+
+ public:
+ typedef boost::iterator_facade<
+ Derived,
+ value_type,
+ iterator_category,
+ reference
+ // expect ptrdiff_t is good enough for difference
+ > type;
+};
+}
+
+template <typename F, typename It1, typename It2, typename Ref=Default, typename Val=Default>
+class transforming_pair_iterator
+: public internal::transforming_pair_iterator_helper<transforming_pair_iterator<F,It1,It2,Ref,Val>,F,It1,It2,Ref,Val>::type,
+private internal::Functor_as_base<F>
+{
+ It1 iter1; It2 iter2;
+ friend class boost::iterator_core_access;
+ typedef typename internal::transforming_pair_iterator_helper<transforming_pair_iterator,F,It1,It2,Ref,Val>::type Base;
+ typedef internal::Functor_as_base<F> Functor_base;
+ typename Base::reference dereference()const{
+ return functor()(*iter1,*iter2);
+ }
+ bool equal(transforming_pair_iterator const&i)const{
+ bool b=(iter1==i.iter1);
+ CGAL_assertion(b==(iter2==i.iter2));
+ //FIXME: or do we want only one driving iterator
+ return b;
+ }
+ void increment(){ ++iter1; ++iter2; }
+ void decrement(){ --iter1; --iter2; }
+ void advance(std::ptrdiff_t n){
+ std::advance(iter1,n);
+ std::advance(iter2,n);
+ }
+ std::ptrdiff_t distance_to(transforming_pair_iterator const&i)const{
+ std::ptrdiff_t dist=std::distance(iter1,i.iter1);
+ CGAL_assertion(dist==std::distance(iter2,i.iter2));
+ return dist;
+ }
+ public:
+ using Functor_base::functor;
+ transforming_pair_iterator(){}
+ explicit transforming_pair_iterator(It1 i1,It2 i2,F const& f=F())
+ :Functor_base(f),iter1(i1),iter2(i2){}
+ template<class F2,class J1,class J2,class R2,class V2>
+ transforming_pair_iterator(
+ transforming_pair_iterator<F2,J1,J2,R2,V2> const&i,
+ typename boost::enable_if_convertible<J1, It1>::type* = 0,
+ typename boost::enable_if_convertible<J2, It2>::type* = 0,
+ typename boost::enable_if_convertible<F2, F>::type* = 0)
+ : Functor_base(i.functor()),iter1(i.iter1),iter2(i.iter2) {}
+
+};
+
+template <typename F, typename It1, typename It2> inline
+transforming_pair_iterator<F,It1,It2> make_transforming_pair_iterator(It1 i1, It2 i2, F const&f=F()) {
+ return transforming_pair_iterator<F,It1,It2>(i1,i2,f);
+}
+
+}
+
+#endif // CGAL_TRANSFORMING_PAIR_ITERATOR_H
diff --git a/include/gudhi_patches/CGAL/typeset.h b/include/gudhi_patches/CGAL/typeset.h
new file mode 100644
index 00000000..d4e24281
--- /dev/null
+++ b/include/gudhi_patches/CGAL/typeset.h
@@ -0,0 +1,117 @@
+// 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_TYPESET_H
+#define CGAL_TYPESET_H
+#include <CGAL/config.h>
+#ifdef CGAL_CXX11
+#include <type_traits>
+#else
+#include <boost/type_traits.hpp>
+#endif
+
+// Sometimes using tuple just to list types is overkill (takes forever to
+// instantiate).
+
+namespace CGAL {
+#ifdef CGAL_CXX11
+ template<class...> struct typeset;
+ template<class H,class...U> struct typeset<H,U...> {
+ typedef H head;
+ typedef typeset<U...> tail;
+ typedef typeset type;
+ template<class X> using contains = typename
+ std::conditional<
+ std::is_same<H,X>::value,
+ std::true_type,
+ typename tail::template contains<X>
+ >::type;
+ template<class X> using add = typename
+ std::conditional<
+ contains<X>::value,
+ typeset<H,U...>,
+ typeset<H,U...,X>
+ >::type;
+ };
+ template<> struct typeset<> {
+ typedef typeset type;
+ template<class X> using contains = std::false_type;
+ template<class X> using add = typeset<X>;
+ };
+#else
+ template<class,class> struct typeset;
+ template<class H=void, class T=typename
+ boost::mpl::if_<boost::is_same<H,void>, void, typeset<void, void> >::type >
+ struct typeset {
+ typedef typeset type;
+ typedef H head;
+ typedef T tail;
+ template<class X> struct contains :
+ boost::mpl::if_<boost::is_same<H,X>,boost::true_type,typename tail::template contains<X> >::type
+ {};
+ template<class X,class=void> struct add;
+ //boost::mpl::if_<boost::is_same<H,X>,typeset,typeset<X,typeset> >::type
+ };
+ template<> struct typeset<> {
+ typedef typeset type;
+ template<class X> struct contains : boost::false_type {};
+ template<class X> struct add : CGAL::typeset<X> {};
+ };
+
+ template<class H,class T>
+ template<class X,class>
+ struct typeset<H,T>::add : typeset<H,typename T::template add<X>::type> {};
+ template<class H,class T>
+ template<class V>
+ struct typeset<H,T>::add<H,V> : typeset<H,T> {};
+#endif
+
+ template<class T1, class T2> struct typeset_union_ :
+ typeset_union_<typename T1::template add<typename T2::head>::type, typename T2::tail>
+ {};
+ template<class T> struct typeset_union_ <T, typeset<> > : T {};
+
+ template<class T1, class T2>
+ struct typeset_intersection_ {
+ typedef typename T1::head H;
+ typedef typename typeset_intersection_<typename T1::tail,T2>::type U;
+ typedef typename
+#ifdef CGAL_CXX11
+ std::conditional<T2::template contains<H>::value,
+#else
+ boost::mpl::if_<typename T2::template contains<H>,
+#endif
+ typename U::template add<H>::type, U>::type type;
+ };
+ template<class T>
+ struct typeset_intersection_<typeset<>,T> : typeset<> {};
+
+#ifdef CGAL_CXX11
+ template<class T1, class T2>
+ using typeset_union = typename typeset_union_<T1,T2>::type;
+ template<class T1, class T2>
+ using typeset_intersection = typename typeset_intersection_<T1,T2>::type;
+#else
+ template<class T1, class T2>
+ struct typeset_union : typeset_union_<T1,T2>::type {};
+ template<class T1, class T2>
+ struct typeset_intersection : typeset_intersection_<T1,T2>::type {};
+#endif
+}
+#endif
diff --git a/include/gudhi_patches/Tangential_complex_CGAL_patches.txt b/include/gudhi_patches/Tangential_complex_CGAL_patches.txt
new file mode 100644
index 00000000..5b9581a0
--- /dev/null
+++ b/include/gudhi_patches/Tangential_complex_CGAL_patches.txt
@@ -0,0 +1,82 @@
+CGAL/Regular_triangulation_traits_adapter.h
+CGAL/Triangulation_ds_vertex.h
+CGAL/Triangulation_data_structure.h
+CGAL/transforming_pair_iterator.h
+CGAL/NewKernel_d/static_int.h
+CGAL/NewKernel_d/Cartesian_LA_functors.h
+CGAL/NewKernel_d/Cartesian_change_FT.h
+CGAL/NewKernel_d/Wrapper/Vector_d.h
+CGAL/NewKernel_d/Wrapper/Hyperplane_d.h
+CGAL/NewKernel_d/Wrapper/Ref_count_obj.h
+CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h
+CGAL/NewKernel_d/Wrapper/Point_d.h
+CGAL/NewKernel_d/Wrapper/Segment_d.h
+CGAL/NewKernel_d/Wrapper/Weighted_point_d.h
+CGAL/NewKernel_d/Wrapper/Sphere_d.h
+CGAL/NewKernel_d/Cartesian_per_dimension.h
+CGAL/NewKernel_d/Kernel_object_converter.h
+CGAL/NewKernel_d/KernelD_converter.h
+CGAL/NewKernel_d/Vector/sse2.h
+CGAL/NewKernel_d/Vector/avx4.h
+CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h
+CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_points.h
+CGAL/NewKernel_d/Vector/determinant_of_points_from_vectors.h
+CGAL/NewKernel_d/Vector/array.h
+CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h
+CGAL/NewKernel_d/Vector/determinant_of_iterator_to_vectors_from_vectors.h
+CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim.h
+CGAL/NewKernel_d/Vector/vector.h
+CGAL/NewKernel_d/Vector/v2int.h
+CGAL/NewKernel_d/Vector/mix.h
+CGAL/NewKernel_d/Cartesian_static_filters.h
+CGAL/NewKernel_d/Cartesian_LA_base.h
+CGAL/NewKernel_d/Lazy_cartesian.h
+CGAL/NewKernel_d/Coaffine.h
+CGAL/NewKernel_d/store_kernel.h
+CGAL/NewKernel_d/Dimension_base.h
+CGAL/NewKernel_d/Kernel_3_interface.h
+CGAL/NewKernel_d/Cartesian_complete.h
+CGAL/NewKernel_d/Cartesian_base.h
+CGAL/NewKernel_d/Cartesian_filter_K.h
+CGAL/NewKernel_d/functor_tags.h
+CGAL/NewKernel_d/Filtered_predicate2.h
+CGAL/NewKernel_d/functor_properties.h
+CGAL/NewKernel_d/Define_kernel_types.h
+CGAL/NewKernel_d/LA_eigen/LA.h
+CGAL/NewKernel_d/LA_eigen/constructors.h
+CGAL/NewKernel_d/Types/Aff_transformation.h
+CGAL/NewKernel_d/Types/Sphere.h
+CGAL/NewKernel_d/Types/Hyperplane.h
+CGAL/NewKernel_d/Types/Line.h
+CGAL/NewKernel_d/Types/Ray.h
+CGAL/NewKernel_d/Types/Iso_box.h
+CGAL/NewKernel_d/Types/Weighted_point.h
+CGAL/NewKernel_d/Types/Segment.h
+CGAL/NewKernel_d/Kernel_d_interface.h
+CGAL/NewKernel_d/utils.h
+CGAL/NewKernel_d/Kernel_2_interface.h
+CGAL/NewKernel_d/Cartesian_filter_NT.h
+CGAL/NewKernel_d/function_objects_cartesian.h
+CGAL/Convex_hull.h
+CGAL/Triangulation_ds_full_cell.h
+CGAL/Regular_triangulation.h
+CGAL/Epick_d.h
+CGAL/transforming_iterator.h
+CGAL/iterator_from_indices.h
+CGAL/Delaunay_triangulation.h
+CGAL/IO/Triangulation_off_ostream.h
+CGAL/typeset.h
+CGAL/Triangulation_full_cell.h
+CGAL/Triangulation.h
+CGAL/internal/Static_or_dynamic_array.h
+CGAL/internal/Combination_enumerator.h
+CGAL/internal/Triangulation/utilities.h
+CGAL/internal/Triangulation/Triangulation_ds_iterators.h
+CGAL/internal/Triangulation/Dummy_TDS.h
+CGAL/argument_swaps.h
+CGAL/Epeck_d.h
+CGAL/determinant_of_vectors.h
+CGAL/TDS_full_cell_default_storage_policy.h
+CGAL/TDS_full_cell_mirror_storage_policy.h
+CGAL/Triangulation_face.h
+CGAL/Triangulation_vertex.h