diff --git a/NewKernel_d/include/CGAL/Epick_d.h b/NewKernel_d/include/CGAL/Epick_d.h index cf780630c56..6443853994f 100644 --- a/NewKernel_d/include/CGAL/Epick_d.h +++ b/NewKernel_d/include/CGAL/Epick_d.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace CGAL { diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_base.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_base.h index 28893d64830..80ee4b33580 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_base.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_base.h @@ -87,6 +87,7 @@ struct Cartesian_LA_base_d : public Dimension_base ::add::type ::add::type ::add::type + ::add::type Object_list; typedef typeset< Point_cartesian_const_iterator_tag>::type diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h index 68acdd27001..9767f2f2e6b 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h @@ -180,7 +180,7 @@ template struct Compute_cartesian_coordinate { #ifdef CGAL_CXX11 typedef decltype(std::declval()[0]) result_type; #else - typedef RT const& result_type; + typedef RT 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 diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h index 3f9804fecbe..403a0e4d68c 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h @@ -24,6 +24,7 @@ #include #include #include +#include namespace CGAL { @@ -45,6 +46,12 @@ struct Cartesian_filter_K : public Base_, typedef typename Store_kernel2::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, + internal::Do_not_store_kernel, + internal::Do_not_store_kernel > Do_not_store_kernel; + //TODO: C2A/C2E could be able to convert *this into this->kernel() or this->kernel2(). typedef KernelD_converter C2A; typedef KernelD_converter C2E; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Coaffine.h b/NewKernel_d/include/CGAL/NewKernel_d/Coaffine.h index 1c2efe462d8..3a27eee90ff 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Coaffine.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Coaffine.h @@ -78,6 +78,10 @@ template struct Construct_flat_orientation : private Store_kernel // the points are affinely independent. template result_type operator()(Iter f, Iter e)const{ + /*std::cerr << "Kernel flat orientation - points: " ; // CJTODO DEBUG + for (Iter it = f ; it != e ; ++it) + std::cerr << (*it)[0] << " "; + std::cerr << std::endl; // CJTODO DEBUG*/ Iter f_save = f; PD pd (this->kernel()); CCC ccc (this->kernel()); @@ -89,6 +93,7 @@ template struct Construct_flat_orientation : private Store_kernel std::vector& rest=o.rest; rest.reserve(dim+1); for(int i=0; i wpoints; + + int dim_from_file; + in >> dim_from_file; + while(in >> wp) + wpoints.push_back(wp); + + // Build the Regular Triangulation + RT rt(dim_from_file); + rt.insert(wpoints.begin(), wpoints.end()); + CGAL_assertion(rt.is_valid(true)); + + // Export + std::stringstream output_filename; + output_filename << "data/rt_dim" << dim << ".off"; + std::ofstream off_stream(output_filename.str()); + CGAL::export_triangulation_to_off(off_stream, rt); +} + +int main() +{ + test(2); + test(3); + return 0; +} diff --git a/Triangulation/benchmark/Triangulation/delaunay.cpp b/Triangulation/benchmark/Triangulation/delaunay.cpp index ea6c160c807..7d1a5b379ee 100644 --- a/Triangulation/benchmark/Triangulation/delaunay.cpp +++ b/Triangulation/benchmark/Triangulation/delaunay.cpp @@ -65,6 +65,5 @@ int main(int argc, char **argv) go<7>(N); go<8>(N); - return 0; } diff --git a/Triangulation/dont_submit b/Triangulation/dont_submit index f5c7a0a6d72..b2de9879971 100644 --- a/Triangulation/dont_submit +++ b/Triangulation/dont_submit @@ -1,3 +1,2 @@ TODO include/CGAL/Convex_hull.h -include/CGAL/Regular_triangulation.h diff --git a/Triangulation/include/CGAL/Delaunay_triangulation.h b/Triangulation/include/CGAL/Delaunay_triangulation.h index dbe9950a7aa..2397f0c8c42 100644 --- a/Triangulation/include/CGAL/Delaunay_triangulation.h +++ b/Triangulation/include/CGAL/Delaunay_triangulation.h @@ -55,7 +55,7 @@ class Delaunay_triangulation public: // PUBLIC NESTED TYPES typedef DCTraits Geom_traits; - typedef typename Base::Triangulation_ds Triangulation_ds; + typedef typename Base::Triangulation_ds Triangulation_ds; typedef typename Base::Vertex Vertex; typedef typename Base::Full_cell Full_cell; @@ -71,21 +71,25 @@ public: // PUBLIC NESTED TYPES 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::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::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; @@ -95,11 +99,12 @@ public: //using Base::incident_full_cells; 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::insert_outside_convex_hull_1; using Base::is_infinite; - using Base::is_valid; using Base::locate; using Base::points_begin; using Base::set_neighbors; @@ -142,32 +147,6 @@ private: } }; public: - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 Rotor; - 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 = full_cell(r)->mirror_index(index_of_covertex(r)); - Full_cell_handle s = full_cell(r)->neighbor(index_of_covertex(r)); - int new_second = s->index(full_cell(r)->vertex(index_of_second_covertex(r))); - return Rotor(s, new_second, opposite); - } // - - - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS @@ -339,6 +318,10 @@ public: 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 @@ -352,27 +335,6 @@ private: Conflict_traversal_pred_in_subspace; typedef Conflict_traversal_predicate Conflict_traversal_pred_in_fullspace; - - // 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 - { - typedef std::vector 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) ); - } - }; }; // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = @@ -427,7 +389,7 @@ Delaunay_triangulation // THE CASE cur_dim >= 2 // Gather the finite vertices sharing an edge with |v| - typedef Full_cell_set Simplices; + typedef typename Base::template Full_cell_set Simplices; Simplices simps; std::back_insert_iterator out(simps); tds().incident_full_cells(v, out); @@ -563,7 +525,7 @@ Delaunay_triangulation Dark_s_handle dark_ret_s = dark_s; Full_cell_handle ret_s; - typedef Full_cell_set Dark_full_cells; + typedef typename Base::template Full_cell_set Dark_full_cells; Dark_full_cells conflict_zone; std::back_insert_iterator dark_out(conflict_zone); @@ -777,7 +739,6 @@ Delaunay_triangulation ::insert_in_conflicting_cell(const Point & p, const Full_cell_handle s) { typedef std::vector Full_cell_h_vector; - typedef typename Full_cell_h_vector::iterator SHV_iterator; static Full_cell_h_vector cs; // for storing conflicting full_cells. cs.clear(); // cs.reserve(64); @@ -888,6 +849,48 @@ Delaunay_triangulation } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY + +template< typename DCTraits, typename TDS > +bool +Delaunay_triangulation +::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)) + { + 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/Triangulation/include/CGAL/IO/Triangulation_off_ostream.h b/Triangulation/include/CGAL/IO/Triangulation_off_ostream.h new file mode 100644 index 00000000000..590c2a6b0e6 --- /dev/null +++ b/Triangulation/include/CGAL/IO/Triangulation_off_ostream.h @@ -0,0 +1,255 @@ +// 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 +#include +#include +#include + +namespace CGAL { + +namespace Triangulation_IO +{ +// TODO: test if the stream is binary or text? +template +void +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)); + } +} + +// TODO: test if the stream is binary or text? +/*template +void +input_point(std::istream & is, const Traits &traits, P & p) +{ + typedef typename Traits::FT FT; + std::vector 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 +std::istream & +operator>>(std::istream &is, typename Wrap::Point_d & p) +{ + typedef typename Wrap::Point_d P; + typedef typename K::FT FT; + std::vector 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 +std::istream & +operator>>(std::istream &is, typename Wrap::Weighted_point_d & wp) +{ + typedef typename Wrap::Point_d P; + typedef typename Wrap::Weighted_point_d 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 coords; + while (line_sstr >> temp) + coords.push_back(temp); + + std::vector::iterator last = coords.end() - 1; + P p = P(coords.begin(), last); + wp = WP(p, *last); + + return is; +} + +template < class GT, class TDS > +std::ostream & +export_triangulation_to_off(std::ostream & os, + const Triangulation & tr, + bool in_3D_export_surface_only = false) +{ + typedef Triangulation Tr; + typedef typename Tr::Vertex_const_handle Vertex_handle; + typedef typename Tr::Vertex_const_iterator Vertex_iterator; + typedef typename Tr::Finite_vertex_const_iterator Finite_vertex_iterator; + typedef typename Tr::Full_cell_const_handle Full_cell_handle; + 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 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/Triangulation/include/CGAL/Regular_triangulation.h b/Triangulation/include/CGAL/Regular_triangulation.h index afc9455c1f8..82c49704516 100644 --- a/Triangulation/include/CGAL/Regular_triangulation.h +++ b/Triangulation/include/CGAL/Regular_triangulation.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 INRIA Sophia-Antipolis (France). +// Copyright (c) 2014 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). @@ -15,7 +15,7 @@ // $URL$ // $Id$ // -// Author(s) : Samuel Hornus +// Author(s) : Clement Jamin #ifndef CGAL_REGULAR_TRIANGULATION_H #define CGAL_REGULAR_TRIANGULATION_H @@ -28,27 +28,909 @@ namespace CGAL { template< typename RTTraits, typename TDS_ = Default > class Regular_triangulation -: public Triangulation::type, - Triangulation_vertex, - Triangulation_full_cell > - >::type > +: public Triangulation< + RTTraits, + typename Default::Get, + Triangulation_full_cell > + >::type > { - typedef typename Maximal_dimension::type - Maximal_dimension_; - typedef typename Default::Get, - Triangulation_full_cell > - >::type TDS; - typedef Triangulation Base; - typedef Regular_triangulation Self; + typedef typename RTTraits::Dimension Maximal_dimension_; + typedef typename Default::Get< + TDS_, + Triangulation_data_structure< + Maximal_dimension_, + Triangulation_vertex, + Triangulation_full_cell + > >::type TDS; + typedef Triangulation Base; + typedef Regular_triangulation Self; + + typedef typename RTTraits::Orientation_d Orientation_d; + typedef typename RTTraits::Construct_weighted_point_d Construct_weighted_point_d; + typedef typename RTTraits::Power_test_d Power_test_d; + typedef typename RTTraits::In_flat_power_test_d In_flat_power_test_d; + typedef typename RTTraits::Flat_orientation_d Flat_orientation_d; + typedef typename RTTraits::Construct_flat_orientation_d Construct_flat_orientation_d; + typedef typename RTTraits::In_flat_orientation_d In_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 Bare_point; + typedef typename RTTraits::Weighted_point 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: - typedef Maximal_dimension_ Maximal_dimension; -}; + + 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::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; + +private: + //*** Power_test_in_flat_d *** CJTODO: better name? + // Wrapper + struct Power_test_in_flat_d + { + boost::optional* fop; + Construct_flat_orientation_d cfo; + In_flat_power_test_d ifpt; + + Power_test_in_flat_d( + boost::optional& x, + Construct_flat_orientation_d const&y, + In_flat_power_test_d const&z) + : fop(&x), cfo(y), ifpt(z) {} + + template + 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 &preset_flat_orientation, + const Geom_traits k = Geom_traits()) + : Base(dim, preset_flat_orientation, k) + { + } + + ~Regular_triangulation() {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ACCESS + + // Not Documented + Power_test_in_flat_d power_test_in_flat_predicate() const + { + return Power_test_in_flat_d ( + flat_orientation_, + geom_traits().construct_flat_orientation_d_object(), + geom_traits().in_flat_power_test_d_object() + ); + } + + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS + + 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 > + size_type insert(ForwardIterator start, ForwardIterator end) + { + size_type n = number_of_vertices(); + typedef std::vector WP_vec; + WP_vec points(start, end); + typename Geom_traits::Point_drop_weight_d pdw = + geom_traits().point_drop_weight_d_object(); + spatial_sort( + boost::make_transform_iterator(points.begin(), pdw), + boost::make_transform_iterator(points.end(), pdw), + typename Geom_traits::Base()); + //spatial_sort(points.begin(), points.end(), geom_traits()); // CJTODO TEMP A REMETTRE + //spatial_sort(points.begin(), points.end(), Geom_traits::Base()); + 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 &, + const Locate_type, + const Face &, + const Facet &, + const Full_cell_handle); + + Vertex_handle insert(const Weighted_point & p, + const 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, const 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 &, const Full_cell_handle); + +// - - - - - - - - - - - - - - - - - - - - - - - - - GATHERING CONFLICTING SIMPLICES + + bool is_in_conflict(const Weighted_point &, Full_cell_const_handle) const; + + template< class OrientationPredicate > + Oriented_side perturbed_power_test(const Weighted_point &, + Full_cell_const_handle, const OrientationPredicate &) const; + + template< typename OutputIterator > + Facet compute_conflict_zone(const Weighted_point &, const Full_cell_handle, OutputIterator) const; + + template < typename OrientationPredicate, typename PowerTestPredicate > + class Conflict_predicate + { + const Self & rt_; + const Weighted_point & p_; + OrientationPredicate ori_; + PowerTestPredicate power_test_; + int cur_dim_; + public: + Conflict_predicate( + const Self & rt, + const Weighted_point & p, + const OrientationPredicate & ori, + const PowerTestPredicate & power_test) + : rt_(rt), p_(p), ori_(ori), power_test_(power_test), cur_dim_(rt.current_dimension()) {} + + inline + bool operator()(Full_cell_const_handle s) const + { + bool ok; + if( ! rt_.is_infinite(s) ) + { + Oriented_side power_test = power_test_(rt_.points_begin(s), rt_.points_begin(s) + cur_dim_ + 1, p_); + if( ON_POSITIVE_SIDE == power_test ) + ok = true; + else if( ON_NEGATIVE_SIDE == power_test ) + ok = false; + else + ok = ON_POSITIVE_SIDE == rt_.perturbed_power_test(p_, s, ori_); + } + else + { + typedef typename Full_cell::Vertex_handle_const_iterator VHCI; + typedef Substitute_point_in_vertex_iterator 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; + +private: + // Some internal types to shorten notation + using typename Base::Coaffine_orientation_d; + using Base::flat_orientation_; + typedef Conflict_predicate + Conflict_pred_in_subspace; + typedef Conflict_predicate + Conflict_pred_in_fullspace; + typedef Conflict_traversal_predicate + Conflict_traversal_pred_in_subspace; + typedef Conflict_traversal_predicate + Conflict_traversal_pred_in_fullspace; +}; // class Regular_triangulation + + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +// FUNCTIONS THAT ARE MEMBER METHODS: + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS + +template< typename RTTraits, typename TDS > +typename Regular_triangulation::Full_cell_handle +Regular_triangulation +::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( is_infinite(left) && left->neighbor(0)->index(left) == 0 ) // we are on the infinite right. + left = left->neighbor(0); + if( 0 == left->index(v) ) + left = left->neighbor(1); + CGAL_assertion( 1 == left->index(v) ); + Full_cell_handle right = left->neighbor(0); + if( ! is_infinite(right) ) + { + tds().associate_vertex_with_full_cell(left, 1, right->vertex(1)); + set_neighbors(left, 0, right->neighbor(0), right->mirror_index(0)); + } + else + { + tds().associate_vertex_with_full_cell(left, 1, left->vertex(0)); + tds().associate_vertex_with_full_cell(left, 0, infinite_vertex()); + set_neighbors(left, 0, left->neighbor(1), left->mirror_index(1)); + set_neighbors(left, 1, right->neighbor(1), right->mirror_index(1)); + } + 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 Simplices; + Simplices simps; + std::back_insert_iterator out(simps); + tds().incident_full_cells(v, out); + typedef std::set 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 Dark_vertex_base; + typedef Triangulation_full_cell< + Geom_traits, + internal::Triangulation::Dark_full_cell_data > Dark_full_cell_base; + typedef Triangulation_data_structure Dark_tds; + typedef Regular_triangulation 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(current_dimension(), flat_orientation_.get_ptr()) + : std::pair(std::numeric_limits::max(), NULL) ); + + Dark_s_handle dark_s; + Dark_v_handle dark_v; + typedef std::map 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()); + if( v_idx != 0 ) + { + // we must put the infinite vertex at index 0. + // OK, now with the new convention that the infinite vertex + // does not have to be at index 0, this is not necessary, + // but still, I prefer to keep this piece of code here. [-- Samuel Hornus] + (*it)->swap_vertices(0, v_idx); + // Now, we preserve the positive orientation of the full_cell + (*it)->swap_vertices(current_dimension() - 1, current_dimension()); + } + } + // 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 = 1; i <= current_dimension(); ++i ) + { + (*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_full_cells; + Dark_full_cells conflict_zone; + std::back_insert_iterator 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 > 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 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(full_cell(light_r)->neighbor(index_of_covertex(light_r))) ) + light_r = rotate_rotor(light_r); + + while( conflict_zone.contains(dark_side.full_cell(dark_r)->neighbor(dark_side.index_of_covertex(dark_r))) ) + dark_r = dark_side.rotate_rotor(dark_r); + + Dark_s_handle dark_ns = dark_side.full_cell(dark_r); + int dark_ni = dark_side.index_of_covertex(dark_r); + Full_cell_handle light_ns = full_cell(light_r); + int light_ni = index_of_covertex(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 RTTraits, typename TDS > +void +Regular_triangulation +::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() ) + { + // FIXME: infinite vertex is NOT at index 0 a priori. + Full_cell_handle s = infinite_vertex()->full_cell()->neighbor(0); + Orientation o = orientation(s); + CGAL_assertion( ZERO != o ); + if( NEGATIVE == o ) + reorient_full_cells(); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSERTIONS + +template< typename RTTraits, typename TDS > +typename Regular_triangulation::Vertex_handle +Regular_triangulation +::insert(const Weighted_point & p, const Locate_type lt, const Face & f, const Facet & ft, const 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; + } +} + +template< typename RTTraits, typename TDS > +typename Regular_triangulation::Vertex_handle +Regular_triangulation +::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 ) + { + // FIXME: infinite vertex is NOT at index 0 a priori. + Full_cell_handle s = infinite_vertex()->full_cell()->neighbor(0); + Orientation o = orientation(s); + CGAL_assertion( ZERO != o ); + if( NEGATIVE == o ) + reorient_full_cells(); + } + return v; +} + +template< typename RTTraits, typename TDS > +typename Regular_triangulation::Vertex_handle +Regular_triangulation +::insert_in_conflicting_cell(const Weighted_point & p, const Full_cell_handle s) +{ + typedef std::vector Full_cell_h_vector; + static Full_cell_h_vector cs; // for storing conflicting full_cells. + cs.clear(); + // cs.reserve(64); + std::back_insert_iterator 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 RTTraits, typename TDS > +template< typename OrientationPred > +Oriented_side +Regular_triangulation +::perturbed_power_test(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 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(*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, + 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 RTTraits, typename TDS > +bool +Regular_triangulation +::is_in_conflict(const Weighted_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(), + power_test_in_flat_predicate()); + return c(s); + } + else + { + Orientation_d ori = geom_traits().orientation_d_object(); + Power_test_d side = geom_traits().power_test_d_object(); + Conflict_pred_in_fullspace c(*this, p, ori, side); + return c(s); + } +} + +template< typename RTTraits, typename TDS > +template< typename OutputIterator > +typename Regular_triangulation::Facet +Regular_triangulation +::compute_conflict_zone(const Weighted_point & p, const 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(), + power_test_in_flat_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_test_d side = geom_traits().power_test_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 RTTraits, typename TDS > +bool +Regular_triangulation +::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_test_d side = + geom_traits().power_test_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 +#endif //CGAL_REGULAR_TRIANGULATION_H diff --git a/Triangulation/include/CGAL/Regular_triangulation_euclidean_traits.h b/Triangulation/include/CGAL/Regular_triangulation_euclidean_traits.h new file mode 100644 index 00000000000..6a4e993ae9a --- /dev/null +++ b/Triangulation/include/CGAL/Regular_triangulation_euclidean_traits.h @@ -0,0 +1,256 @@ +// 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_EUCLIDEAN_TRAITS_H +#define CGAL_REGULAR_TRIANGULATION_EUCLIDEAN_TRAITS_H + +#include +#include +#include +#include +#include + +#include + +namespace CGAL { + +template < class K, class Weight = typename K::RT > +class Regular_triangulation_euclidean_traits + : public K +{ +public: + typedef K Base; + typedef Regular_triangulation_euclidean_traits Self; + + // Types from K + + typedef K Kernel; + typedef typename K::Dimension Dimension; + typedef typename K::FT FT; + typedef typename K::Point_d Bare_point; + typedef typename K::Weighted_point_d Weighted_point; + typedef Weighted_point Weighted_point_d; + typedef Weighted_point Point_d; + + typedef typename K::Construct_weighted_point_d Construct_weighted_point_d; + typedef typename K::Power_test_d Power_test_d; + typedef typename K::In_flat_power_test_d In_flat_power_test_d; + typedef typename K::Flat_orientation_d Flat_orientation_d; + typedef typename K::Point_drop_weight_d Point_drop_weight_d; + + //============================================================================= + // Custom types + //============================================================================= + + class Orientation_d + { + const K &m_kernel; + + public: + typedef Orientation result_type; + + Orientation_d(const K &kernel) + : m_kernel(kernel) {} + + template + result_type operator()(ForwardIterator start, ForwardIterator end) const + { + Point_drop_weight_d pdw = m_kernel.point_drop_weight_d_object(); + return m_kernel.orientation_d_object() ( + boost::make_transform_iterator(start, pdw), + boost::make_transform_iterator(end, pdw) + ); + } + }; + + //============================================================================= + + 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 + result_type operator()(ForwardIterator start, ForwardIterator end) const + { + Point_drop_weight_d pdw = m_kernel.point_drop_weight_d_object(); + return m_kernel.construct_flat_orientation_d_object() ( + boost::make_transform_iterator(start, pdw), + boost::make_transform_iterator(end, pdw) + ); + } + }; + + + //============================================================================= + + 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 + result_type operator()(Flat_orientation_d orient, + ForwardIterator start, ForwardIterator end) const + { + Point_drop_weight_d pdw = m_kernel.point_drop_weight_d_object(); + return m_kernel.in_flat_orientation_d_object() ( + orient, + boost::make_transform_iterator(start, pdw), + boost::make_transform_iterator(end, pdw) + ); + } + }; + + //============================================================================= + + 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 + result_type operator()(ForwardIterator start, ForwardIterator end, + const Weighted_point_d & p) const + { + Point_drop_weight_d pdw = m_kernel.point_drop_weight_d_object(); + return m_kernel.contained_in_affine_hull_d_object() ( + boost::make_transform_iterator(start, pdw), + boost::make_transform_iterator(end, pdw), + pdw(p) + ); + } + }; + + //============================================================================= + + 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 + { + Point_drop_weight_d pdw = m_kernel.point_drop_weight_d_object(); + return m_kernel.compare_lexicographically_d_object()(pdw(p), pdw(q)); + } + }; + + //============================================================================= + + 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 + { + Point_drop_weight_d pdw = m_kernel.point_drop_weight_d_object(); + auto pp = pdw(p); + auto ddsd = m_kernel.compute_coordinate_d_object(); + ddsd(pp, i); + return m_kernel.compute_coordinate_d_object()(pdw(p), i); + } + }; + + //============================================================================= + + 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 + { + Point_drop_weight_d pdw = m_kernel.point_drop_weight_d_object(); + return m_kernel.point_dimension_d_object()(pdw(p)); + } + }; + + //============================================================================= + // Object creation + //============================================================================= + + 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_EUCLIDEAN_TRAITS_H diff --git a/Triangulation/include/CGAL/Triangulation.h b/Triangulation/include/CGAL/Triangulation.h index e1b7ca59daf..4874d8bea98 100644 --- a/Triangulation/include/CGAL/Triangulation.h +++ b/Triangulation/include/CGAL/Triangulation.h @@ -50,18 +50,18 @@ 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) + 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(); + if (vh == vh_where_point_should_be_substituted_) + return *subtitute_point_; + else + return vh->point(); } private: @@ -74,635 +74,683 @@ private: template < class TriangulationTraits, class TDS_ = Default > class Triangulation { - typedef typename TriangulationTraits::Dimension Maximal_dimension_; - typedef typename Default::Get, - Triangulation_full_cell > - >::type TDS; - typedef Triangulation Self; - + typedef typename TriangulationTraits::Dimension Maximal_dimension_; + typedef typename Default::Get, + Triangulation_full_cell > + >::type TDS; + typedef Triangulation 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; + 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* fop; + Construct_flat_orientation_d cfo; + In_flat_orientation_d ifo; + + Coaffine_orientation_d( + boost::optional& x, + Construct_flat_orientation_d const&y, + In_flat_orientation_d const&z) + : fop(&x), cfo(y), ifo(z) {} - // Wrapper - struct Coaffine_orientation_d + template + CGAL::Orientation operator()(Iter a, Iter b) const { - boost::optional* fop; - Construct_flat_orientation_d cfo; - In_flat_orientation_d ifo; - - Coaffine_orientation_d( - boost::optional& x, - Construct_flat_orientation_d const&y, - In_flat_orientation_d const&z) - : fop(&x), cfo(y), ifo(z) {} - - template - 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; + if (*fop) + return ifo(fop->get(),a,b); + *fop = cfo(a,b); + CGAL_assertion(ifo(fop->get(),a,b) == CGAL::POSITIVE); + return CGAL::POSITIVE; } + }; - typedef typename TriangulationTraits::Orientation_d - Orientation_d; + 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 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 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 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::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::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; + 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 - }; + /// 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 + // Finite elements iterators - class Finiteness_predicate; + class Finiteness_predicate; - typedef boost::filter_iterator - Finite_vertex_iterator; - typedef boost::filter_iterator - Finite_vertex_const_iterator; - typedef boost::filter_iterator - Finite_full_cell_iterator; - typedef boost::filter_iterator - Finite_full_cell_const_iterator; - typedef boost::filter_iterator - Finite_facet_iterator; + typedef boost::filter_iterator + Finite_vertex_iterator; + typedef boost::filter_iterator + Finite_vertex_const_iterator; + typedef boost::filter_iterator + Finite_full_cell_iterator; + typedef boost::filter_iterator + Finite_full_cell_const_iterator; + typedef boost::filter_iterator + Finite_facet_iterator; protected: // DATA MEMBERS - Triangulation_ds tds_; - const Geom_traits kernel_; - Vertex_handle infinity_; - mutable std::vector orientations_; - mutable boost::optional 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::max() otherwise) - std::pair preset_flat_orientation_; - // for stochastic walk in the locate() function: - mutable Random rng_; + Triangulation_ds tds_; + const Geom_traits kernel_; + Vertex_handle infinity_; + mutable std::vector orientations_; + mutable boost::optional 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::max() otherwise) + std::pair preset_flat_orientation_; + // for stochastic walk in the locate() function: + mutable Random rng_; #ifdef CGAL_TRIANGULATION_STATISTICS - mutable unsigned long walk_size_; + 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 - > Point_const_iterator; + typedef CGAL::Iterator_project< + typename Full_cell::Vertex_handle_const_iterator, + internal::Triangulation::Point_from_vertex_handle + > 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()); } + 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 + // FACETS OPERATIONS - Full_cell_handle full_cell(const Facet & f) const - { - return tds().full_cell(f); - } + 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); - } + int index_of_covertex(const Facet & f) const + { + return tds().index_of_covertex(f); + } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UTILITIES - // - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS + // 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 Rotor; + 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 = full_cell(r)->mirror_index(index_of_covertex(r)); + Full_cell_handle s = full_cell(r)->neighbor(index_of_covertex(r)); + int new_second = s->index(full_cell(r)->vertex(index_of_second_covertex(r))); + return Rotor(s, new_second, opposite); + } - Triangulation(int dim, const Geom_traits k = Geom_traits()) - : tds_(dim) - , kernel_(k) - , infinity_() - , rng_((long)0) - , preset_flat_orientation_(std::numeric_limits::max(), NULL) + // - - - - - - - - - - - - - - - - - - - - - - - - CREATION / CONSTRUCTORS + + Triangulation(int dim, const Geom_traits k = Geom_traits()) + : tds_(dim) + , kernel_(k) + , infinity_() + , preset_flat_orientation_(std::numeric_limits::max(), NULL) + , rng_((long)0) #ifdef CGAL_TRIANGULATION_STATISTICS - ,walk_size_(0) + ,walk_size_(0) #endif - { - clear(); - } + { + 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 &preset_flat_orientation, - const Geom_traits k = Geom_traits()) - : tds_(dim) - , kernel_(k) - , infinity_() - , rng_((long)0) - , preset_flat_orientation_(preset_flat_orientation) + // 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 &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) + ,walk_size_(0) #endif - { - clear(); - } - - Triangulation(const Triangulation & t2) - : tds_(t2.tds_) - , kernel_(t2.kernel_) - , infinity_() - , rng_(t2.rng_) - , preset_flat_orientation_(std::numeric_limits::max(), NULL) + { + clear(); + } + + Triangulation(const Triangulation & t2) + : tds_(t2.tds_) + , kernel_(t2.kernel_) + , infinity_() + , preset_flat_orientation_(std::numeric_limits::max(), NULL) + , rng_(t2.rng_) #ifdef CGAL_TRIANGULATION_STATISTICS - ,walk_size_(t2.walk_size_) + ,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() ) { - // 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(); + ++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() {} + ~Triangulation() {} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ACCESS FUNCTIONS + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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); - } + /* 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); - } */ + // 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() - ); - } + 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_; - } + const Triangulation_ds & tds() const + { + return tds_; + } - Triangulation_ds & tds() - { - return tds_; - } + Triangulation_ds & tds() + { + return tds_; + } - const Geom_traits & geom_traits() const - { - return kernel_; - } + const Geom_traits & geom_traits() const + { + return kernel_; + } - int maximal_dimension() const { return tds().maximal_dimension(); } - int current_dimension() const { return tds().current_dimension(); } + int maximal_dimension() const { return tds().maximal_dimension(); } + int current_dimension() const { return tds().current_dimension(); } - bool empty() const - { - return current_dimension() == -1; - } + bool empty() const + { + return current_dimension() == -1; + } - size_type number_of_vertices() const - { - return tds().number_of_vertices() - 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(); - } + size_type number_of_full_cells() const + { + return tds().number_of_full_cells(); + } - Vertex_handle infinite_vertex() const - { - return infinity_; - } + 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(); - } + 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 + 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 ) { - 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; + 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_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(); } + 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()); } + 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_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(); } + 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()); } + 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()); } + 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 + class Finiteness_predicate + { + const Self & t_; + public: + Finiteness_predicate(const Self & t) : t_(t) {} + template < class T > + bool operator()(const T & t) const { - 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); - } - }; + 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_ );} - }; + 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 + 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 ) { - 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; + 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_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_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(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(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_handle()); - if( is_infinite(s) ) - return (s->vertex(index_of_covertex(ft)) != infinite_vertex()); - return false; - } + 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_handle()); + if( is_infinite(s) ) + return (s->vertex(index_of_covertex(ft)) != infinite_vertex()); + return false; + } - bool is_infinite(const Face & f) const + bool is_infinite(const Face & f) const + { + Full_cell_const_handle s = f.full_cell(); + CGAL_precondition(s != Full_cell_handle()); + if( is_infinite(s) ) { - Full_cell_const_handle s = f.full_cell(); - CGAL_precondition(s != Full_cell_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; + Vertex_handle v; + for( int i(0); i<= f.face_dimension(); ++i) + if ( is_infinite( f.vertex(i) )) return true; } + return false; + } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ELEMENT GATHERING + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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_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) + template< typename OutputIterator > + OutputIterator incident_faces(Vertex_const_handle v, int d, OutputIterator out) + { + 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 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() ) { - return tds().incident_faces(v, d, out); + Orientation_d ori = geom_traits().orientation_d_object(); + return ori(points_begin(s), points_begin(s) + 1 + current_dimension()); } - /* - template< typename OutputIterator, class Comparator > - OutputIterator incident_upper_faces( Vertex_const_handle v, int d, - OutputIterator out, Comparator cmp = Comparator()) + else { - 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 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()); - } + 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(); + 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; + walk_size_ = 0; #endif - } + } - void set_current_dimension(int d) - { - tds().set_current_dimension(d); - } + void set_current_dimension(int d) + { + tds().set_current_dimension(d); + } - Full_cell_handle new_full_cell() - { - return tds().new_full_cell(); - } + Full_cell_handle new_full_cell() + { + return tds().new_full_cell(); + } - Vertex_handle new_vertex(const Point & p) - { - return tds().new_vertex(p); - } + 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); - } + 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; + 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; + 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; + 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 &); + Vertex_handle contract_face(const Point &, const Face &); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - POINT INSERTION - template< typename ForwardIterator > - size_type insert(ForwardIterator start, ForwardIterator end) + template< typename ForwardIterator > + size_type insert(ForwardIterator start, ForwardIterator end) + { + size_type n = number_of_vertices(); + std::vector points(start, end); + spatial_sort(points.begin(), points.end(), geom_traits()); + Full_cell_handle hint = Full_cell_handle(); + typename std::vector::const_iterator s = points.begin(); + while( s != points.end() ) { - size_type n = number_of_vertices(); - std::vector points(start, end); - spatial_sort(points.begin(), points.end(), geom_traits()); - Full_cell_handle hint = Full_cell_handle(); - typename std::vector::const_iterator s = points.begin(); - while( s != points.end() ) - { - hint = insert(*s++, hint)->full_cell(); - } - return number_of_vertices() - n; + hint = insert(*s++, hint)->full_cell(); } - Vertex_handle insert(const Point &, const Locate_type, const Face &, const Facet &, const 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 &); + return number_of_vertices() - n; + } + Vertex_handle insert(const Point &, const Locate_type, const Face &, const Facet &, const 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 + 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 { - 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; - // FIXME: infinite vertex is NOT at index 0 a priori. - n->vertex(0)->set_point(p_); - bool ok = (POSITIVE == ori_(t_.points_begin(n), t_.points_begin(n) + cur_dim_ + 1)); - return ok; - } - }; + 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; + // FIXME: infinite vertex is NOT at index 0 a priori. + n->vertex(0)->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(); + // 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 + { + typedef std::vector 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) ); + } + }; }; // Triangulation<...> @@ -715,20 +763,20 @@ void Triangulation ::reorient_full_cells() { - if( current_dimension() < 1 ) - return; - Full_cell_iterator sit = full_cells_begin(); - Full_cell_iterator send = full_cells_end(); - while( sit != send ) + if( current_dimension() < 1 ) + return; + Full_cell_iterator sit = full_cells_begin(); + Full_cell_iterator send = full_cells_end(); + while( sit != send ) + { + if( is_infinite(sit) && (1 == current_dimension()) ) { - if( is_infinite(sit) && (1 == current_dimension()) ) - { - ++sit; - continue; - } - sit->swap_vertices(current_dimension() - 1, current_dimension()); - ++sit; + ++sit; + continue; } + sit->swap_vertices(current_dimension() - 1, current_dimension()); + ++sit; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -739,11 +787,11 @@ typename Triangulation::Vertex_handle Triangulation ::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; + 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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -754,32 +802,32 @@ typename Triangulation::Vertex_handle Triangulation ::insert(const Point & p, const Locate_type lt, const Face & f, const Facet & ft, const Full_cell_handle s) { - switch( lt ) + 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: { - 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; + return insert_in_facet(p, ft); + break; } - CGAL_assertion(false); - return Vertex_handle(); + 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 > @@ -787,11 +835,11 @@ typename Triangulation::Vertex_handle Triangulation ::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); + 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 > @@ -799,9 +847,9 @@ typename Triangulation::Vertex_handle Triangulation ::insert(const Point & p, Vertex_handle v) { - if( Vertex_handle() == v ) - v = infinite_vertex(); - return insert(p, v->full_cell()); + if( Vertex_handle() == v ) + v = infinite_vertex(); + return insert(p, v->full_cell()); } template < class TT, class TDS > @@ -809,10 +857,10 @@ typename Triangulation::Vertex_handle Triangulation ::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; + CGAL_precondition( ! is_infinite(f) ); + Vertex_handle v = tds().insert_in_face(f); + v->set_point(p); + return v; } template < class TT, class TDS > @@ -820,10 +868,10 @@ typename Triangulation::Vertex_handle Triangulation ::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; + CGAL_precondition( ! is_infinite(ft) ); + Vertex_handle v = tds().insert_in_facet(ft); + v->set_point(p); + return v; } template < class TT, class TDS > @@ -831,10 +879,10 @@ typename Triangulation::Vertex_handle Triangulation ::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; + CGAL_precondition( ! is_infinite(s) ); + Vertex_handle v = tds().insert_in_full_cell(s); + v->set_point(p); + return v; } // NOT DOCUMENTED... @@ -843,20 +891,20 @@ typename Triangulation::Vertex_handle Triangulation ::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() ); - // FIXME: infinite vertex is NOT at index 0 a priori. But I'm not sure it's a problem here. - bool swap = (0 == s->neighbor(0)->index(s)); - Vertex_handle v = tds().insert_in_full_cell(s); - v->set_point(p); - if( swap ) - { - s->swap_vertices(0, 1); - } - return v; + // 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() ); + // FIXME: infinite vertex is NOT at index 0 a priori. But I'm not sure it's a problem here. + bool swap = (0 == s->neighbor(0)->index(s)); + Vertex_handle v = tds().insert_in_full_cell(s); + v->set_point(p); + if( swap ) + { + s->swap_vertices(0, 1); + } + return v; } template < class TT, class TDS > @@ -864,31 +912,31 @@ typename Triangulation::Vertex_handle Triangulation ::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 simps; - simps.reserve(64); - std::back_insert_iterator > out(simps); - if( current_dimension() < maximal_dimension() ) - { - Outside_convex_hull_traversal_predicate - ochtp(*this, p, coaffine_orientation_predicate()); - tds().gather_full_cells(s, ochtp, out); - } - else - { - Orientation_d ori = geom_traits().orientation_d_object(); - Outside_convex_hull_traversal_predicate - ochtp(*this, p, ori); - tds().gather_full_cells(s, ochtp, out); - } - // FIXME: infinite vertex is NOT at index 0 a priori. - Vertex_handle v = insert_in_hole(p, simps.begin(), simps.end(), Facet(s, 0)); - return v; + if( 1 == current_dimension() ) + { + return insert_outside_convex_hull_1(p, s); + } + CGAL_precondition( is_infinite(s) ); + CGAL_assertion( current_dimension() >= 2 ); + std::vector simps; + simps.reserve(64); + std::back_insert_iterator > out(simps); + if( current_dimension() < maximal_dimension() ) + { + Outside_convex_hull_traversal_predicate + ochtp(*this, p, coaffine_orientation_predicate()); + tds().gather_full_cells(s, ochtp, out); + } + else + { + Orientation_d ori = geom_traits().orientation_d_object(); + Outside_convex_hull_traversal_predicate + ochtp(*this, p, ori); + tds().gather_full_cells(s, ochtp, out); + } + // FIXME: infinite vertex is NOT at index 0 a priori. + Vertex_handle v = insert_in_hole(p, simps.begin(), simps.end(), Facet(s, 0)); + return v; } template < class TT, class TDS > @@ -896,21 +944,21 @@ typename Triangulation::Vertex_handle Triangulation ::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 ) - { - // FIXME: infinite vertex is NOT at index 0 a priori. - Full_cell_handle s = infinite_vertex()->full_cell()->neighbor(0); - Orientation o = orientation(s); - CGAL_assertion( COPLANAR != o ); - if( NEGATIVE == o ) - reorient_full_cells(); - } - return v; + 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 ) + { + // FIXME: infinite vertex is NOT at index 0 a priori. + Full_cell_handle s = infinite_vertex()->full_cell()->neighbor(0); + Orientation o = orientation(s); + CGAL_assertion( COPLANAR != o ); + if( NEGATIVE == o ) + reorient_full_cells(); + } + return v; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -921,181 +969,181 @@ template< typename OrientationPredicate > typename Triangulation::Full_cell_handle Triangulation ::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) - const Full_cell_handle start// starting full_cell for the walk - , OrientationPredicate const& orientation_pred - ) const + 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) + const Full_cell_handle start// starting full_cell for the walk + , OrientationPredicate const& orientation_pred + ) const { - const int cur_dim = current_dimension(); + const int cur_dim = current_dimension(); - if( cur_dim == -1 ) + 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(); + 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 - // FIXME: infinite vertex is NOT at index 0 a priori. - s = const_cast(this)->infinite_full_cell()->neighbor(0); else { - s = start; - if( is_infinite(s) ) - s = s->neighbor(0); // FIXME: index of infinite vertex is not zero ( not 0) + loc_type = ON_VERTEX; + face.set_full_cell(vit->full_cell()); + face.set_index(0, 0); + return vit->full_cell(); } + } - // Check if query |p| is outside the affine hull - if( cur_dim < maximal_dimension() ) + 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 + // FIXME: infinite vertex is NOT at index 0 a priori. + s = const_cast(this)->infinite_full_cell()->neighbor(0); + else + { + s = start; + if( is_infinite(s) ) + s = s->neighbor(0); // FIXME: index of infinite vertex is not zero ( not 0) + } + + // 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) ) { - 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(); - } + 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| + // 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) ) { - #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 - } + 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); + 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)); + 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; - } + 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) ) - { + // 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); - 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; + } + 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); } - return s; + //-- 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::Full_cell_handle Triangulation ::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 + 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()); + 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()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1105,14 +1153,14 @@ template < class TT, class TDS > typename Triangulation::Full_cell_handle Triangulation ::locate( const Point & p, - Locate_type & loc_type, - Face & face, - Facet & facet, - Vertex_handle start) const + 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()); + if( Vertex_handle() == start ) + start = infinite_vertex(); + return locate(p, loc_type, face, facet, start->full_cell()); } template < class TT, class TDS > @@ -1120,10 +1168,10 @@ typename Triangulation::Full_cell_handle Triangulation ::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); + Locate_type lt; + Face face(maximal_dimension()); + Facet facet; + return locate(p, lt, face, facet, s); } template < class TT, class TDS > @@ -1131,9 +1179,9 @@ typename Triangulation::Full_cell_handle Triangulation ::locate(const Point & p, Vertex_handle v) const { - if( Vertex_handle() != v ) - v = infinite_vertex(); - return this->locate(p, v->full_cell()); + if( Vertex_handle() != v ) + v = infinite_vertex(); + return this->locate(p, v->full_cell()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VALIDITY @@ -1143,71 +1191,71 @@ bool Triangulation ::is_valid(bool verbose, int level) const { - if( ! tds().is_valid(verbose, level) ) - return false; + 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; - } - } + 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::are_incident_full_cells_valid(Vertex_const_handle v, bool verbose, int level) const { - if( current_dimension() <= 0 ) - return true; - typedef std::vector Simps; - Simps simps; - simps.reserve(64); - std::back_insert_iterator 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; - } - } + if( current_dimension() <= 0 ) return true; + typedef std::vector Simps; + Simps simps; + simps.reserve(64); + std::back_insert_iterator 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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1226,46 +1274,43 @@ operator>>(std::istream & is, Triangulation & tr) // 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 T; - typedef typename T::Vertex_handle Vertex_handle; - typedef typename T::Vertex_iterator Vertex_iterator; - typedef typename T::Full_cell_handle Full_cell_handle; - typedef typename T::Full_cell_iterator Full_cell_iterator; + typedef Triangulation 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()); - } + // 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"); + CGAL_assertion_msg( cd <= tr.maximal_dimension(), "input Triangulation has too high dimension"); - tr.clear(); - tr.set_current_dimension(cd); + tr.clear(); + tr.set_current_dimension(cd); - if( n == 0 ) - return is; + if( n == 0 ) + return is; - std::vector vertices; - vertices.resize(n+1); - vertices[0] = tr.infinite_vertex(); - is >> (*vertices[0]); + std::vector 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; - } + // 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 + // now, read the combinatorial information return tr.tds().read_full_cells(is, vertices); } @@ -1281,43 +1326,41 @@ operator<<(std::ostream & os, const Triangulation & tr) // 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 T; - typedef typename T::Vertex_const_handle Vertex_handle; - typedef typename T::Vertex_const_iterator Vertex_iterator; - typedef typename T::Full_cell_const_handle Full_cell_handle; - typedef typename T::Full_cell_const_iterator Full_cell_iterator; + typedef Triangulation 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()); - } + // 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; + if( n == 0 ) + return os; - size_t i(0); - // write the vertices - std::map index_of_vertex; + size_t i(0); + // write the vertices + std::map 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 ); + // 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); + // output the combinatorial information + return tr.tds().write_full_cells(os, index_of_vertex); } } //namespace CGAL diff --git a/Triangulation/include/CGAL/Triangulation_data_structure.h b/Triangulation/include/CGAL/Triangulation_data_structure.h index 67c4b9fde3d..583f798446e 100644 --- a/Triangulation/include/CGAL/Triangulation_data_structure.h +++ b/Triangulation/include/CGAL/Triangulation_data_structure.h @@ -39,577 +39,601 @@ namespace CGAL { template< class Dimen, - class Vb = Default, - class Fcb = Default > + class Vb = Default, + class Fcb = Default > class Triangulation_data_structure { - typedef Triangulation_data_structure Self; - typedef typename Default::Get >::type V_base; - typedef typename Default::Get >::type FC_base; + typedef Triangulation_data_structure Self; + typedef typename Default::Get >::type V_base; + typedef typename Default::Get >::type FC_base; public: - typedef typename V_base::template Rebind_TDS::Other Vertex; /* Concept */ - typedef typename FC_base::template Rebind_TDS::Other Full_cell; /* Concept */ + typedef typename V_base::template Rebind_TDS::Other Vertex; /* Concept */ + typedef typename FC_base::template Rebind_TDS::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 Other; + typedef Triangulation_data_structure Other; }; template < typename Fcb2 > struct Rebind_full_cell { - typedef Triangulation_data_structure Other; + typedef Triangulation_data_structure 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_) {} + // 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; } + 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. - }; + 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_container; - typedef Compact_container Full_cell_container; + typedef Compact_container Vertex_container; + typedef Compact_container Full_cell_container; public: - typedef Dimen Maximal_dimension; + 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::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 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 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 Facet_iterator; /* Concept */ + typedef internal::Triangulation:: + Triangulation_ds_facet_iterator 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|) */ + /* 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 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_; } - }; + // 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 Face; /* Concept */ + typedef Triangulation_face 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 + 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(); - } + void clean_dynamic_memory() + { + vertices_.clear(); + full_cells_.clear(); + } - template < class Dim_tag > - struct get_maximal_dimension - { - static int value(const int D) { return D; } - }; - // specialization - template < int D > - struct get_maximal_dimension > - { - static int value(const int) { return D; } - }; + template < class Dim_tag > + struct get_maximal_dimension + { + static int value(const int D) { return D; } + }; + // specialization + template < int D > + struct get_maximal_dimension > + { + static int value(const int) { return D; } + }; public: - Triangulation_data_structure( int dim=0) /* Concept */ - : dmax_(get_maximal_dimension::value(dim)), dcur_(-2), - vertices_(), full_cells_() - { - CGAL_assertion_msg(dmax_ > 0, "maximal dimension must be positive."); - } + Triangulation_data_structure( int dim=0) /* Concept */ + : dmax_(get_maximal_dimension::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() + { + 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_) + 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 V_map; + typedef std::map 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() ) { - typedef std::map V_map; - typedef std::map 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 <= current_dimension(); ++i ) - { - associate_vertex_with_full_cell(cto, i, vmap[cto->vertex(i)]); - cto->set_neighbor(i, cmap[cto->neighbor(i)]); - } - ++cto; - } + for( int i = 0; i <= current_dimension(); ++i ) + { + associate_vertex_with_full_cell(cto, i, vmap[cto->vertex(i)]); + cto->set_neighbor(i, cmap[cto->neighbor(i)]); + } + ++cto; } + } - // QUERIES + // QUERIES protected: - bool check_range(const int i) const + bool check_range(const int i) const + { + if( current_dimension() < 0 ) { - if( current_dimension() < 0 ) - { - return (0 == i); - } - return ( (0 <= i) && (i <= current_dimension()) ); + 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 */ + /* 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(); - } + 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; - } + 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_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(const Full_cell_handle s, const int i) const /* Concept */ - { - CGAL_precondition(s != Full_cell_handle() && check_range(i)); - return s->vertex(i); - } + Vertex_handle vertex(const Full_cell_handle s, const int i) const /* Concept */ + { + CGAL_precondition(s != Full_cell_handle() && check_range(i)); + return s->vertex(i); + } - Vertex_const_handle vertex(const Full_cell_const_handle s, const int i) const /* Concept */ - { - CGAL_precondition(s != Full_cell_handle() && check_range(i)); - return s->vertex(i); - } + Vertex_const_handle vertex(const Full_cell_const_handle s, const int i) const /* Concept */ + { + CGAL_precondition(s != Full_cell_handle() && check_range(i)); + return s->vertex(i); + } - bool is_vertex(const 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_vertex(const 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(const 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; - } + bool is_full_cell(const 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(const Vertex_handle v) const /* Concept */ - { - CGAL_precondition(v != Vertex_handle()); - return v->full_cell(); - } + Full_cell_handle full_cell(const Vertex_handle v) const /* Concept */ + { + CGAL_precondition(v != Vertex_handle()); + return v->full_cell(); + } - Full_cell_const_handle full_cell(const Vertex_const_handle v) const /* Concept */ - { - CGAL_precondition(Vertex_const_handle() != v); - return v->full_cell(); - } + Full_cell_const_handle full_cell(const Vertex_const_handle v) const /* Concept */ + { + CGAL_precondition(Vertex_const_handle() != v); + return v->full_cell(); + } - Full_cell_handle neighbor(const Full_cell_handle s, const int i) const /* Concept */ - { - CGAL_precondition(Full_cell_handle() != s && check_range(i)); - return s->neighbor(i); - } + Full_cell_handle neighbor(const Full_cell_handle s, const int i) const /* Concept */ + { + CGAL_precondition(Full_cell_handle() != s && check_range(i)); + return s->neighbor(i); + } - Full_cell_const_handle neighbor(const Full_cell_const_handle s, const int i) const/* Concept */ - { - CGAL_precondition(Full_cell_const_handle() != s && check_range(i)); - return s->neighbor(i); - } + Full_cell_const_handle neighbor(const Full_cell_const_handle s, const int i) const/* Concept */ + { + CGAL_precondition(Full_cell_const_handle() != s && check_range(i)); + return s->neighbor(i); + } - int mirror_index(const Full_cell_handle s, const int i) const /* Concept */ - { - CGAL_precondition(Full_cell_handle() != s && check_range(i)); - return s->mirror_index(i); - } + int mirror_index(const Full_cell_handle s, const int i) const /* Concept */ + { + CGAL_precondition(Full_cell_handle() != s && check_range(i)); + return s->mirror_index(i); + } - int mirror_index(const Full_cell_const_handle s, const int i) const - { - CGAL_precondition(Full_cell_const_handle() != s && check_range(i)); /* Concept */ - return s->mirror_index(i); - } + int mirror_index(const Full_cell_const_handle s, const int i) const + { + CGAL_precondition(Full_cell_const_handle() != s && check_range(i)); /* Concept */ + return s->mirror_index(i); + } - int mirror_vertex(const Full_cell_handle s, const int i) const /* Concept */ - { - CGAL_precondition(Full_cell_handle() != s && check_range(i)); - return s->mirror_vertex(i); - } + int mirror_vertex(const Full_cell_handle s, const int i) const /* Concept */ + { + CGAL_precondition(Full_cell_handle() != s && check_range(i)); + return s->mirror_vertex(i); + } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FACETS OPERATIONS + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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< 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(); - } + // 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(); - } + // 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; - } + // 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); - } + // 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 + // NICE UPDATE OPERATIONS protected: - void do_insert_increase_dimension(const Vertex_handle, const Vertex_handle); + void do_insert_increase_dimension(const Vertex_handle, const Vertex_handle); public: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REMOVALS - Vertex_handle collapse_face(const Face &); /* Concept */ - void remove_decrease_dimension(Vertex_handle, Vertex_handle); /* Concept */ + 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, const Forward_iterator, Facet); /* Concept */ - template< typename Forward_iterator, typename OutputIterator > - Vertex_handle insert_in_hole(Forward_iterator, const Forward_iterator, Facet, OutputIterator); /* Concept */ + 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, const Forward_iterator, Facet); /* Concept */ + template< typename Forward_iterator, typename OutputIterator > + Vertex_handle insert_in_hole(Forward_iterator, const Forward_iterator, Facet, OutputIterator); /* Concept */ - template< typename OutputIterator > - Full_cell_handle insert_in_tagged_hole(Vertex_handle, Facet, OutputIterator); + template< typename OutputIterator > + Full_cell_handle insert_in_tagged_hole(Vertex_handle, Facet, OutputIterator); - Vertex_handle insert_increase_dimension(Vertex_handle=Vertex_handle()); /* Concept */ + Vertex_handle insert_increase_dimension(Vertex_handle=Vertex_handle()); /* Concept */ private: - // NOT DOCUMENTED - void clear_visited_marks(Full_cell_handle) const; + // 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_) + {} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DANGEROUS UPDATE OPERATIONS + // "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 + 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(); - } + // 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 clear() /* Concept */ + { + clean_dynamic_memory(); + dcur_ = -2; + } - void set_current_dimension(const int d) /* Concept */ - { - CGAL_precondition(-2<=d && d<=maximal_dimension()); - dcur_ = d; - } + void set_current_dimension(const int d) /* Concept */ + { + CGAL_precondition(-2<=d && d<=maximal_dimension()); + dcur_ = d; + } - Full_cell_handle new_full_cell(const Full_cell_handle s) - { - return full_cells_.emplace(*s); - } + Full_cell_handle new_full_cell(const Full_cell_handle s) + { + return full_cells_.emplace(*s); + } - Full_cell_handle new_full_cell() /* Concept */ - { - return full_cells_.emplace(dmax_); - } + 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); - } + 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< 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); - } + template< class T > + Vertex_handle new_vertex( const T & t ) + { + return vertices_.emplace(t); + } - Vertex_handle new_vertex() /* Concept */ - { - return vertices_.emplace(); - } + Vertex_handle new_vertex() /* Concept */ + { + return vertices_.emplace(); + } - void delete_vertex(Vertex_handle v) /* Concept */ - { - CGAL_precondition( Vertex_handle() != v ); - vertices_.erase(v); - } + 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, const 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 associate_vertex_with_full_cell(Full_cell_handle s, const 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); - } + 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 + // SANITY CHECKS - bool is_valid(bool = true, int = 0) const; /* Concept */ + bool is_valid(bool = true, int = 0) const; /* Concept */ - // NOT DOCUMENTED - template< class OutStream> void write_graph(OutStream &); + // 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_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 */ + 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); - } + 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 + // 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) { - 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; - } + 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; + } + }; - // 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 */ + 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 > - OutputIterator incident_upper_faces(Vertex_const_handle v, const int dim, OutputIterator out, Comparator cmp = Comparator()) - { - return incident_faces(v, dim, out, cmp, true); - } - template< typename OutputIterator, typename Comparator = std::less > - OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator, Comparator = Comparator(), bool = false); + template< typename OutputIterator, typename Comparator = std::less > + OutputIterator incident_upper_faces(Vertex_const_handle v, const int dim, OutputIterator out, Comparator cmp = Comparator()) + { + return incident_faces(v, dim, out, cmp, true); + } + template< typename OutputIterator, typename Comparator = std::less > + OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator, Comparator = Comparator(), bool = false); #else - template< typename OutputIterator, typename Comparator > - OutputIterator incident_upper_faces(Vertex_const_handle v, const 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, const int dim, OutputIterator out) - { - return incident_faces(v, dim, out, std::less(), true); - } - template< typename OutputIterator, typename Comparator > - OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator, Comparator = Comparator(), bool = false); - template< typename OutputIterator > - OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator, - std::less = std::less(), bool = false); + template< typename OutputIterator, typename Comparator > + OutputIterator incident_upper_faces(Vertex_const_handle v, const 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, const int dim, OutputIterator out) + { + return incident_faces(v, dim, out, std::less(), true); + } + template< typename OutputIterator, typename Comparator > + OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator, Comparator = Comparator(), bool = false); + template< typename OutputIterator > + OutputIterator incident_faces(Vertex_const_handle, const int, OutputIterator, + std::less = std::less(), bool = false); #endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INPUT / OUTPUT - std::istream & read_full_cells(std::istream &, const std::vector &); - std::ostream & write_full_cells(std::ostream &, std::map &) const; + std::istream & read_full_cells(std::istream &, const std::vector &); + std::ostream & write_full_cells(std::ostream &, std::map &) const; }; // end of ``declaration/definition'' of Triangulation_data_structure<...> @@ -626,10 +650,10 @@ OutputIterator Triangulation_data_structure ::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; + // 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 > @@ -639,10 +663,10 @@ Triangulation_data_structure ::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); + 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 > @@ -651,10 +675,10 @@ OutputIterator Triangulation_data_structure ::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; + // 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 > @@ -662,35 +686,35 @@ template< typename TraversalPredicate, typename OutputIterator > typename Triangulation_data_structure::Facet Triangulation_data_structure ::gather_full_cells(Full_cell_handle start, - TraversalPredicate & tp, - OutputIterator & out) const /* Concept */ + TraversalPredicate & tp, + OutputIterator & out) const /* Concept */ { - std::queue queue; - set_visited(start, true); - queue.push(start); - const int cur_dim = current_dimension(); - Facet ft; - while( ! queue.empty() ) + std::queue 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 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); - } - } + 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; + } + clear_visited_marks(start); + return ft; } #ifdef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES @@ -699,9 +723,9 @@ template< typename OutputIterator > OutputIterator Triangulation_data_structure ::incident_faces(Vertex_const_handle v, const int dim, OutputIterator out, - std::less cmp, bool upper_faces) + std::less cmp, bool upper_faces) { - return incident_faces >(v, dim, out, cmp, upper_faces); + return incident_faces >(v, dim, out, cmp, upper_faces); } #endif @@ -711,73 +735,73 @@ OutputIterator Triangulation_data_structure ::incident_faces(Vertex_const_handle v, const int dim, OutputIterator out, Comparator cmp, bool upper_faces) { - CGAL_precondition( 0 < dim ); - if( dim >= current_dimension() ) - return out; - typedef std::vector Simplices; - Simplices simps; - simps.reserve(64); - // gather incident full_cells - std::back_insert_iterator sout(simps); - incident_full_cells(v, sout); - // for storing the handles to the vertices of a full_cell - typedef std::vector Vertices; - typedef std::vector 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 - Upper_face_comparator; - Upper_face_comparator ufc(dim); - typedef std::set 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, v_idx); - while( ! f_idx.end() ) - { - // check if face has already been found - for( int i = 0; i < dim; ++i ) - f.set_index(1 + i, sorted_idx[f_idx[i]]); - face_set.insert(f); - // compute next sorted face (lexicographic enumeration) - ++f_idx; - } - } - typename Face_set::iterator fit = face_set.begin(); - while( fit != face_set.end() ) - *out++ = *fit++; + CGAL_precondition( 0 < dim ); + if( dim >= current_dimension() ) return out; + typedef std::vector Simplices; + Simplices simps; + simps.reserve(64); + // gather incident full_cells + std::back_insert_iterator sout(simps); + incident_full_cells(v, sout); + // for storing the handles to the vertices of a full_cell + typedef std::vector Vertices; + typedef std::vector 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 + Upper_face_comparator; + Upper_face_comparator ufc(dim); + typedef std::set 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, v_idx); + while( ! f_idx.end() ) + { + // check if face has already been found + for( int i = 0; i < dim; ++i ) + f.set_index(1 + i, sorted_idx[f_idx[i]]); + face_set.insert(f); + // 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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -788,21 +812,21 @@ typename Triangulation_data_structure::Vertex_handle Triangulation_data_structure ::collapse_face(const Face & f) /* Concept */ { - const int fd = f.face_dimension(); - CGAL_precondition( (1 <= fd ) && (fd < current_dimension())); - std::vector 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 > 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; + const int fd = f.face_dimension(); + CGAL_precondition( (1 <= fd ) && (fd < current_dimension())); + std::vector 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 > 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 @@ -810,68 +834,68 @@ void Triangulation_data_structure ::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 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()); - if( ( ! (*it)->has_vertex(star) ) || (current_dimension() > 2) ) - (*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); + 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 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()); + if( ( ! (*it)->has_vertex(star) ) || (current_dimension() > 2) ) + (*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); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -882,31 +906,31 @@ typename Triangulation_data_structure::Vertex_handle Triangulation_data_structure ::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)); + 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 ) + 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 ) { - 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)); + if( j == i ) continue; + set_neighbors(fc.neighbor(i), j, fc.neighbor(j), 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; + return v; } template @@ -914,23 +938,23 @@ typename Triangulation_data_structure::Vertex_handle Triangulation_data_structure ::insert_in_face(const Face & f) /* Concept */ { - std::vector simps; - simps.reserve(64); - std::back_insert_iterator > out(simps); - incident_full_cells(f, out); - return insert_in_hole(simps.begin(), simps.end(), Facet(f.full_cell(), f.index(0))); + std::vector simps; + simps.reserve(64); + std::back_insert_iterator > out(simps); + incident_full_cells(f, out); + return insert_in_hole(simps.begin(), simps.end(), Facet(f.full_cell(), f.index(0))); } template typename Triangulation_data_structure::Vertex_handle Triangulation_data_structure ::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)); + 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 @@ -938,62 +962,101 @@ template < typename OutputIterator > typename Triangulation_data_structure::Full_cell_handle Triangulation_data_structure ::insert_in_tagged_hole(Vertex_handle v, Facet f, - OutputIterator new_full_cells) + OutputIterator new_full_cells) { - CGAL_assertion_msg(is_boundary_facet(f), "starting facet should be on the hole boundary"); + CGAL_assertion_msg(is_boundary_facet(f), "starting facet should be on the hole boundary"); - const int cur_dim = current_dimension(); + const int cur_dim = current_dimension(); + Full_cell_handle new_s; - Full_cell_handle old_s = full_cell(f); - Full_cell_handle new_s = new_full_cell(); - const int facet_index = index_of_covertex(f); + std::queue task_queue; + task_queue.push( + IITH_task(f, mirror_index(full_cell(f), index_of_covertex(f))) ); - int i(0); - for( ; i < facet_index; ++i ) + 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 ) + ++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, + associate_vertex_with_full_cell(new_s, facet_index, v); + set_neighbors(new_s, facet_index, neighbor(old_s, facet_index), 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; + // 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); + 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 outside = neighbor(full_cell(rot), index_of_covertex(rot)); Full_cell_handle inside = full_cell(rot); - Vertex_handle m = inside->mirror_vertex(index_of_covertex(rot), current_dimension()); + 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); - if( new_neighbor == inside ) - { // not already extruded... we do it recursively - new_neighbor = insert_in_tagged_hole( v, - Facet(full_cell(rot), index_of_covertex(rot)), - new_full_cells); + // 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 + )); } - // now the new neighboring full_cell exists, we link both - set_neighbors(new_s, i, new_neighbor, index_of_second_covertex(rot)); + } } - return new_s; + + // 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 > @@ -1001,18 +1064,18 @@ template< typename Forward_iterator, typename OutputIterator > typename Triangulation_data_structure::Vertex_handle Triangulation_data_structure ::insert_in_hole(Forward_iterator start, Forward_iterator end, Facet f, - OutputIterator out) /* Concept */ + 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; + 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 > @@ -1021,8 +1084,8 @@ typename Triangulation_data_structure::Vertex_handle Triangulation_data_structure ::insert_in_hole(Forward_iterator start, Forward_iterator end, Facet f) /* Concept */ { - Emptyset_iterator out; - return insert_in_hole(start, end, f, out); + Emptyset_iterator out; + return insert_in_hole(start, end, f, out); } template @@ -1030,104 +1093,104 @@ void Triangulation_data_structure ::clear_visited_marks(Full_cell_handle start) const // NOT DOCUMENTED { - CGAL_precondition(start != Full_cell_handle()); + CGAL_precondition(start != Full_cell_handle()); - std::queue queue; - set_visited(start, false); - queue.push(start); - const int cur_dim = current_dimension(); - while( ! queue.empty() ) + std::queue 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 ) { - 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)); - } - } + if( get_visited(s->neighbor(i)) ) + { + set_visited(s->neighbor(i), false); + queue.push(s->neighbor(i)); + } } + } } template void Triangulation_data_structure ::do_insert_increase_dimension(const Vertex_handle x, const Vertex_handle star) { - Full_cell_handle start = full_cells_begin(); - Full_cell_handle swap_me; - const int cur_dim = current_dimension(); + 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)); + } + else if( cur_dim == 2 ) + { // if cur. dim. is 2, we must take care of the 'rightmost' infinite vertex. + if( S->mirror_index(S->index(star)) == 0 ) + swap_me = S; + } + } + // now we setup the neighbors + set_visited(start, false); + std::queue 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( 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)); - } - else if( cur_dim == 2 ) - { // if cur. dim. is 2, we must take care of the 'rightmost' infinite vertex. - if( S->mirror_index(S->index(star)) == 0 ) - swap_me = S; - } + if( x != S->vertex(cur_dim) ) + S->swap_vertices(cur_dim - 1, cur_dim); } - // now we setup the neighbors - set_visited(start, false); - std::queue 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); + } + if( Full_cell_handle() != swap_me ) + swap_me->swap_vertices(1, 2); } template @@ -1135,41 +1198,41 @@ typename Triangulation_data_structure::Vertex_handle Triangulation_data_structure ::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)); - } + 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; + 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; } - return v; + 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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1179,85 +1242,85 @@ template bool Triangulation_data_structure ::is_valid(bool verbose, int /* level */) const /* Concept */ { - Full_cell_const_handle s, t; - Vertex_const_handle v; - int i, j, k; + Full_cell_const_handle s, t; + Vertex_const_handle v; + int i, j, k; - if( current_dimension() == -2 ) + if( current_dimension() == -2 ) + { + if( ! vertices_.empty() || ! full_cells_.empty() ) { - 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( verbose ) CGAL_warning_msg(false, "current dimension is -2 but there are vertices or full_cells"); + return false; } + } - if( current_dimension() == -1 ) + if( current_dimension() == -1 ) + { + if ( (number_of_vertices() != 1) || (number_of_full_cells() != 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; - } + 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... + 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; - } - } + 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; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1269,45 +1332,45 @@ template void Triangulation_data_structure ::write_graph(OutStream & os) { - std::vector > 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 ) + std::vector > 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 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; - } + 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( int i = 0; i < edges.size(); ++i ) + } + for( int i = 0; i < edges.size(); ++i ) + { + os << std::endl << edges[i].size(); + for( std::set::const_iterator nit = edges[i].begin(); + nit != edges[i].end(); ++nit ) { - os << std::endl << edges[i].size(); - for( std::set::const_iterator nit = edges[i].begin(); - nit != edges[i].end(); ++nit ) - { - os << ' ' << (*nit); - } + os << ' ' << (*nit); } + } } // NOT DOCUMENTED... @@ -1316,76 +1379,76 @@ std::istream & Triangulation_data_structure ::read_full_cells(std::istream & is, const std::vector & vertices) { - 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()); + 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_cells; - full_cells.reserve(m); - // read the vertices of each full_cell - size_t i = 0; + std::vector full_cells; + full_cells.reserve(m); + // read the vertices of each full_cell + 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 ) { - 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; + 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; + } - // read the neighbors of each full_cell - i = 0; - if( is_ascii(is) ) - while( i < m ) + // compute the mirror indices + for( i = 0; i < m; ++i ) + { + Full_cell_handle s = full_cells[i]; + for( int j = 0; j <= cd; ++j ) { - for( int j = 0; j <= cd; ++j ) - { - is >> index; - full_cells[i]->set_neighbor(j, full_cells[index]); - } - ++i; + 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); } - 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; + } + return is; } // NOT DOCUMENTED... @@ -1394,52 +1457,52 @@ std::ostream & Triangulation_data_structure ::write_full_cells(std::ostream & os, std::map & index_of_vertex) const { - std::map index_of_full_cell; + std::map index_of_full_cell; - size_t m = number_of_full_cells(); + 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 << m; - else - write(os, m, io_Read_write()); + 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); + } - const int cur_dim = current_dimension(); - // write the vertex indices of each full_cell - int i = 0; + CGAL_assertion( 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 ) { - 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); + 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)]); } - CGAL_assertion( 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; + return os; } // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = @@ -1458,45 +1521,42 @@ operator>>(std::istream & is, Triangulation_data_structure & tr) // 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 TDS; - typedef typename TDS::Vertex_handle Vertex_handle; - typedef typename TDS::Vertex_iterator Vertex_iterator; - typedef typename TDS::Full_cell_handle Full_cell_handle; - typedef typename TDS::Full_cell_iterator Full_cell_iterator; + typedef Triangulation_data_structure TDS; + typedef typename TDS::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()); - } + // 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_data_structure has too high dimension"); + CGAL_assertion_msg( cd <= tr.maximal_dimension(), "input Triangulation_data_structure has too high dimension"); - tr.clear(); - tr.set_current_dimension(cd); + tr.clear(); + tr.set_current_dimension(cd); - if( n == 0 ) - return is; + if( n == 0 ) + return is; - std::vector vertices; - vertices.resize(n); + std::vector vertices; + vertices.resize(n); - // read the vertices: - size_t i(0); - while( i < n ) - { - vertices[i] = tr.new_vertex(); - is >> (*vertices[i]); // read a vertex - ++i; - } + // read the vertices: + 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); + // now, read the combinatorial information + return tr.read_full_cells(is, vertices); } template @@ -1511,37 +1571,35 @@ operator<<(std::ostream & os, const Triangulation_data_structure // 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 TDS; - typedef typename TDS::Vertex_const_handle Vertex_handle; - typedef typename TDS::Vertex_const_iterator Vertex_iterator; - typedef typename TDS::Full_cell_const_handle Full_cell_handle; - typedef typename TDS::Full_cell_const_iterator Full_cell_iterator; + typedef Triangulation_data_structure TDS; + typedef typename TDS::Vertex_const_handle Vertex_handle; + typedef typename TDS::Vertex_const_iterator Vertex_iterator; - // outputs dimension and number of vertices - 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()); - } + // outputs dimension and number of vertices + 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; + if( n == 0 ) + return os; - // write the vertices - std::map index_of_vertex; - int i = 0; - for( Vertex_iterator it = tr.vertices_begin(); it != tr.vertices_end(); ++it, ++i ) - { - os << *it; // write the vertex - index_of_vertex[it] = i; - } - CGAL_assertion( i == n ); + // write the vertices + std::map index_of_vertex; + int i = 0; + for( Vertex_iterator it = tr.vertices_begin(); it != tr.vertices_end(); ++it, ++i ) + { + os << *it << std::endl; // write the vertex + index_of_vertex[it] = i; + } + CGAL_assertion( i == n ); - // output the combinatorial information - return tr.write_full_cells(os, index_of_vertex); + // output the combinatorial information + return tr.write_full_cells(os, index_of_vertex); } } //namespace CGAL diff --git a/Triangulation/include/CGAL/Triangulation_full_cell.h b/Triangulation/include/CGAL/Triangulation_full_cell.h index e8ded7119f8..3177d487989 100644 --- a/Triangulation/include/CGAL/Triangulation_full_cell.h +++ b/Triangulation/include/CGAL/Triangulation_full_cell.h @@ -128,7 +128,7 @@ operator>>(std::istream & is, No_full_cell_data &) } std::ostream & -operator<<(std::ostream & os, const No_full_cell_data & nd) +operator<<(std::ostream & os, const No_full_cell_data &) { return os; } diff --git a/Triangulation/include/CGAL/Triangulation_vertex.h b/Triangulation/include/CGAL/Triangulation_vertex.h index 25e88a8d1b3..74d6a4928eb 100644 --- a/Triangulation/include/CGAL/Triangulation_vertex.h +++ b/Triangulation/include/CGAL/Triangulation_vertex.h @@ -100,7 +100,7 @@ operator>>(std::istream & is, No_vertex_data &) } std::ostream & -operator<<(std::ostream & os, const No_vertex_data & nd) +operator<<(std::ostream & os, const No_vertex_data &) { return os; } diff --git a/Triangulation/include/CGAL/internal/Triangulation/utilities.h b/Triangulation/include/CGAL/internal/Triangulation/utilities.h index 2d6e61ca484..b07fc75f3c9 100644 --- a/Triangulation/include/CGAL/internal/Triangulation/utilities.h +++ b/Triangulation/include/CGAL/internal/Triangulation/utilities.h @@ -98,7 +98,7 @@ public: template< class T > struct Compare_points_for_perturbation { - typedef typename T::Point_d Point; + typedef typename T::Geom_traits::Point_d Point; const T & t_; @@ -119,8 +119,8 @@ public: template< class T > struct Point_from_pointer { - typedef const typename T::Point_d * argument_type; - typedef const typename T::Point_d result_type; + 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); diff --git a/Triangulation/test/Triangulation/regular.cpp b/Triangulation/test/Triangulation/regular.cpp new file mode 100644 index 00000000000..cbfb021a058 --- /dev/null +++ b/Triangulation/test/Triangulation/regular.cpp @@ -0,0 +1,133 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace std; + +template +void test(const int d, const string & type, const int N) +{ + typedef typename RTri::Full_cell_handle Full_cell_handle; + typedef typename RTri::Face Face; + typedef typename RTri::Point Point; + typedef typename RTri::Bare_point Bare_point; + typedef typename RTri::Finite_full_cell_const_iterator Finite_full_cell_const_iterator; + typedef typename RTri::Finite_vertex_iterator Finite_vertex_iterator; + + typedef CGAL::Random_points_in_cube_d Random_points_iterator; + + RTri rt(d); + cerr << "\nBuilding Regular triangulation of (" << type << d << ") dimension with " << N << " points"; + assert(rt.empty()); + + vector points; + //CGAL::Random rng; + //Random_points_iterator rand_it(d, 2.0, rng); // CJTODO: unused + + srand(10); + for( int i = 0; i < N; ++i ) + { + vector coords(d); + for( int j = 0; j < d; ++j ) + coords[j] = static_cast(rand() % 100000)/10000; + points.push_back(Point( + Bare_point(d, coords.begin(), coords.end()), + /*static_cast(rand() % 100000)/100000*/static_cast(i)/20 + )); + } + rt.insert(points.begin(), points.end()); + cerr << "\nChecking topology and geometry..."; + assert( rt.is_valid(true) ); + + cerr << "\nTraversing finite full_cells... "; + size_t nbfs(0), nbis(0); + Finite_full_cell_const_iterator fsit = rt.finite_full_cells_begin(); + while( fsit != rt.finite_full_cells_end() ) + ++fsit, ++nbfs; + cerr << nbfs << " + "; + vector infinite_full_cells; + rt.tds().incident_full_cells(rt.infinite_vertex(), back_inserter(infinite_full_cells)); + nbis = infinite_full_cells.size(); + cerr << nbis << " = " << (nbis+nbfs) + << " = " << rt.number_of_full_cells(); + cerr << "\nThe triangulation has current dimension " << rt.current_dimension(); + CGAL_assertion( rt.number_of_full_cells() == nbis+nbfs); + + cerr << "\nTraversing finite vertices... "; + size_t nbfv(0); + Finite_vertex_iterator fvit = rt.finite_vertices_begin(); + while( fvit != rt.finite_vertices_end() ) + ++fvit, ++nbfv; + cerr << nbfv < 1 ) + { + typedef vector Faces; + Faces edges; + back_insert_iterator out(edges); + rt.tds().incident_faces(rt.infinite_vertex(), 1, out); + cout << "\nThere are " << edges.size() << " vertices on the convex hull."; + edges.clear(); + } + else // rt.maximal_dimension() == 1 + { + typedef vector Cells; + Cells cells; + back_insert_iterator out(cells); + rt.tds().incident_full_cells(rt.infinite_vertex(), out); + cout << "\nThere are " << cells.size() << " vertices on the convex hull."; + cells.clear(); + } + + // Remove all ! + cerr << "\nBefore removal: " << rt.number_of_vertices() << " vertices. After: "; + random_shuffle(points.begin(), points.end()); + rt.remove(points.begin(), points.end()); + assert( rt.is_valid() ); + //std::cerr << ((rt.is_valid(true)) ? "VALID!" : "NOT VALID :(") << std::endl; + cerr << rt.number_of_vertices() << " vertices."; + // assert( rt.empty() ); NOT YET ! + // CLEAR + rt.clear(); + assert( -1 == rt.current_dimension() ); + assert( rt.empty() ); + assert( rt.is_valid() ); + //std::cerr << ((rt.is_valid(true)) ? "VALID!" : "NOT VALID :(") << std::endl; +} + +template< int D > +void go(const int N) +{ + //typedef CGAL::Epick_d FK; + typedef CGAL::Epick_d > FK; + typedef CGAL::Regular_triangulation_euclidean_traits Traits; + typedef CGAL::Regular_triangulation Triangulation; + //test(D, "dynamic", N); + test(D, "static", N); +} + +int main(int argc, char **argv) +{ + srand(static_cast(time(NULL))); + int N = 10; + if( argc > 1 ) + N = atoi(argv[1]); + go<5>(N); + go<4>(N); + go<3>(N); + go<2>(N); + go<1>(N); + + cerr << endl; + return 0; +} diff --git a/Triangulation/test/Triangulation/test_delaunay.cpp b/Triangulation/test/Triangulation/test_delaunay.cpp index 38ea692aba8..76cd1914eae 100644 --- a/Triangulation/test/Triangulation/test_delaunay.cpp +++ b/Triangulation/test/Triangulation/test_delaunay.cpp @@ -19,92 +19,88 @@ void test(const int d, const string & type, const int N) // we must write 'typename' below, because we are in a template-function, // so the parser has no way to know that DC contains sub-types, before // instanciating the function. - typedef typename DC::Vertex Vertex; - typedef typename DC::Vertex_handle Vertex_handle; - typedef typename DC::Full_cell Full_cell; typedef typename DC::Full_cell_handle Full_cell_handle; - typedef typename DC::Facet Facet; typedef typename DC::Face Face; typedef typename DC::Point Point; - typedef typename DC::Geom_traits::RT RT; typedef typename DC::Finite_full_cell_const_iterator Finite_full_cell_const_iterator; typedef typename DC::Finite_vertex_iterator Finite_vertex_iterator; typedef CGAL::Random_points_in_cube_d Random_points_iterator; - DC pc(d); + DC dt(d); cerr << "\nBuilding Delaunay triangulation of (" << type << d << ") dimension with " << N << " points"; - assert(pc.empty()); + assert(dt.empty()); vector points; - CGAL::Random rng; - Random_points_iterator rand_it(d, 2.0, rng); + //CGAL::Random rng; + //Random_points_iterator rand_it(d, 2.0, rng); //CGAL::cpp11::copy_n(rand_it, N, back_inserter(points)); - vector coords(d); + srand(10); for( int i = 0; i < N; ++i ) { + vector coords(d); for( int j = 0; j < d; ++j ) - coords[j] = rand() % 100000; + coords[j] = static_cast(rand() % 100000)/10000; points.push_back(Point(d, coords.begin(), coords.end())); } - pc.insert(points.begin(), points.end()); + dt.insert(points.begin(), points.end()); cerr << "\nChecking topology and geometry..."; - assert( pc.is_valid() ); + assert( dt.is_valid() ); cerr << "\nTraversing finite full_cells... "; size_t nbfs(0), nbis(0); - Finite_full_cell_const_iterator fsit = pc.finite_full_cells_begin(); - while( fsit != pc.finite_full_cells_end() ) + Finite_full_cell_const_iterator fsit = dt.finite_full_cells_begin(); + while( fsit != dt.finite_full_cells_end() ) ++fsit, ++nbfs; cerr << nbfs << " + "; vector infinite_full_cells; - pc.tds().incident_full_cells(pc.infinite_vertex(), back_inserter(infinite_full_cells)); + dt.tds().incident_full_cells(dt.infinite_vertex(), back_inserter(infinite_full_cells)); nbis = infinite_full_cells.size(); cerr << nbis << " = " << (nbis+nbfs) - << " = " << pc.number_of_full_cells(); - cerr << "\nThe triangulation has current dimension " << pc.current_dimension(); - CGAL_assertion( pc.number_of_full_cells() == nbis+nbfs); + << " = " << dt.number_of_full_cells(); + cerr << "\nThe triangulation has current dimension " << dt.current_dimension(); + CGAL_assertion( dt.number_of_full_cells() == nbis+nbfs); cerr << "\nTraversing finite vertices... "; size_t nbfv(0); - Finite_vertex_iterator fvit = pc.finite_vertices_begin(); - while( fvit != pc.finite_vertices_end() ) + Finite_vertex_iterator fvit = dt.finite_vertices_begin(); + while( fvit != dt.finite_vertices_end() ) ++fvit, ++nbfv; cerr << nbfv < 1 ) + if( dt.maximal_dimension() > 1 ) { typedef vector Faces; Faces edges; back_insert_iterator out(edges); - pc.tds().incident_faces(pc.infinite_vertex(), 1, out); + dt.tds().incident_faces(dt.infinite_vertex(), 1, out); cout << "\nThere are " << edges.size() << " vertices on the convex hull."; edges.clear(); } - else // pc.maximal_dimension() == 1 + else // dt.maximal_dimension() == 1 { typedef vector Cells; Cells cells; back_insert_iterator out(cells); - pc.tds().incident_full_cells(pc.infinite_vertex(), out); + dt.tds().incident_full_cells(dt.infinite_vertex(), out); cout << "\nThere are " << cells.size() << " vertices on the convex hull."; cells.clear(); } // Remove all ! - cerr << "\nBefore removal: " << pc.number_of_vertices() << " vertices. After: "; + cerr << "\nBefore removal: " << dt.number_of_vertices() << " vertices. After: "; random_shuffle(points.begin(), points.end()); - pc.remove(points.begin(), points.end()); - assert( pc.is_valid() ); - cerr << pc.number_of_vertices() << " vertices."; - // assert( pc.empty() ); NOT YET ! + dt.remove(points.begin(), points.end()); + assert( dt.is_valid() ); + cerr << dt.number_of_vertices() << " vertices."; + // assert( dt.empty() ); NOT YET ! // CLEAR - pc.clear(); - assert( -1 == pc.current_dimension() ); - assert( pc.empty() ); - assert( pc.is_valid() ); + dt.clear(); + assert( -1 == dt.current_dimension() ); + assert( dt.empty() ); + assert( dt.is_valid() ); } template< int D > @@ -120,14 +116,14 @@ void go(const int N) int main(int argc, char **argv) { srand(static_cast(time(NULL))); - int N = 100; + int N = 10; if( argc > 1 ) N = atoi(argv[1]); - go<5>(N); - go<4>(N); - go<3>(N); - go<2>(N); - go<1>(N); + //go<5>(N); + //go<4>(N); + //go<3>(N); + go<2>(N); + //go<1>(N); cerr << endl; return 0; diff --git a/Triangulation/test/Triangulation/test_triangulation.cpp b/Triangulation/test/Triangulation/test_triangulation.cpp index 96f427efea1..8f6bd1f6453 100644 --- a/Triangulation/test/Triangulation/test_triangulation.cpp +++ b/Triangulation/test/Triangulation/test_triangulation.cpp @@ -119,10 +119,10 @@ int main(int argc, char **argv) int N = 1000; if( argc > 1 ) N = atoi(argv[1]); - go<5>(N); - go<3>(N); + //go<5>(N); + //go<3>(N); go<2>(N); - go<1>(N); + //go<1>(N); cerr << std::endl; return 0; diff --git a/Triangulation_2/applications/Triangulation_2/data/points.cin b/Triangulation_2/applications/Triangulation_2/data/points.cin new file mode 100644 index 00000000000..52e8743d807 --- /dev/null +++ b/Triangulation_2/applications/Triangulation_2/data/points.cin @@ -0,0 +1,10 @@ +0.0071 1.6899 0 +0.3272 1.3694 0.05 +1.3697 1.8296 0.1 +0.6722 0.3012 0.15 +1.1726 0.1899 0.2 +0.4374 2.8541 0.25 +2.5923 0.1904 0.3 +1.3083 2.5462 0.35 +1.4981 1.3929 0.4 +2.1304 2.055 0.45 \ No newline at end of file diff --git a/Triangulation_2/applications/Triangulation_2/points_to_RT2_to_off.cpp b/Triangulation_2/applications/Triangulation_2/points_to_RT2_to_off.cpp new file mode 100644 index 00000000000..f7a18fb81cb --- /dev/null +++ b/Triangulation_2/applications/Triangulation_2/points_to_RT2_to_off.cpp @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Regular_triangulation_filtered_traits_2 Traits; +typedef CGAL::Regular_triangulation_2 Regular_triangulation; + +int main() +{ + std::ifstream in("data/points.cin"); + + Regular_triangulation::Weighted_point wp; + std::vector wpoints; + + while(in >> wp) + wpoints.push_back(wp); + + Regular_triangulation rt(wpoints.begin(), wpoints.end()); + std::ofstream off_stream("data/rt2.off"); + CGAL::export_triangulation_2_to_off(off_stream, rt); + return 0; +} diff --git a/Triangulation_2/include/CGAL/IO/Triangulation_off_ostream_2.h b/Triangulation_2/include/CGAL/IO/Triangulation_off_ostream_2.h new file mode 100644 index 00000000000..a4cd70e8e0d --- /dev/null +++ b/Triangulation_2/include/CGAL/IO/Triangulation_off_ostream_2.h @@ -0,0 +1,79 @@ +// 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_OFF_OSTREAM_2_H +#define CGAL_TRIANGULATION_OFF_OSTREAM_2_H + +#include +#include +#include + +namespace CGAL { + +template < class GT, class TDS > +std::ostream & +export_triangulation_2_to_off(std::ostream & os, + const Triangulation_2 & tr) +{ + typedef Triangulation_2 Tr; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Vertex_iterator Vertex_iterator; + typedef typename Tr::Finite_vertices_iterator Finite_vertex_iterator; + typedef typename Tr::Finite_faces_iterator Finite_faces_iterator; + + size_t n = tr.number_of_vertices(); + + std::stringstream output; + + // write the vertices + std::map index_of_vertex; + int i = 0; + for(Finite_vertex_iterator it = tr.finite_vertices_begin(); + it != tr.finite_vertices_end(); ++it, ++i) + { + output << it->point().x() << " " << it->point().y() << " 0" << std::endl; + index_of_vertex[it.base()] = i; + } + CGAL_assertion( i == n ); + + size_t number_of_triangles = 0; + + for (Finite_faces_iterator fit = tr.finite_faces_begin() ; + fit != tr.finite_faces_end() ; ++fit) + { + output << "3 " + << index_of_vertex[fit->vertex(0)] << " " + << index_of_vertex[fit->vertex(1)] << " " + << index_of_vertex[fit->vertex(2)] + << std::endl; + ++number_of_triangles; + } + + os << "OFF \n" + << n << " " + << number_of_triangles << " 0\n" + << output.str(); + + return os; +} + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_OFF_OSTREAM_2_H \ No newline at end of file diff --git a/Triangulation_3/applications/Triangulation_3/data/points.cin b/Triangulation_3/applications/Triangulation_3/data/points.cin new file mode 100644 index 00000000000..5f2f53d1426 --- /dev/null +++ b/Triangulation_3/applications/Triangulation_3/data/points.cin @@ -0,0 +1,10 @@ +0.0071 1.6899 2.521 0 +0.3272 1.3694 3.15 0.05 +1.3697 1.8296 2.654 0.1 +0.6722 0.3012 0.1548 0.15 +1.1726 0.1899 0.3658 0.2 +0.4374 2.8541 1.45894 0.25 +2.5923 0.1904 0.6971 0.3 +1.3083 2.5462 1.3658 0.35 +1.4981 1.3929 2.949 0.4 +2.1304 2.055 0.6597455 0.45 \ No newline at end of file diff --git a/Triangulation_3/applications/Triangulation_3/points_to_RT3_to_off.cpp b/Triangulation_3/applications/Triangulation_3/points_to_RT3_to_off.cpp new file mode 100644 index 00000000000..4dffb3ea265 --- /dev/null +++ b/Triangulation_3/applications/Triangulation_3/points_to_RT3_to_off.cpp @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Regular_triangulation_euclidean_traits_3 Traits; +typedef CGAL::Regular_triangulation_3 Regular_triangulation; + +int main() +{ + std::ifstream in("data/points.cin"); + + Regular_triangulation::Weighted_point wp; + std::vector wpoints; + + while(in >> wp) + wpoints.push_back(wp); + + Regular_triangulation rt(wpoints.begin(), wpoints.end()); + std::ofstream off_stream("data/rt3.off"); + CGAL::export_triangulation_3_to_off(off_stream, rt); + return 0; +} diff --git a/Triangulation_3/include/CGAL/IO/Triangulation_off_ostream_3.h b/Triangulation_3/include/CGAL/IO/Triangulation_off_ostream_3.h new file mode 100644 index 00000000000..b6287f71d52 --- /dev/null +++ b/Triangulation_3/include/CGAL/IO/Triangulation_off_ostream_3.h @@ -0,0 +1,119 @@ +// 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_OFF_OSTREAM_3_H +#define CGAL_TRIANGULATION_OFF_OSTREAM_3_H + +#include +#include +#include + +namespace CGAL { + +template < class GT, class TDS > +std::ostream & +export_triangulation_3_to_off(std::ostream & os, + const Triangulation_3 & tr, + bool export_surface_only = false) +{ + typedef Triangulation_3 Tr; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Vertex_iterator Vertex_iterator; + typedef typename Tr::Finite_vertices_iterator Finite_vertex_iterator; + typedef typename Tr::All_cells_iterator Cells_iterator; + typedef typename Tr::Finite_cells_iterator Finite_cells_iterator; + + size_t n = tr.number_of_vertices(); + + std::stringstream output; + + // write the vertices + std::map index_of_vertex; + int i = 0; + for(Finite_vertex_iterator it = tr.finite_vertices_begin(); + it != tr.finite_vertices_end(); ++it, ++i) + { + output << it->point().x() << " " + << it->point().y() << " " + << it->point().z() << std::endl; + index_of_vertex[it.base()] = i; + } + CGAL_assertion( i == n ); + + size_t number_of_triangles = 0; + + if (export_surface_only) + { + for (Cells_iterator cit = tr.cells_begin() ; + cit != tr.cells_end() ; ++cit) + { + if (tr.is_infinite(cit)) + { + output << "3 "; + for (int i = 0 ; i < 4 ; ++i) + { + if (!tr.is_infinite(cit->vertex(i))) + output << index_of_vertex[cit->vertex(i)] << " "; + } + output << std::endl; + ++number_of_triangles; + } + } + } + else + { + for (Finite_cells_iterator cit = tr.finite_cells_begin() ; + cit != tr.finite_cells_end() ; ++cit) + { + output << "3 " + << index_of_vertex[cit->vertex(0)] << " " + << index_of_vertex[cit->vertex(1)] << " " + << index_of_vertex[cit->vertex(2)] + << std::endl; + output << "3 " + << index_of_vertex[cit->vertex(0)] << " " + << index_of_vertex[cit->vertex(2)] << " " + << index_of_vertex[cit->vertex(3)] + << std::endl; + output << "3 " + << index_of_vertex[cit->vertex(1)] << " " + << index_of_vertex[cit->vertex(2)] << " " + << index_of_vertex[cit->vertex(3)] + << std::endl; + output << "3 " + << index_of_vertex[cit->vertex(0)] << " " + << index_of_vertex[cit->vertex(1)] << " " + << index_of_vertex[cit->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_OFF_OSTREAM_3_H \ No newline at end of file