diff --git a/.gitattributes b/.gitattributes index 5fddd29d4ff..0b7e88f5331 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1281,6 +1281,131 @@ Circular_kernel_3/test/Circular_kernel_3/test_Lazy_spherical_kernel_basics.cpp - Circular_kernel_3/test/Circular_kernel_3/test_Spherical_kernel_basics.cpp -text Circular_kernel_3/test/Circular_kernel_3/test_Spherical_kernel_with_core.cpp -text Circulator/doc_tex/Circulator/circulator.png -text +Combinatorial_map/doc_tex/Combinatorial_map/Combinatorial_map.tex -text +Combinatorial_map/doc_tex/Combinatorial_map/PkgDescription.tex -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/Diagramme_class.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte-3d-sew.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte-3d-sew2.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte2-3d.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-edge.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-facet.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-vertex.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-map.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-map2d.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-zoom.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-zoom2.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/map2d-with-attrib.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/object2d-nonmanifold.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/object2d.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d-nonmanifold.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d-nonmanifold2.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/ope1.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/ope2.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/ope3.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pb-carte3D.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pb2-carte3D.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/Diagramme_class.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte-3d-sew.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte-3d-sew2.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte2-3d.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-edge.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-facet.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-vertex.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-map.pdf -text svneol=unset#unset +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-map2d.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-zoom.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-zoom2.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/map2d-with-attrib.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object2d-nonmanifold.pdf -text svneol=unset#unset +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object2d.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d-nonmanifold.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d-nonmanifold2.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope1.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope2.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope3.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/pb-carte3D.pdf -text svneol=unset#unset +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/pb2-carte3D.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/quasivariete.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/quasivarietea.pdf -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/triangulation.pdf -text svneol=unset#unset +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/Diagramme_class.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte-3d-sew.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte-3d-sew2.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte2-3d.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-edge.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-facet.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-vertex.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-map.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-map2d.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-zoom.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-zoom2.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/map2d-with-attrib.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object2d-nonmanifold.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object2d.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d-nonmanifold.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d-nonmanifold2.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope1.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope2.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope3.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/pb-carte3D.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/pb2-carte3D.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/quasivariete.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/quasivarietea.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/png/triangulation.png -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/quasivariete.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/quasivarietea.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/fig/triangulation.fig -text +Combinatorial_map/doc_tex/Combinatorial_map/main.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/CellAttribute.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/Cell_attribute.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/CombinatorialMap.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/CombinatorialMapItems.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_constructors.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_min_items.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_operations.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/Dart.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/Dart_base.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/intro.tex -text +Combinatorial_map/doc_tex/Combinatorial_map_ref/main.tex -text +Combinatorial_map/doc_tex/wrapper.tex -text +Combinatorial_map/dont_submit -text +Combinatorial_map/examples/Combinatorial_map/CMakeLists.txt -text +Combinatorial_map/examples/Combinatorial_map/map_3_marks.cpp -text +Combinatorial_map/examples/Combinatorial_map/map_3_operations.cpp -text +Combinatorial_map/examples/Combinatorial_map/map_3_simple_example.cpp -text +Combinatorial_map/examples/Combinatorial_map/map_3_with_colored_facets.cpp -text +Combinatorial_map/examples/Combinatorial_map/map_4_simple_example.cpp -text +Combinatorial_map/include/CGAL/Cell_attribute.h -text +Combinatorial_map/include/CGAL/Cell_const_iterators.h -text +Combinatorial_map/include/CGAL/Cell_iterators.h -text +Combinatorial_map/include/CGAL/Combinatorial_map.h -text +Combinatorial_map/include/CGAL/Combinatorial_map_basic_operations.h -text +Combinatorial_map/include/CGAL/Combinatorial_map_constructors.h -text +Combinatorial_map/include/CGAL/Combinatorial_map_min_items.h -text +Combinatorial_map/include/CGAL/Combinatorial_map_operations.h -text +Combinatorial_map/include/CGAL/Dart.h -text +Combinatorial_map/include/CGAL/Dart_const_iterators.h -text +Combinatorial_map/include/CGAL/Dart_iterators.h -text +Combinatorial_map/include/CGAL/internal/Combinatorial_map_functors.h -text +Combinatorial_map/include/CGAL/internal/Combinatorial_map_utility.h -text +Combinatorial_map/package_info/Combinatorial_map/description.txt -text +Combinatorial_map/package_info/Combinatorial_map/long_description.txt -text +Combinatorial_map/package_info/Combinatorial_map/maintainer -text +Combinatorial_map/test/Combinatorial_map/CMakeLists.txt -text +Combinatorial_map/test/Combinatorial_map/Combinatorial_map_2_test.h -text +Combinatorial_map/test/Combinatorial_map/Combinatorial_map_3_test.h -text +Combinatorial_map/test/Combinatorial_map/Combinatorial_map_test.cpp -text +Combinatorial_map/test/Combinatorial_map/data/aircraft.off -text +Combinatorial_map/test/Combinatorial_map/data/points -text +Combinatorial_map/test/Combinatorial_map/data/small_points -text +Combinatorial_map/test/Combinatorial_map/data/small_points2 -text Convex_decomposition_3/demo/Convex_decomposition_3/star.nef3 -text Convex_decomposition_3/doc_tex/Convex_decomposition_3/PkgDescription.tex -text Convex_decomposition_3/doc_tex/Convex_decomposition_3/fig/teaser.png -text diff --git a/Algebraic_kernel_d/include/CGAL/RS/isole_1.h b/Algebraic_kernel_d/include/CGAL/RS/isole_1.h index d8d86f18779..407a80f5694 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/isole_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/isole_1.h @@ -56,7 +56,7 @@ isolator >::operator()(const Polynomial &p, mpz_t *coeffs=(mpz_t*)malloc((degree+1)*sizeof(mpz_t)); mpfi_ptr *intervals_mpfi=(mpfi_ptr*)malloc(degree*sizeof(mpfi_ptr)); std::vector intervals; - for(int i=0;i<=degree;++i) + for(unsigned int i=0;i<=degree;++i) coeffs[i][0]=*(p[i].mpz()); init_solver(); create_rs_upoly(coeffs,degree,rs_get_default_up()); diff --git a/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt b/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt index 99c568e337f..866e4fdf4ba 100644 --- a/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt +++ b/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt @@ -41,15 +41,19 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "Algebraic_kernel_d_1_CORE.cpp" ) create_single_source_cgal_program( "Algebraic_kernel_d_1_GMP.cpp" ) create_single_source_cgal_program( "Algebraic_kernel_d_2.cpp" ) - create_single_source_cgal_program( "Algebraic_kernel_rs_gmpq_d_1.cpp" ) - create_single_source_cgal_program( "Algebraic_kernel_rs_gmpz_d_1.cpp" ) create_single_source_cgal_program( "Algebraic_real_d_1.cpp" ) create_single_source_cgal_program( "Bitstream_descartes.cpp" ) create_single_source_cgal_program( "Curve_analysis_2.cpp" ) create_single_source_cgal_program( "Curve_pair_analysis_2.cpp" ) create_single_source_cgal_program( "Descartes.cpp" ) create_single_source_cgal_program( "Real_embeddable_traits_extension.cpp" ) - create_single_source_cgal_program( "rs_isolator.cpp" ) + if(RS_FOUND) + create_single_source_cgal_program( "Algebraic_kernel_rs_gmpq_d_1.cpp" ) + create_single_source_cgal_program( "Algebraic_kernel_rs_gmpz_d_1.cpp" ) + create_single_source_cgal_program( "rs_isolator.cpp" ) + else() + message(STATUS "NOTICE: Some tests require the RS library, and will not be compiled.") + endif() else() diff --git a/Alpha_shapes_2/include/CGAL/Alpha_shape_2.h b/Alpha_shapes_2/include/CGAL/Alpha_shape_2.h index c7b3bf80f02..3f591c79e32 100644 --- a/Alpha_shapes_2/include/CGAL/Alpha_shape_2.h +++ b/Alpha_shapes_2/include/CGAL/Alpha_shape_2.h @@ -1406,6 +1406,8 @@ Alpha_shape_2
::find_alpha_solid() const // starting point for searching // takes O(#alpha_shape) time Coord_type alpha_solid = 0; + + if (number_of_vertices()<3) return alpha_solid; Finite_vertices_iterator vertex_it; // only finite vertices diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2.h index bfaaf1f1976..6fa25e9b896 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_2_impl.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_2_impl.h index f6306c31f92..e50f3777832 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_2_impl.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_2_impl.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas #ifndef CGAL_APOLLONIUS_GRAPH_2_IMPL_H diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_hierarchy_2_impl.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_hierarchy_2_impl.h index 18c70f27d17..bcee91c165f 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_hierarchy_2_impl.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_hierarchy_2_impl.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas #ifndef CGAL_APOLLONIUS_GRAPH_HIERARCHY_2_IMPL_H #define CGAL_APOLLONIUS_GRAPH_HIERARCHY_2_IMPL_H diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Bounded_side_of_ccw_circle_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Bounded_side_of_ccw_circle_C2.h index 4f91fe57643..53ce876175c 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Bounded_side_of_ccw_circle_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Bounded_side_of_ccw_circle_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_weight_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_weight_2.h index a3ed45a77a6..6c73d29c505 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_weight_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_weight_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_x_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_x_2.h index ebe2429f03d..b7278070951 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_x_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_x_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_y_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_y_2.h index 26965d5eb14..3ffd57d4c3a 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_y_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Compare_y_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_C2.h index e1700376ced..fda0b0b99ab 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_ftC2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_ftC2.h index 0791248fd85..d15feb7849b 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_ftC2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_ftC2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_rtH2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_rtH2.h index 32a8ba782b1..cad16f60c20 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_rtH2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Constructions_rtH2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_mixed_filtered_traits_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_mixed_filtered_traits_2.h index e0e2fb12336..78052a34d2b 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_mixed_filtered_traits_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_mixed_filtered_traits_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_mixed_traits_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_mixed_traits_2.h index de63dcab68b..8246e457105 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_mixed_traits_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_mixed_traits_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas // Christophe Delage // David Millman diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_new_filtered_traits_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_new_filtered_traits_2.h index 9e204547b4a..af7fc9f8b53 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_new_filtered_traits_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_new_filtered_traits_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_new_traits_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_new_traits_2.h index 4de67913414..b9bf3b4d65e 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_new_traits_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_new_traits_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas // Christophe Delage // David Millman diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Conflict_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Conflict_2.h index d96eca823c8..09af8cabb03 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Conflict_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Conflict_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas // Christophe Delage // David Millman diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Edge_conflict_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Edge_conflict_2.h index 60bbe4c25d3..6963698ef43 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Edge_conflict_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Edge_conflict_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas // Christophe Delage // David Millman diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Finite_edge_conflict_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Finite_edge_conflict_2.h index a8b445f35f0..6e15eb48843 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Finite_edge_conflict_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Finite_edge_conflict_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas // Christophe Delage // David Millman diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Infinite_edge_conflict_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Infinite_edge_conflict_2.h index 639dd51cd84..53a6f816f3e 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Infinite_edge_conflict_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Infinite_edge_conflict_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas // Christophe Delage // David Millman diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/New_predicates_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/New_predicates_C2.h index 7b4c5191ff4..68a554f6eb1 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/New_predicates_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/New_predicates_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Orientation_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Orientation_2.h index 6445c6aebcc..dc90290b563 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Orientation_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Orientation_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas // Christophe Delage // David Millman diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Vertex_conflict_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Vertex_conflict_2.h index db7dfb0d80b..59771d75284 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Vertex_conflict_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Delage_traits/Vertex_conflict_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas // Christophe Delage // David Millman diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Finite_edge_test8_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Finite_edge_test8_C2.h index e91542ce247..092e29e2044 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Finite_edge_test8_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Finite_edge_test8_C2.h @@ -1,4 +1,4 @@ -// Copyright (c) 2007 Foundation for Research and Technology-Hellas (Greece). +// Copyright (c) 2007 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Finite_edge_test_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Finite_edge_test_C2.h index c5736ac4e8c..1752789e19e 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Finite_edge_test_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Finite_edge_test_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Incircle8_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Incircle8_C2.h index f7d57da1457..fbfeb7b119f 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Incircle8_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Incircle8_C2.h @@ -1,4 +1,4 @@ -// Copyright (c) 2007 Foundation for Research and Technology-Hellas (Greece). +// Copyright (c) 2007 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Incircle_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Incircle_C2.h index 4e44b631967..f9e2a7d1741 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Incircle_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Incircle_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Infinite_edge_test_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Infinite_edge_test_C2.h index 38700409fc5..ca9302b9ec2 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Infinite_edge_test_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Infinite_edge_test_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Is_degenerate_edge_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Is_degenerate_edge_C2.h index 37fbd5e78a7..6965d6b24d2 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Is_degenerate_edge_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Is_degenerate_edge_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Is_hidden_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Is_hidden_C2.h index 57350931520..66020be1445 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Is_hidden_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Is_hidden_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Kernel_wrapper_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Kernel_wrapper_2.h index bbf5d0875ab..1aaf0eb5bc9 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Kernel_wrapper_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Kernel_wrapper_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Orientation8_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Orientation8_C2.h index 21f1b99ccb6..e7b4599b1bb 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Orientation8_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Orientation8_C2.h @@ -1,4 +1,4 @@ -// Copyright (c) 2007 Foundation for Research and Technology-Hellas (Greece). +// Copyright (c) 2007 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Orientation_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Orientation_2.h index 35f257cd661..b0f3d5f33a3 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Orientation_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Orientation_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Oriented_side_of_bisector_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Oriented_side_of_bisector_C2.h index e54eb05b5e1..3059d74993c 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Oriented_side_of_bisector_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Oriented_side_of_bisector_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Predicate_constructions_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Predicate_constructions_C2.h index b3e087255cd..9c9e908c77b 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Predicate_constructions_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Predicate_constructions_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Predicates_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Predicates_C2.h index 08f926de950..67190999f8e 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Predicates_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Predicates_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Traits_wrapper_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Traits_wrapper_2.h index d0d946cbe77..651829c32ba 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Traits_wrapper_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Traits_wrapper_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/basic.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/basic.h index b4a6ff0471d..c577ad90e6c 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/basic.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/basic.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas #ifndef CGAL_APOLLONIUS_GRAPH_2_BASIC_H #define CGAL_APOLLONIUS_GRAPH_2_BASIC_H 1 diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/check_filter.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/check_filter.h index a52a74dab36..3654fddd46a 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/check_filter.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/check_filter.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/comparator_profiler.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/comparator_profiler.h index 898961721cc..4246e802383 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/comparator_profiler.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/comparator_profiler.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/compare_quadratic.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/compare_quadratic.h index 81325a3011a..a8561b60f62 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/compare_quadratic.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/compare_quadratic.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/predicate_profiler.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/predicate_profiler.h index 057db54b6b7..fcb966f1119 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/predicate_profiler.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/predicate_profiler.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Apollonius_graph_uncertain_filtered_traits_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Apollonius_graph_uncertain_filtered_traits_2.h index d5e0ce69217..7b531258f69 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Apollonius_graph_uncertain_filtered_traits_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Apollonius_graph_uncertain_filtered_traits_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_is_hidden_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_is_hidden_C2.h index ea0c36704d6..1278be7d648 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_is_hidden_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_is_hidden_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_oriented_side_of_bisector_C2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_oriented_side_of_bisector_C2.h index 4c6f26d0df7..1ffef81e6bd 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_oriented_side_of_bisector_C2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_oriented_side_of_bisector_C2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_vertex_conflict_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_vertex_conflict_2.h index 58c0b38b928..34a26a2096a 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_vertex_conflict_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/Uncertain_vertex_conflict_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas // Christophe Delage // David Millman diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/uncertain_functions_on_signs.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/uncertain_functions_on_signs.h index 23bce6de9f7..d25747340e8 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/uncertain_functions_on_signs.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/uncertain/uncertain_functions_on_signs.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_data_structure_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_data_structure_2.h index 88f3647ca5c..5f6175447b3 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_data_structure_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_data_structure_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_filtered_traits_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_filtered_traits_2.h index a29f7a73402..a922ab4c441 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_filtered_traits_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_filtered_traits_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_hierarchy_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_hierarchy_2.h index 4d06ce76313..5cf75a75ab4 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_hierarchy_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_hierarchy_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas #ifndef CGAL_APOLLONIUS_GRAPH_HIERARCHY_2_H #define CGAL_APOLLONIUS_GRAPH_HIERARCHY_2_H diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h index d8de07c78a4..c4858867c44 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas #ifndef CGAL_APOLLONIUS_GRAPH_HIERARCHY_VERTEX_BASE_2_H #define CGAL_APOLLONIUS_GRAPH_HIERARCHY_VERTEX_BASE_2_H diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_traits_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_traits_2.h index 53876508623..664f4a2f18b 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_traits_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_traits_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas #ifndef CGAL_APOLLONIUS_GRAPH_TRAITS_2_H #define CGAL_APOLLONIUS_GRAPH_TRAITS_2_H diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_vertex_base_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_vertex_base_2.h index 683d6c2091a..56e17c900ce 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_vertex_base_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_vertex_base_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas #ifndef CGAL_APOLLONIUS_GRAPH_VERTEX_BASE_2_H #define CGAL_APOLLONIUS_GRAPH_VERTEX_BASE_2_H diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_site_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_site_2.h index 0042607dcc4..fbae0de359a 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_site_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_site_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas #ifndef CGAL_APOLLONIUS_SITE_2_H #define CGAL_APOLLONIUS_SITE_2_H diff --git a/Apollonius_graph_2/include/CGAL/Hyperbola_2.h b/Apollonius_graph_2/include/CGAL/Hyperbola_2.h index 3fa69cb8b0f..7749e5f75b0 100644 --- a/Apollonius_graph_2/include/CGAL/Hyperbola_2.h +++ b/Apollonius_graph_2/include/CGAL/Hyperbola_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Hyperbola_ray_2.h b/Apollonius_graph_2/include/CGAL/Hyperbola_ray_2.h index 2b72ea40e47..b6ddb559483 100644 --- a/Apollonius_graph_2/include/CGAL/Hyperbola_ray_2.h +++ b/Apollonius_graph_2/include/CGAL/Hyperbola_ray_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Hyperbola_segment_2.h b/Apollonius_graph_2/include/CGAL/Hyperbola_segment_2.h index 79cf1dc8a4f..410f0b39f6e 100644 --- a/Apollonius_graph_2/include/CGAL/Hyperbola_segment_2.h +++ b/Apollonius_graph_2/include/CGAL/Hyperbola_segment_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/IO/Qt_widget_Apollonius_site_2.h b/Apollonius_graph_2/include/CGAL/IO/Qt_widget_Apollonius_site_2.h index c3640af1e20..b460963d34a 100644 --- a/Apollonius_graph_2/include/CGAL/IO/Qt_widget_Apollonius_site_2.h +++ b/Apollonius_graph_2/include/CGAL/IO/Qt_widget_Apollonius_site_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas #ifndef CGAL_QT_WIDGET_APOLLONIUS_SITE_2_H diff --git a/Apollonius_graph_2/include/CGAL/IO/Qt_widget_Hyperbola_2.h b/Apollonius_graph_2/include/CGAL/IO/Qt_widget_Hyperbola_2.h index d842c96050d..fba6df4eee6 100644 --- a/Apollonius_graph_2/include/CGAL/IO/Qt_widget_Hyperbola_2.h +++ b/Apollonius_graph_2/include/CGAL/IO/Qt_widget_Hyperbola_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas #ifndef CGAL_QT_WIDGET_HYPERBOLA_2_H #define CGAL_QT_WIDGET_HYPERBOLA_2_H diff --git a/Apollonius_graph_2/include/CGAL/Parabola_2.h b/Apollonius_graph_2/include/CGAL/Parabola_2.h index c89cf16a410..6e06222fc27 100644 --- a/Apollonius_graph_2/include/CGAL/Parabola_2.h +++ b/Apollonius_graph_2/include/CGAL/Parabola_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/Parabola_segment_2.h b/Apollonius_graph_2/include/CGAL/Parabola_segment_2.h index 38f4a10320f..9ee8a94e1f2 100644 --- a/Apollonius_graph_2/include/CGAL/Parabola_segment_2.h +++ b/Apollonius_graph_2/include/CGAL/Parabola_segment_2.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/functions_on_signs.h b/Apollonius_graph_2/include/CGAL/functions_on_signs.h index 34214bccafb..517a6a11cc4 100644 --- a/Apollonius_graph_2/include/CGAL/functions_on_signs.h +++ b/Apollonius_graph_2/include/CGAL/functions_on_signs.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/in_place_edge_list.h b/Apollonius_graph_2/include/CGAL/in_place_edge_list.h index 38af54a0d03..1ac3a6095f3 100644 --- a/Apollonius_graph_2/include/CGAL/in_place_edge_list.h +++ b/Apollonius_graph_2/include/CGAL/in_place_edge_list.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/Apollonius_graph_2/include/CGAL/more_functions_on_signs.h b/Apollonius_graph_2/include/CGAL/more_functions_on_signs.h index 97eb4fd9cdb..ab14c193590 100644 --- a/Apollonius_graph_2/include/CGAL/more_functions_on_signs.h +++ b/Apollonius_graph_2/include/CGAL/more_functions_on_signs.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Menelaos Karavelas +// Author(s) : Menelaos Karavelas diff --git a/BGL/doc_tex/BGL_ref/HalfedgeGraph.tex b/BGL/doc_tex/BGL_ref/HalfedgeGraph.tex index d9d09a5e005..25fdbfc5452 100644 --- a/BGL/doc_tex/BGL_ref/HalfedgeGraph.tex +++ b/BGL/doc_tex/BGL_ref/HalfedgeGraph.tex @@ -30,7 +30,7 @@ for the vertices and edges such that the ordered edges do not intersect. \ccRefines -\ccAnchor{http://www.boost.org/libs/graph/doc/IncidenceGraph.html}{IncidenceGraph}\\ +\ccAnchor{http://www.boost.org/libs/graph/doc/BidirectionalGraph.html}{BidirectionalGraph}\\ \ccAnchor{http://www.boost.org/libs/graph/doc/PropertyGraph.html}{PropertyGraph} A model of \ccRefName\ must have the {\em interior properties} diff --git a/BGL/include/CGAL/boost/graph/halfedge_graph_traits_Polyhedron_3.h b/BGL/include/CGAL/boost/graph/halfedge_graph_traits_Polyhedron_3.h index 763e5d8dbb4..95a347fc37f 100644 --- a/BGL/include/CGAL/boost/graph/halfedge_graph_traits_Polyhedron_3.h +++ b/BGL/include/CGAL/boost/graph/halfedge_graph_traits_Polyhedron_3.h @@ -96,21 +96,21 @@ opposite_edge( typename boost::graph_traits< Polyhedron_3 const>::ed template typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor -next_edge_ccw( typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor outedge +next_edge_ccw( typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor inedge , Polyhedron_3 const& ) { HalfedgeDS_items_decorator< Polyhedron_3 > D ; - return D.get_prev(outedge)->opposite(); + return D.get_prev(inedge->opposite()); } template typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor -next_edge_cw( typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor outedge +next_edge_cw( typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor inedge , Polyhedron_3 const& ) { - return outedge->opposite()->next(); + return inedge->next()->opposite(); } diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b768c31f2b..94e613318cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,9 +22,25 @@ if ( ${CGAL_SCM_NAME} STREQUAL "svn" ) find_program(SVN_EXECUTABLE svn DOC "subversion command line client") - # TODO detect name - set ( CGAL_SCM_BRANCH_NAME "n/a" ) + function(Subversion_GET_URL dir variable) + # use svnversion + execute_process(COMMAND "${SVN_EXECUTABLE}" info --xml "${dir}" + OUTPUT_VARIABLE ${variable} + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX REPLACE ".*([^<]+).*" "\\1" ${variable} "${${variable}}") + if(NOT variable) + message("Warning: can not get the Subversion URL of directory ${dir}") + endif() + set(${variable} ${${variable}} PARENT_SCOPE) + endfunction(Subversion_GET_URL) + Subversion_GET_URL("${CGAL_INSTALLATION_PACKAGE_DIR}" CGAL_INSTALLATION_SVN_URL) + # Remove the "/Installation" suffix. + string(REGEX REPLACE "(.*)/Installation" "\\1" CGAL_TMP_SVN_BRANCH_NAME "${CGAL_INSTALLATION_SVN_URL}") + # Remove the prefix of the URL "https://scm.gforge.inria.fr/". + string(REGEX REPLACE "[a-z+]+://[a-z0-9.]+" "" CGAL_TMP_SVN_BRANCH_NAME "${CGAL_TMP_SVN_BRANCH_NAME}") + + set ( CGAL_SCM_BRANCH_NAME "${CGAL_TMP_SVN_BRANCH_NAME}" ) endif() if ( ${CGAL_SCM_NAME} STREQUAL "git" ) diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/Combinatorial_map.tex b/Combinatorial_map/doc_tex/Combinatorial_map/Combinatorial_map.tex new file mode 100644 index 00000000000..550fccdc7f0 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map/Combinatorial_map.tex @@ -0,0 +1,2261 @@ +\def\ccTagRmTrailingConst{\ccFalse} + +\newcommand{\mb}[1]{\beta_{#1}} +\newcommand{\orb}[1]{\langle{}#1\rangle{}} +\newcommand{\nulldart}{\texttt{null\_dart\_handle}} + +\section{Introduction} +A $d$D combinatorial map is a data structure representing an +orientable subdivided $d$D % \emph{quasi-manifold}, \emph{i.e.} a $d$D +object obtained by taking $d$D cells, and allowing to glue $d$D cells +along $(d-1)$D cells. It provides a description of all the cells of +the subdivision (for example vertices and edges), together with incidence +and adjacency relationships. This package is a generalization of the +halfedge data structure to higher dimension.\footnote{A 2D + combinatorial map is equivalent to a halfedge data structure: there + is a one-to-one mapping between elements of both data structures, + halfedges corresponding to darts.} + +We denote $i$-cell for an $i$-dimensional cell (for example in 3D, +0-cells are \emph{vertices}, 1-cells are \emph{edges}, 2-cells are +\emph{facets}, and 3-cells are \emph{volumes}). A \emph{boundary + relation} is defined on these cells, giving for each $i$-cell $c$ +the set of $(i-1)$-cells contained in the boundary of $c$. Two cells +$c_1$ and $c_2$ are \emph{incident} if there is a path of cells, +starting from the cell of biggest dimension to the other cell, such +that each cell of the path (except the first one) belongs to the +boundary of the previous cell in the path. Two $i$-cells $c$ and $c'$ +are \emph{adjacent} if there is an $(i-1)$-cell incident to both $c$ +and $c'$. You can see an example of a 2D object and a 3D object in +Figure~\ref{fig-exemple-3Dmanifold} showing some cells of the +subdivision and some adjacency and incidence relations. +\begin{figure}[ht] + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=.3\textwidth] + {Combinatorial_map/fig/pdf/object2d} + \qquad + \includegraphics[width=.4\textwidth] + {Combinatorial_map/fig/pdf/intuitif-example} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ + +
+ \end{ccHtmlOnly} + \caption{Example of subdivided objects that can be described by + combinatorial maps. \textbf{Left}: A 2D object composed of + three facets ($2$-cells), named $f_1$, $f_2$ and $f_3$, nine + edges ($1$-cells) and seven vertices ($0$-cells). $f_1$ and + $f_2$ are adjacent along edge $e_1$, thus $e_1$ is incident both + to $f_1$ and $f_2$. Vertex $v_1$ is incident to edge $e_1$, thus + $v_1$ is incident to $f_1$ and $f_2$ by transitivity. + \textbf{Right}: A 3D object (only partially represented for vertices and edges) + composed of three volumes ($3$-cells), named $vol_1$, $vol_2$ + and $vol_3$, twelve facets ($2$-cells) (there is one facet + $f_4$ between $vol_1$ and $vol_2$, and similarly between $vol_1$ + and $vol_3$ and $vol_2$ and $vol_3$), sixteen edges ($1$-cells), + and eight vertices ($0$-cells). $vol_1$ and $vol_2$ are adjacent + along facet $f_4$, thus $f_4$ is incident both to $vol_1$ and + $vol_2$. Edge $e_4$ is incident to the three facets between + $vol_1$ and $vol_2$, $vol_1$ and $vol_3$, and $vol_2$ and + $vol_3$. $e_4$ is also incident to the three volumes by + transitivity.} + \label{fig-exemple-3Dmanifold} +\end{figure} + +A combinatorial map is an edge-centered data structure describing the +cells and the incidence and adjacency relations, using only one basic +element called \emph{dart}, and a set of \emph{pointers} between these +darts. A dart can be thought as a part of an oriented edge (1-cell), +together with a part of incident cells of dimensions 0, 2, 3,\ldots, +$d$. When a dart $d_0$ describe a part of an $i$-cell $c$, we say that +$d_0$ \emph{belongs} to $c$, and that $c$ \emph{contains} $d_0$. Let +us look at the example in Figure~\ref{fig-exemple-combi-maps} showing +the 2D and 3D combinatorial maps describing the two objects given in +Figure~\ref{fig-exemple-3Dmanifold}. +\begin{figure}[ht] + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=.3\textwidth] + {Combinatorial_map/fig/pdf/intuitif-example-map2d} + \qquad + \includegraphics[width=.4\textwidth] + {Combinatorial_map/fig/pdf/intuitif-example-map} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ + +
+ \end{ccHtmlOnly} + \caption{Combinatorial maps representing the objects given in + Figure~\ref{fig-exemple-3Dmanifold}. + \textbf{Left}: The 2D combinatorial map which contains 12 darts. + \textbf{Right}: The 3D combinatorial map which contains 54 darts + (18 for each volume). + } + \label{fig-exemple-combi-maps} +\end{figure} + +First let us start in 2D (Figure~\ref{fig-exemple-combi-maps} (Left)). +Facet $f_1$ is described by four darts. These darts are linked +together with pointers. Starting from a dart and following a $\beta_1$ +pointer, we get to a dart which belongs to the same facet but to the +next edge (1-cell, which explains the index~$1$ of~$\beta_1$). +Starting from any dart and following $\beta_1$ pointers, we can reach +exactly all the darts describing the facet. Starting from a dart and +following a $\beta_2$ pointer, we get to a dart which belongs to the +same edge but to the neighboring facet (2-cell, which explains the +index~$2$ of~$\beta_2$). Starting from any dart and following +$\beta_2$ pointers, we can reach exactly all the darts describing the +edge (in 2D one or two darts). + +Things are slightly different for vertices. Indeed, each $\beta_i$ +points to a dart belonging to a different $i$-cell, but also to a +different $0$-cell (vertex). This is so because two linked darts have +opposite orientations. For this reason, starting from any dart +belonging to a vertex $v$, we have to follow $\beta_2$ then $\beta_1$ +to reach exactly the darts describing the vertex $v$. In fact, by +composing two $\beta_i$s, we always obtain a dart belonging to the +same vertex. + +The main interest of combinatorial map definition based on darts and +$\beta_i$ pointers is to be able to increase the dimension ``only'' by +adding new pointers. We can verify this fact by studying the 3D +example (Figure~\ref{fig-exemple-combi-maps} (Right)). In addition to +$\beta_1$ and $\beta_2$ of the 2D case, there is a new pointer +$\beta_3$. + +If we take a closer look at the central edge $e_4$ shown in +Figure~\ref{fig-intuitive-exemple} (Left), we can see that it is +described by six darts linked together. Starting from a dart and +following a $\beta_3$ pointer, we get to a dart which belongs to the +same edge, to the same facet, but to the neighboring volume (a 3-cell, +which explains the index $3$ in $\beta_3$). Similarly, starting from +a dart and following a $\beta_2$ pointer, we get to a dart which +belongs to the same edge, to the same volume, but to the neighboring +facet (2-cell). Starting from any of these six darts and following +$\beta_2$ and $\beta_3$ pointers, we can reach exactly the six darts +describing edge $e$. +% +% Finally, following a $\beta_1$ pointer, we get to a +% dart which belongs to the same facet, the same volume but on the +% neighboring edge (1-cell). +% +\def\LargFig{.3\textwidth} +\begin{figure} + \begin{ccTexOnly} + \begin{center} +% \includegraphics[width=\LargFig]{Combinatorial_map/fig/pdf/intuitif-example-map}\qquad + \includegraphics[width=\LargFig]{Combinatorial_map/fig/pdf/intuitif-example-zoom} + \includegraphics[width=\LargFig]{Combinatorial_map/fig/pdf/intuitif-example-zoom2} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ + + + + +
+ \end{ccHtmlOnly} + \caption{Two zooms on the 3D combinatorial map given in + Figure~\ref{fig-exemple-combi-maps} (Right). + \textbf{Left}:~Zoom around the central edge $e_4$ which details + the six darts belonging to the edge. \textbf{Right}:~Zoom + around the facet between volumes $vol_2$ and $vol_3$ which + details the eight darts belonging to the facet.} + \label{fig-intuitive-exemple} +\end{figure} + +% Things are quite similar to obtain the darts belonging to a facet +% rather than an edge (see Figure~\ref{fig-intuitive-exemple} (Right)). +For facets, by following a $\beta_1$ pointer, we get to a dart which +belongs to the same facet, to the same volume, but to the next edge +(1-cell, which explains the index~$1$ of~$\beta_1$). Starting from any +dart and following $\beta_1$ and $\beta_3$ pointers, we can reach +exactly all the darts describing the facet (see +Figure~\ref{fig-intuitive-exemple} (Right)). +% +For volumes, starting from any dart and following $\beta_1$ and +$\beta_2$ pointers, we can reach exactly all the darts describing the +volume. + +% Things are slightly different for vertices. Indeed, each $\beta_i$ +% points to a dart belonging to a different $i$-cell, but also to a +% different $0$-cell (vertex). +% In the above paragraphs, +% we explained that when following a $\beta_i$ pointer we change the +% $i$-cell. We have not mentioned that this also changes the 0-cell +% (vertex). +% This is so because two linked darts have opposite orientations. For +% this reason, starting from any dart belonging to a vertex $v$, we have +For vertices, we have to follow $\beta_2$ then $\beta_1$, and +$\beta_3$ then $\beta_1$ to reach exactly the darts describing the +vertex $v$. Indeed, as in 2D, we have to compose two $\beta_i$s to +obtain a dart belonging to the same vertex. + +In some cases, the general rule that by following a $\beta_i$ we get a +dart which belongs to the neighboring $i$-cell is not true, as for example +for darts belonging to the boundary of the represented +object. For example, in Figure~\ref{fig-exemple-3Dmanifold} (Left), any dart +$d_0$ that does not belong to edge $e_1$, $e_2$ and $e_3$ +belongs to a 2-cell, and there is no neighboring facet along the edge containing $d_0$. +% this is the +% case for $\beta_2$ for all the darts that does not belong to edge +% $e_1$, $e_2$ and $e_3$. +% Indeed, these darts belong to a 2-cell, and +% there is no neighboring facet along the edge containing these darts. +Another example is in Figure~\ref{fig-exemple-3Dmanifold} (Right), for +any dart $d_0$ that belongs to facet $f_5$. +% this is the case for +% $\beta_3$ for example for all the darts belonging to facet +% $f_5$. Indeed, these darts +$d_0$ belongs to volume $vol_2$, but there is no neighboring volume +along this facet. The general rule is also not true for unbounded +cells. For example if we remove a dart in +Figure~\ref{fig-exemple-combi-maps} (Left), we obtain an unbounded +facet having a dart without next dart for $\beta_1$, and if we remove +a facet in Figure~\ref{fig-exemple-combi-maps} (Right), we obtain an +unbounded volume having some darts without neighboring facet for +$\beta_2$. In such a case, there is a particular value called +$\varnothing$ used to describe that a dart $d_0$ is not linked to +another dart in dimension~$i$. + +% No it is false (case when c_i=c'_i) and we exchange also c_0... +% A dart $a$ corresponds to a tuple of cells: +% $(c_0,\ldots,c_d)$, all incident, each $c_i$ being an +% $i$-cell. Given a dart $a$ corresponding to +% $(c_0\ldots,c_{i-1},c_i,c_{i+1},\ldots,c_d)$, $\beta_i(a)$ gives the +% dart $a'$ corresponding to +% $(c_0\ldots,c_{i-1},c'_i,c_{i+1},\ldots,c_d)$ with $c'_i$ the only +% $i$-cell different from $c_i$ incident both to $c_{i-1}$ and +% $c_{i+1}$, or NULL if such a cell does not exist. + +Combinatorial maps are defined in any dimension. A 0D combinatorial +map is a set of isolated darts describing isolated vertices. A 1D +combinatorial map describes paths or cycles of darts corresponding to +paths or cycles of edges, and equivalent to double linked lists. The +most useful cases are 2D and 3D combinatorial maps. Since 2D +combinatorial maps are equivalent to halfedge data structure, notions +are illustrated in 3D in the following examples to help the reader +understand this specific case. But it is important to keep in mind +that one main interest of combinatorial maps is their generic +definition in any dimension, and that everything presented in this +manual is valid in any dimension. + +A $d$D combinatorial map is useful when you want to describe $d$D +objects and the adjacency relations between these objects, and you +want to be able to efficiency traverse these objects by using the +different relations. For example, we can use a 3D combinatorial map +to describe a 3D segmented image: each 3-cell corresponds to a region +in the image and each 2-cell corresponds to a contact area between two +regions. + +A combinatorial map does not contain any geometrical +information. However, this package allows to associate any information +to the cells of the combinatorial map. A specific information, which +is often used in practice, consists in adding linear geometry to a +combinatorial map by associating a point to each vertex of the +map\footnote{When an object has a point associated to each vertex, + each edge is thus a straight line segment, which explains the name + ``linear geometry''.}: this is the object of the +\ccc{Linear_cell_complex} package. This package can for example be +useful to describe 3D buildings as set of walls, rooms, doors and +windows (both combinatorial and geometrical descriptions) and all the +adjacency relations between these elements allowing for example to +move a camera in a given building from rooms to rooms by traversing +doors. + +% Combinatorial maps only describe the +% We have seen that cells are only represented implicitly by sets of +% darts. Higher level data structures as the \ccc{Linear_cell_complex} +% often need to associate information to cells. This can be geometric or +% non-geometric information, such as 3D points associated to vertices, +% the edge length associated to edges, or a color or normal to a facet. +% The combinatorial map allows to store attributes, with links between +% darts and the attribute of the cell represented by the dart. The +% combinatorial map further provides methods to enumerate the +% attributes, and it provides a mechanism to merge or split attributes +% when cells are merged or split. Attributes may exist for only some of +% the dimensions, and if they exist for dimension $i$, they do not +% necessarily exist for each of the $i$-cells. + +\section{Data Structure Presentation}\label{sec_presentation} +In this section, we describe $d$D combinatorial maps in terms of data +structure and operations. Mathematical definitions are provided in +Section~\ref{sec_definition}, and a package description is given in +Section~\ref{sec-software-design}. + +\subsection{Combinatorial Map and Darts}\label{ssec-combi-map-and-darts} +A $d$D combinatorial map is a set of darts $D$. A dart $d_0$ is an +element that can be \emph{linked} with $d+1$ darts by pointers called +$\mb{i}$, with $0 \leq i \leq d$. Dart $d_0$ is said \emph{$i$-free} +when $\mb{i}(d_0)=\varnothing$. Each $\mb{i}$, for $2 \leq i \leq d$, +is its own inverse, i.e., if dart $d_0$ is not $i$-free, then +$\mb{i}(\mb{i}(d_0))=d_0$. This is different for $\mb{0}$ and +$\mb{1}$: $\mb{0}$ is the inverse of $\mb{1}$, i.e., if darts $d_1$ +and $d_2$ are such that $\mb{1}(d_1)=d_2$, then +$\mb{0}(d_2)=d_1$. Given dart $d_1$, if there is no dart $d_2$ such +that $\mb{1}(d_2)=d_1$, then $\mb{0}(d_1)=\varnothing$. $\varnothing$ +is a constant, which does not belong to the set of darts $D$ of the +combinatorial map. However, by definition $\varnothing$ is linked with +itself for all $\beta_i$s: $\forall i$, $0 \leq i \leq d$, +$\mb{i}(\varnothing)=\varnothing$. + +% There is a particular value called +% $\varnothing$ used to describe that a dart $d_0$ is not linked to +% another dart in dimension~$i$. In such a case +% $\mb{i}(d_0)=\varnothing$ and we say that $d_0$ is \emph{$i$-free}. + + +% (see Section~\ref{ssec-combimap-validity}). +% we do not need to represent +% the inverse one-to-one mapping because, for each non free dart $a$, +% Note that $\mb{0}$ is +% only a notation and not a new link. +% (even if in practice this +% one-to-one mapping is often explicitly encoded for complexity reasons). + +A combinatorial map is \emph{without $i$-boundary} if there is no +$i$-free dart, and it is \emph{without boundary} if it is without +$i$-boundary for all dimensions $1 \leq i \leq d$. + + +We show in Figure~\ref{fig-exemple-carte3d} a 3D object and the +corresponding 3D combinatorial map. This map has 40 darts represented +by arrows, some darts being numbered. In this combinatorial map, we +have for example $\beta_1(1)=2$, $\beta_2(1)=10$, and +$\beta_3(1)=5$. This combinatorial map is without 1-boundary and +2-boundary, but has some 3-boundary, because some darts are $3$-free, +for example $\beta_3(10)=\varnothing$ and $\beta_3(12)=\varnothing$. +% +\def\LargFig{.4\textwidth} +\begin{figure} + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=\LargFig]{Combinatorial_map/fig/pdf/object3d}\qquad + \includegraphics[width=\LargFig]{Combinatorial_map/fig/pdf/exemple-carte2-3d} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ + + + +
+ \end{ccHtmlOnly} + \caption{Example of a 3D combinatorial map. \textbf{Left}:~A 3D object + made of two volumes adjacent along facet $f_2$. \textbf{Right}:~The + corresponding 3D combinatorial map. Darts are drawn with + arrows, sometimes numbered. Two darts linked by $\beta_1$ are + drawn consecutively (for example $\beta_1(10)=11$), and two + darts linked by $\beta_2$ are drawn parallel, in reverse + orientations, with a little gray segment joining them (for + example $\beta_2(1)=10$). $\beta_3$ pointers are represented by + blue segments (for example $\beta_3(1)=5$).} + \label{fig-exemple-carte3d} +\end{figure} + +\subsection{Cells as Sets of Darts}\label{ssec-cells-in-map} +A cell in a $d$D combinatorial map is implicitly represented by a +subset of darts. +% When a dart $d_0$ is an element of the set of darts of +% an $i$-cell $c$, we say that $d_0$ \emph{belongs} to $c$, and that $c$ +% \emph{contains} $d_0$. +In this section, we will see how to retrieve all cells containing a +given dart, how to retrieve all darts belonging to a cell containing a +given dart, and how incidence and adjacency relations are defined in +terms of darts. + +The first important property of a combinatorial map is that +each dart belongs to an $i$-cell, $\forall i$, $0 \leq i \leq d$. +For example in 3D, a dart belongs to a vertex, an edge, a facet, and a +volume. This means that a 3D combinatorial map containing an isolated +dart contains exactly one vertex, one edge, one facet and one volume. + +% Moreover, given $d+1$ pairwise incident cells +% of different dimension, there exists a unique dart which is part of +% each cell. + +The second important property is that cells of a combinatorial map +correspond to specific \emph{orbits}. Given a set +$S \subseteq \{\beta_1,\ldots,\beta_d\}$ and a dart +$d_0$, the \emph{orbit} $\orb{S}(d_0)$ is the set of darts that can be +reached from $d_0$ by following any combination of any $\beta_i$'s in $S$ +and their inverses (to simplify notations, we can use for example +$\orb{\beta_1,\beta_4}(d_0)$ to denote $\orb{S}(d_0)$ with +$S=\{\beta_1,\beta_4\}$). + +Given a dart $d_0$, in general, $\mb{i}(d_0)$ (with $1\leq i \leq d$) +belongs to the same cells as $d_0$, only the $i$-cell and $0$-cell are +different. There are two exceptions: (1)~if $d_0$ is $i$-free, then +$\mb{i}(d_0)=\varnothing$; (2)~if $\mb{i}(d_0)$ belongs to the same $i$-cell +as $d_0$ (case of multi-incidence). For example if an edge is an isolated +loop, it is incident twice to the same vertex, then given a dart $d_0$ +belonging to this edge, $\mb{1}(d_0)$ goes to the next edge, which is in +fact the same edge. + +Since $\mb{i}(d_0)$ (with $1\leq i \leq d$) allows to change the +current $i$-cell, all the darts that can be reached from $d_0$ by +using any combination of $\mb{j}$'s, $\forall j$, $1 \leq j \leq d$ and +$j\neq i$ and their inverse are contained in the same $i$-cell as +$d_0$. The $i$-cell containing $d_0$ is defined in terms of orbit by +$\orb{\beta_1,\ldots,\beta_{i-1},\beta_{i+1},\ldots,\beta_d}(d_0)$. + +% since $\mb{0}$ is not a relation +% (but only a notation for $\mb{1}^{-1}$). Thus, + +There is a special case for vertices. Given a dart $d_0$, the set of +darts contained in the same vertex as $d_0$ are the darts that can be +reached from $d_0$ by using any combination of $\mb{i}\circ\mb{j}$, +$\forall i,j$, $1 \leq i< j \leq d$, and their inverse. The $0$-cell +containing $d_0$ is defined in terms of orbit by +$\orb{\{\mb{i}\circ\mb{j}|\forall i,j: 1\leq i + \end{ccHtmlOnly} + \caption{Example of combinatorial maps with attributes. Attributes + are represented by black rectangles containing an information, and + association between darts and attributes are represented by small + lines. \textbf{Left}:~A 2D combinatorial map with 1-attributes + containing a double, for example corresponding to the length of + the 1-cell, and 2-attributes containing a color in RGB format. + Only three edges of the combinatorial map, among the nine, are + associated to a 1-attribute. All the 2-cells are associated to a + 2-attribute. \textbf{Right}:~A 3D combinatorial map with + 2-attributes containing a color in RGB format. Only three 2-cells + of the combinatorial map, among the ten, are associated to a + 2-attribute.} + \label{fig-exemple-attribs} +\end{figure} + +\subsection{Combinatorial Map Properties}\label{ssec-combimap-validity} +There are some conditions that a combinatorial map must satisfy to be +valid. Some of them have already been given about the $\beta$ pointers +(see Section~\ref{ssec-combi-map-and-darts}) and about the association +between darts and attributes (see +Section~\ref{ssec-associate-attributes}). + +There is an additional condition related to the type of represented +objects, which are \emph{quasi-manifold} orientable $d$D objects. A +$d$D quasi-manifold is an object obtained by taking some isolated +$d$-cells, and allowing to glue $d$-cells along $(d-1)$-cells. It is +orientable if it is possible to embed it in the Euclidean space and to +define a global ``left'' and ``right'' direction in each point of the +embedded object. In 2D, quasi-manifolds are manifolds, but this is no +longer true in higher dimension as we can see in the example presented +in Figure~\ref{fig-quasivariete}. In this example, the object to the +right is not a manifold since the neighborhood of the point $p$ in the +object is not homeomorphic\footnote{Intuitively, two objects are + homeomorphic if each object can be continuously deformed into the + second one. In such a case, the two objects have exactly the same + topological properties.} to a 3D ball. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FIGURE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{figure} + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=.33\textwidth]{Combinatorial_map/fig/pdf/quasivarietea} + \includegraphics[width=.33\textwidth]{Combinatorial_map/fig/pdf/quasivariete} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ + +
+ \end{ccHtmlOnly} + \caption{Example of a 3D quasi-manifold which is not a manifold. + The object to the right is made of the four pyramids (shown to the + left) glued together along facets, thus it is a quasi-manifold.} + \label{fig-quasivariete} +\end{figure} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Combinatorial maps can only represent quasi-manifolds due to the +definition of $\beta$ pointers. As we have seen in +Section~\ref{ssec-cells-in-map}, $\mb{i}(d_0)$ (with $1\leq i \leq d$) +belongs to the same cells as $d_0$, only the $i$-cell and $0$-cell are +different. In other words, $\mb{i}$ links two $i$-cells that +share a common $(i-1)$-cell: it is not possible to link more than two +$i$-cells along a same $(i-1)$-cell. +% +% If we want to put in relation two $i$-cells that share +% a common $(i-2)$-cell (for example in 3D two 3-cells shazing an edge +% as in Figure~\ref{fig-nonquasi-manifold} (Right)), we need to add +% another pointer because this relation must be distinguished from the +% previous relation. Since we +% +For this reason, it is not possible to describe non quasi-manifold +objects as those shown in Figure~\ref{fig-nonquasi-manifold} by +combinatorial maps. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{figure}[ht] + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=.22\textwidth] + {Combinatorial_map/fig/pdf/object2d-nonmanifold} + \qquad + \includegraphics[width=.3\textwidth] + {Combinatorial_map/fig/pdf/object3d-nonmanifold} + \qquad + \includegraphics[width=.35\textwidth] + {Combinatorial_map/fig/pdf/object3d-nonmanifold2} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ + + +
+ \end{ccHtmlOnly} + \caption{Three examples of non quasi-manifold + objects. \textbf{Left}: A 2D object which is not a + quasi-manifold since the two 2-cells share a common vertex but + no common 1-cell. \textbf{Middle}: A 3D object which is not a + quasi-manifold since is it not only composed by 3D cells glued + together (there is an isolated 2-cell in dark + gray). \textbf{Right}: A 3D object which is not a quasi-manifold + since the two 3-cells share a common edge but no common 2-cell. + } + \label{fig-nonquasi-manifold} +\end{figure} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Due to this additional condition, any objects can not be represented +by a combinatorial map but only orientable quasi-manifolds. We need to +study now the inverse relation. Does any set of darts linked together by +$\mb{i}$'s, with $0 \leq i \leq d$ correspond to a quasi-manifold? As +we can see in Figure~\ref{fig-pb-carte}, the answer is no. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{figure}[ht] + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=.4\textwidth] + {Combinatorial_map/fig/pdf/pb-carte3D} + \qquad + \includegraphics[width=.4\textwidth] + {Combinatorial_map/fig/pdf/pb2-carte3D} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ + +
+ \end{ccHtmlOnly} + \caption{Two examples of darts linked together by some $\beta_0$, + $\beta_1$, $\beta_2$ and $\beta_3$ which does not represend a 3D + quasi-manifold, and thus which are not 3D combinatorial map. + \textbf{Left}: In this example, all the darts are 3-free except + $\beta_3(1)=5$ and $\beta_3(4)=6$ (and vice-versa). + \textbf{Right}: In this example, darts linked by $\beta_3$ + are not in the same order in both 3-cells. + } + \label{fig-pb-carte} +\end{figure} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +In the first example (Left), there are two 3-cells (one to the left +for the cube, a second to the right for the pyramid) which are +``partially adjacent'' along one 2-cell. Indeed, only two darts +of the 2-cell are linked by $\beta_3$. We have $\beta_3(1)=5$ and +$\beta_3(4)=6$ (and reciprocally). This configuration is not possible +in a quasi-manifold: two $d$-cells are always glue along an ``entire'' +$(d-1)$-cells. + +But as we can see in the second example (Right), the condition that +all the darts of the cell are linked in not sufficient. Indeed, in +this example, all the darts of the 2-cell between the cube and the +pyramid are linked together by $\beta_3$. However, this configuration +does not correspond to an orientable 3D quasi-manifold. Indeed, the +operation of gluing two $d$-cells along one $(d-1)$-cell must +preserve the initial $(d-1)$-cell. + +To avoid these two kinds of configurations, conditions are added on +$\beta$ pointers compositions (see Section~\ref{sec_definition}, +condition~(4) of the definition of combinatorial maps). Intuitively +these conditions say that if two darts are linked by $\beta_i$, then +all the required darts are linked by $\beta_i$ two by two in such a +way that neighborhood relations are preserved. + + +We say that a combinatorial map is \emph{valid} if it satisfies all +the conditions on $\beta$ pointers and on association between darts +and attributes. High level operations provided on combinatorial maps +ensure that these conditions are always satisfied. Sometimes, it can +be useful to use low level operations in a specific algorithm, for +example to modify locally a combinatorial map in a really fast way. In +such a case, additional operations may be needed to restore these +validity conditions. + +% +% (valid in the sense that it corresponds to a quasi-manifold). + +% The validity conditions are defined as follow: +% \begin{description} +% \item[V1] $\mb{1}$ is injective: + +% $\forall d_1 \in D$, $\forall d_2 \in D$, if $\mb{1}(d_1)=\mb{1}(d_2)$, then +% $\mb{1}(d_1)=\varnothing$ or $d_1=d_2$; + +% \item[V2] Other $\mb{i}$s are their own inverse function that link two different darts: + +% $\forall d_0 \in D$, $\forall i$, $2 \leq i \leq d$: $\mb{i}(d_0)\neq d_0$ and +% if $\mb{i}(d_0) \neq \varnothing$, then +% $\mb{i}(\mb{i}(d_0))=d_0$; + +% \item[V3] Composition rule: + +% $\forall d_0 \in D$, $\forall i$, $0 \leq i \leq d-2$: +% $\forall j$, $3 \leq j \leq d$ such that $i+2 \leq j$: +% $\mb{i}(\mb{j}(d_0))=\mb{j}(\mb{i}^{-1}(d_0))$. + +% \end{description} + +% The first condition ensures that any two sequences of darts obtained +% from two darts and using $\beta_1$ iteratively (which are cycles when +% no dart is 1-free or paths otherwise) are either equal or +% disjoint. These cycles and paths describe the 2D facets. + +% The second condition ensures that given $i$, $2\leq i\leq d$, and a non +% $i$-free dart $d_0$, there is at most one $i$-cell adjacent to the +% $i$-cell containing $d_0$. (For example in 3D, given a facet incident to +% an edge and a volume, there is at most one other facet incident to the +% same edge and the same volume. In Figure~\ref{fig-exemple-carte3d}, we +% have for example $\beta_2(1)=10$ and thus $\beta_2(10)=1$). +% % This guaranties the quasi-manifold property. + +% The last condition ensures that objects are correctly glued together. +% (For example in 3D, if two darts are linked by $\mb{3}$, the following +% constraints need to be satisfied: +% $\mb{0}(\mb{3}(d_0))=\mb{3}(\mb{0}^{-1}(d_0))$, and +% $\mb{1}(\mb{3}(d_0))=\mb{3}(\mb{1}^{-1}(d_0))$, which means that all the +% darts of the two facets must be consistently linked by $\mb{3}$. In +% Figure~\ref{fig-exemple-carte3d}, we have for example +% $\beta_3(4)=6$. This implies that $\beta_3(1)=5$, $\beta_3(2)=8$, and +% $\beta_3(3)=7$). + + % In Section~\ref{ssec-combimap-validity} we have presented the three + % conditions that a combinatorial map must satisfy to be + % valid. However, these conditions were for combinatorial map without + % attributes. + % When an $i$-attribute is not void, the following two + % additional conditions have to be satisfied in order to have a correct + % association between $i$-cells and $i$-attributes: + % \begin{description} + % \item[V4] all the darts belonging to the same $i$-cell are associated to + % the same $i$-attribute; + % \item[V5] two darts belonging to two different $i$-cells are associated + % to two distinct $i$-attributes. + % \end{description} + % Thus, a combinatorial map with attribute is valid if it satisfies + % the three validity conditions on darts presented in + % Section~\ref{ssec-combimap-validity}, plus the two conditions given + % above for each $i$-attribute. + +% In practice, attributes are associated to darts because cells are not +% explicitely represented, thus these two conditions are required to +% make as if attributes are associated by one-to-one mappings to cells. +% Note that there is no restriction on information contained in +% attributes (two different cells are always associated to two different +% attributes but possibly with the same information, and moreover this +% information can be shared by several attributes by adding an +% indirection). Note also that it is not required that each $i$-cell is +% associated with an $i$-attribute. + +\section{Software Design}\label{sec-software-design} +The diagram in Figure~\ref{fig-diagram_class} shows the different +classes of the package. \ccc{Combinatorial_map} is the main class +(see Section~\ref{ssec-combinatorial-map}). It allows to manage darts +(see Section~\ref{ssec-darts}) and attributes (see +Section~\ref{ssec-attributes}). +% An attribute is an information +% associated to some cells of the combinatorial map. +Users can customize a combinatorial map thanks to an items class (see +Section~\ref{ssec-item}), which defines the dart type and the +attribute types. These types may be different for different +dimensions, and they may also be void. The darts and attributes are +accessed through \emph{handles}. A handle is a model of the +\ccc{Handle} concept, thus supporting the two dereference operators +\ccc{operator*} and \ccc{operator->}. + +\begin{figure} + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=.95\textwidth] + {Combinatorial_map/fig/pdf/Diagramme_class} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ + +
+ \end{ccHtmlOnly} + \caption{UML diagram of the main classes of the package. $k$ is the number of + non void attributes.} + \label{fig-diagram_class} +\end{figure} + + +% , and +% the type enabled and disabled attributes are defined. This allows for +% example to enable attributes associated to vertices and to facets, in +% order to store in each vertex its degree (an unsigned int), and to +% store in each facet its color (an instance of \ccc{CGAL::Color}). +% There is a default items class \ccc{Combinatorial_map_min_items} +% which defines \ccc{Dart} as the type of dart, without any enabled +% attributes. + +\subsection{Combinatorial Maps}\label{ssec-combinatorial-map} +The class \ccc{Combinatorial_map} is a model of the +\ccc{CombinatorialMap} concept. It has three template parameters +standing for the dimension of the combinatorial map (an +\ccc{unsigned int}), an items class (a model of the +\ccc{CombinatorialMapItems} +concept), and an allocator which must be a model of the allocator +concept of the {\stl}. Default classes are provided for the items and +the allocator classes. + +The main role of the class \ccc{Combinatorial_map} is the storage and +the management of darts. It allows to create or remove an isolated +dart from the combinatorial map. The \ccc{Dart_handle} type defines a +handle to the type of used darts (given in the items class). +\ccc{Combinatorial_map} provides several \emph{ranges} which allow to +iterate over specific subsets of darts of the combinatorial map (see +Section~\ref{ssec-range}). It also defines several methods to link +and to unlink darts by $\beta_i$s (see +Section~\ref{ssec-link-darts}). We said that a dart $d_0$ is $i$-free +if $\mb{i}(d_0)=\varnothing$. The $\varnothing$ constant is +represented in the class \ccc{Combinatorial_map} through a +\ccc{static const Dart_handle} +called \nulldart. Finally, some high levels +operations are defined as global functions taking a +\ccc{Combinatorial_map} as argument (see +Section~\ref{ssec-operations}) + +% The concept \ccc{CombinatorialMap} has one template parameter +% standing for an items class (a model of the +% \ccc{CombinatorialMapItems} concept). +% , and an allocator which +% must be a model of the allocator concept of the {\stl}. + +%The class \ccc{Combinatorial_map} + +The second role of the class \ccc{Combinatorial_map} is the storage +and the management of attributes. It allows to create or remove an +attribute, and provides methods to associate attributes and cells. +A range is defined for each $i$-attribute allowing to iterate +over all the $i$-attributes of the combinatorial map. Finally, +\ccc{Combinatorial_map} defines several types allowing to manage the +attributes. We can use +\ccc{Combinatorial_map::Attribute_handle::type} for a handle to the +$i$-attributes (and the const version +\ccc{Combinatorial_map::Attribute_const_handle::type}) and +\ccc{Combinatorial_map::Attribute_type::type} for the type of the +$i$-attributes. + +\subsection{Combinatorial Map Items}\label{ssec-item} + +The \ccc{CombinatorialMapItems} concept defines dart and attribute +types of a combinatorial map. It contains one inner class named +\ccc{Dart_wrapper}, having one template parameter, \ccc{CMap}, a model +of \ccc{CombinatorialMap} concept. The \ccc{Dart_wrapper} class +provides two local types: \ccc{Dart} which must be a model of the +\ccc{Dart} concept, and \ccc{Attributes} which defines the attributes +and their types. + +The \ccc{Attributes} tuple must contain at most $d+1$ types (one for +each possible cell dimension of the combinatorial map). Each type of +the tuple must be either a model of the \ccc{CellAttribute} concept or +\ccc{void}. The first type corresponds to 0-attributes, the second to +1-attributes and so on. If the $i^{\mbox{th}}$ type in the tuple is +\ccc{void}, $(i-1)$-attributes are disabled: we say that +$(i-1)$-attributes are \emph{void}. Otherwise, $(i-1)$-attributes are +enabled and have the given type: we say $(i-1)$-attributes are +\emph{non void}. If the size of the tuple is $k$, with $k < +dimension+1$, $\forall i: k \leq i \leq dimension$, $i$-attributes are +void. + +The class \ccc{Combinatorial_map_min_items} is a model of the +\ccc{CombinatorialMapItems} concept which can be used for default behaviors. +It defines \ccc{CGAL::Dart} as type of dart, and +\ccc{Attributes} as empty tuple. + +\subsection{Darts}\label{ssec-darts} + +The class \ccc{Dart}, a model of the \ccc{Dart} concept, +defines a $d$D dart. It has two template parameters standing for the +dimension of the combinatorial map, and a model of the +\ccc{CombinatorialMap} concept, which provides the two types +\ccc{Dart_handle} and \ccc{Dart_const_handle}. + +Each instance \ccc{d0} of \ccc{Dart} stores the $\beta_i$ pointers in an +array of $d+1$ \ccc{Dart_handle} (because we describe also the +$\beta_0$ pointer). It also stores the attributes associated to this +dart in a tuple of \ccc{CMap::Attribute_handle::type}, one for each +non void $i$-attribute. + +Methods are defined allowing to retrieve each $\beta_i$ and each +associated $i$-attribute of \ccc{d0}, and allowing to test if \ccc{d0} +dart is $i$-free. + +Note that the use of the \ccc{Dart} class is not hard wired in +the combinatorial map class. Users can provide their own model of the +\ccc{Dart} concept, and pass it to the combinatorial map with the help +of a custom item class. + +\subsection{Cell Attributes}\label{ssec-attributes} + +The class \ccc{Cell_attribute}, a +model of the \ccc{CellAttribute} concept, represents an attribute +associated with a cell of a combinatorial map. The +template parameter \ccc{CMap} must be a model of the +\ccc{CombinatorialMap} concept. The attribute stores a handle to one +dart of its associated cell when the template parameter \ccc{Tag} is +\ccc{Tag_true}. +% (bi-directional association between darts and +%attributes). If \ccc{Tag} is \ccc{Tag_false}, the attribute does not +%know a dart of its associated cell (uni-directional association from +%darts to attributes). +\ccc{Info_} is the type of information stored in the attribute. It may +be \ccc{void}. \ccc{OnMerge} and \ccc{OnSplit} must be either +\ccc{Null_functor}, or models of the \ccc{Binary Function} concept +having two references to a model of \ccc{CellAttribute} as type of +both parameters and \ccc{void} as return type. There are two default +parameters for \ccc{OnMerge} and \ccc{OnSplit}, which are +\ccc{Null_functor}, a default parameter for \ccc{Tag} which is +\ccc{Tag_true}, and a default parameter for \ccc{Info_} which is +\ccc{void}. + +If \ccc{Info_} is different from \ccc{void}, the class +\ccc{Cell_attribute} contains two methods \ccc{info()} returning the +information contained in the attribute (const and non const version). +The information is returned by reference, thus the non const version +allows the modification of the information. + +Two attributes are merged when their corresponding cells are merged +into one cell during some operation. In this case, the functor +\ccc{OnMerge} is called, unless it is equal to \ccc{Null_functor}. +This functor allows the user to define its own custom behavior when +two attributes are merged (for example if the information is a color, +we can compute the average color of the two initial attributes, and +affect this value to the first attribute, see example in +Section~\ref{ssec-combi-map-with-color}). Similarly, the functor +\ccc{OnSplit} is called when one attribute is split in two, because +its corresponding cell is split in two during some operation, unless +it is equal to \ccc{Null_functor}. In any high level operation, +\ccc{OnMerge} is called before to start the operation (i.e. before +modifying the combinatorial map), and \ccc{OnSplit} is called when the +operation is finished (i.e. after all the modifications were made). + +% They contain a method \ccc{operator ()} +% taking two references on \ccc{Cell_attribute} as parameters. +% \ccc{On_merge} allows the user to define his own behavior when two +% attributes are merged, and \ccc{On_split} allows the user to define +% his own behavior for the split of an attribute in two. + +% The class \ccc{Cell_attribute} defines the two local types +% \ccc{On_merge} and \ccc{On_split} equal to +% \ccc{OnMerge} and \ccc{OnSplit}, allowing to retrieve the functors +% associated with each attribute. + +What we said for the dart also holds for the cell attribute. The +combinatorial map can be used with any user defined model of the +\ccc{CellAttribute} concept. + +% \ccc{operator() (CellAttribute&attr1, CellAttribute&attr2)} of +% \ccc{Functor_on_merge} is called before merging \ccc{attr1} and +% \ccc{attr2} into \ccc{attr1}. + +% \ccc{operator() (CellAttribute&attr1, CellAttribute&attr2)} of +% \ccc{Functor_on_split} is called after splitting of \ccc{attr1} into +% \ccc{attr1} and \ccc{attr2}. + +% There is no dimension associated with a cell attribute, since we can +% use the same class for attributes associated with cells of different +% dimensions. + +% The class \ccc{Cell_attribute} +% is a model of the \ccc{CellAttribute} concept. There are two default +% template parameters for \ccc{Functor_on_merge} and \ccc{Functor_on_split}, +% which are \ccc{Void_functor}, a functor doing nothing. + +% An attribute can contain any information, by using the class +% \ccc{Cell_attribute_with_info}, +% another model of the \ccc{CellAttribute} concept. The additional +% template parameter indicates the type of the information contained +% in the attribute (defined in the combinatorial map items). + +% We can for instance use +% \ccc{Cell_attribute_with_info} for an attribute +% containing an unsigned int (for example to associate to each vertex +% its degree) or \ccc{Cell_attribute_with_info} +% for an attribute containing a \ccc{CGAL::Color}. Method \ccc{Info& +% info()} allows to get the information of an attribute. We can +% modify the value of the information since the information is returned +% by reference. Finally, if you want an attribute which contain several +% information, you have to create a new structure containing all these +% information and use this structure as \ccc{Info} template parameter. + +\subsection{Example of Combinatorial Map Definition}\label{ssec-example-def} + +Here comes an example of two combinatorial map definitions. The first +case \ccc{Example_cmap4} defines a 4D combinatorial map which uses all +the default values (\ccc{Dart} and +\ccc{Combinatorial_map_min_items}). The second example +\ccc{Example_custom_cmap3} uses its own model of the +\ccc{CombinatorialMapItems} concept. In this model, the type +of dart is \ccc{Dart<3,CMap>}, thus a dart is in 3D, and an +attribute containing an integer is associated to edges. + +\begin{ccExampleCode} +typedef CGAL::Combinatorial_map<4> Example_cmap4; + +struct Example_items_3 +{ + template + struct Dart_wrapper + { + typedef CGAL::Dart<3, CMap> Dart; + typedef Cell_attribute Edge_attrib; + typedef CGAL::cpp0x::tuple Attributes; + }; +}; +typedef CGAL::Combinatorial_map<3, Example_items_3> Example_custom_cmap3; +\end{ccExampleCode} + + +\section{Iteration and Creation Operations} + +An important operation in combinatorial maps consists in iterating +over specific subsets of darts or over attributes. For that, several +\emph{ranges} are offered (see Section~\ref{ssec-range}). A range is +a model of the \ccc{Range} concept, thus supporting the two methods +\ccc{begin()} and \ccc{end()} allowing to iterate over all the +elements in the range. Several global functions allow to create +specific configurations of darts into a combinatorial map (see +Section~\ref{ssec-construction}). Darts can be marked during +operations, for example when performing a breadth-first search +traversal, thanks to Boolean marks (see +Sections~\ref{ssec-adv-marks}). In the following, we denote by +\ccc{dh0}, \ccc{dh1}, \ccc{dh2} the dart handles for the darts +\ccc{d0}, \ccc{d1}, \ccc{d2}, respectively. That is \ccc{d0 == *dh0}. + +\subsection{Iterating over Orbits, Cells, and Attributes}\label{ssec-range} + +The combinatorial map offers iterators to traverse the darts +of a specific orbit, to traverse all darts of one cell, or +one dart per cell, and to traverse all $i$-attributes. + +Instead of the \ccc{begin()/end()} member function pair as we know it +from \stl\ containers, and from most \cgal\ data structures, the +combinatorial map defines range classes which are all models of the +\ccc{Range} concept. + +There are three different categories of dart range classes: +\begin{itemize} +\item \ccc{Dart_range}: range of all the darts of a combinatorial map; +\item \ccc{Dart_of_orbit_range}: range of all the darts of + the orbit $\orb{Beta...}(d0)$ for a given $d0$. $Beta...$ is a + sequence of integers $i_1,\ldots,i_k$, each $i_j \in + \{0,\ldots,d\}$. These integers must satisfy: $i_1} for the orbit + $\orb{\mb{1},\mb{2}}(d0)$); +\item \ccc{Dart_of_cell_range}: range of all the darts of + the $i$-cell containing a given dart. The $i$-cell is considered in + dimension \ccc{dim} (with $0 \leq dim \leq d$, $dim=d$ by default), + with $0\leq i \leq dim+1$. If $i=dim+1$, + \ccc{Dart_of_cell_range} is the range of all the darts of + the connected component containing a given dart. +\end{itemize} + +% \ccc{Dart_of_orbit_range} allows to retrieve the different orbits of a +% combinatorial map. Indeed, orbit $\orb{S}(a)$ is obtained by +% iterating over a \ccc{Dart_of_orbit_range} using all the $\beta_i$s in +% $S$, and by keeping all the encountered darts in a data structure (for +% example in a \ccc{set} of the \stl). + +There are also two different classes of ranges containing one dart per +$i$-cell. Note that in these classes, the dart of each $i$-cell can +be any dart of the cell. Moreover, each $i$-cell (and $j$-cell in the +second case) is considered in dimension \ccc{dim} (with $0 \leq dim +\leq d$, $dim=d$ by default). +\begin{itemize} +\item \ccc{One_dart_per_cell_range}: range containing one dart of + each $i$-cell of the combinatorial map, $0\leq i \leq dim+1$ (for + example \ccc{One_dart_per_cell_range<2>} for the range of one dart per + 2-cell of the combinatorial map); +\item \ccc{One_dart_per_incident_cell_range}: range + containing one dart of each $i$-cell incident to the $j$-cell + containing a given dart, with $0\leq i \leq dim+1$ and $0\leq j + \leq dim+1$ (for example + \ccc{One_dart_per_incident_cell_range<0,3>} for the range of + one dart per vertex of the volume incident to the starting dart). + If $i==j$, the range contains only the given dart. +\end{itemize} + +The iterators of the \ccc{Dart_range} are bidirectional iterators, +while the iterators of the other four ranges are forward iterators. +The value type of all these iterators is \ccc{Dart}. + +Additionally, there is a range over non void $i$-attributes: +\ccc{Attribute_range::type}, having a bidirectional iterator with +value type \ccc{Attribute_type::type}. + +For each range, there is an associated const range, a model of the +\ccc{ConstRange} concept. You can find some examples of ranges in +Section~\ref{ssec-example-3DCM}. + +\subsection{Construction Operations}\label{ssec-construction} + +Several global functions allow to create specific configurations of +darts into a combinatorial map. Existing darts in the combinatorial +map are not modified. Note that the dimension of the combinatorial map +must be large enough: darts must contain all the $\beta$ pointers used by the +operation. All these functions take an instance of +\ccc{CombinatorialMap} as first parameter (called \ccc{cm}) and return +a \ccc{Dart_handle} to a new dart created during the operation. + +\begin{itemize} +\item \ccc{make_edge(cm)}: creates an isolated edge (two darts + linked by $\beta_2$); dimension must be greater or equal than two; +\item \ccc{make_combinatorial_polygon(cm,alg)}: creates an + isolated combinatorial polygon of length \ccc{alg} (\ccc{alg} darts + linked by $\beta_1$), for \ccc{alg}$>0$; dimension must be greater + or equal than one; +\item \ccc{make_combinatorial_tetrahedron(cm)}: creates an + isolated combinatorial tetrahedron (four combinatorial triangles + linked together by $\beta_2$); dimension must be greater or equal + than two; +\item \ccc{make_combinatorial_hexahedron(cm)}: creates an + isolated combinatorial hexahedron (six combinatorial quadrangles + linked together by $\beta_2$); dimension must be greater or equal + than two. +\end{itemize} + +\begin{ccAdvanced} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Boolean Marks\label{ssec-adv-marks}} +It is often necessary to mark darts, for example to retrieve in $O(1)$ +if a given dart was already processed during a specific algorithm, for example, +iteration over a given range. Users can also mark specific parts of a +combinatorial map (for example mark all the darts belonging to objects +having specific semantics). To answer these needs, a +\ccc{CombinatorialMap} has a certain number of Boolean marks (fixed by +the constant \ccc{NB_MARKS}). When one +wants to use a Boolean mark, the following methods are available (with +\ccc{cm} an instance of a combinatorial map): +\begin{itemize} +\item get a new free mark: \ccc{int m = cm.get_new_mark()} (return + -1 if no mark is available); + +\item set mark $m$ for a given dart \ccc{d0}: \ccc{cm.mark(dh0,m)}; +\item unset mark $m$ for a given dart \ccc{d0}: \ccc{cm.unmark(dh0,m)}; +\item test if a given dart \ccc{d0} is marked for $m$: \ccc{cm.is_marked(dh0,m)}; + +\item unmark all the darts of \ccc{cm} for $m$: \ccc{cm.unmark_all(m)}; +% The complexity of this method is $O(1)$, if +% the darts of \ccc{cm} $D$ are all marked or all unmarked, and it is $O(|D|)$ +% otherwise + +\item negate mark $m$ of all the darts of \ccc{cm}: \ccc{cm.negate_mark(m)}. + All the marked darts become unmarked and all the unmarked darts become marked; +% The complexity of this method is $O(1)$; + +\item free mark $m$: + \ccc{cm.free_mark(m)}. This method unmarks all the darts of \ccc{cm} + for $m$ before freeing it.% (same complexity as \ccc{cm.unmark_all(m)}). +\end{itemize} + +It is important to free a mark when it is no longer needed, otherwise +you may at some point run out of marks. + +The following example illustrates how to use marks. Two combinatorial +tetrahedra are created and 3-sewn (see Section~\ref{ssec-link-darts} +for a detailed description of the sew operation). Then a mark is +reserved and used to mark all the darts belonging to the first +combinatorial tetrahedron. Finally, these tetrahedron are merged. The +marks allow us to know which darts come from the first and second +tetrahedron. + +\begin{ccExampleCode} + CMap_3 cm; + + // Reserve a mark + int mark = cm.get_new_mark(); + if ( mark==-1 ) + { + std::cerr<<"No more free mark, exit."<(dh1, dh2); + + // Mark the darts belonging to the first tetrahedron. + for (CMap_3::Dart_of_cell_range<3>::const_iterator + it(cm.darts_of_cell<3>(dh1).begin()), + itend(cm.darts_of_cell<3>(dh1).end()); it!=itend; ++it) + cm.mark(it, mark); + + // Remove the common 2-cell between the two tetrahedra: + // the two tetrahedra are merged. + CGAL::remove_cell(cm, dh1); + + // Thanks to the mark, we know which darts come from the first tetrahedron. + unsigned int res=0; + for (CMap_3::Dart_range::const_iterator it(cm.darts().begin()), + itend(cm.darts().end()); it!=itend; ++it) + { + if ( cm.is_marked(it, mark) ) + ++res; + } + + std::cout<<"Number of darts from the first tetrahedron: "< + \end{ccHtmlOnly} + \caption{Example of 3-sew operation. \textbf{Left}:~A 3D + combinatorial map containing two volumes that are not connected, + with 2-attributes. Each attribute contains a color in RGB format, + and there are four 2-cells associated with attributes. + Associations between darts and attributes are drawn with red + segments. \textbf{Right}:~The 3D combinatorial map obtained as + result of \ccc{sew<3>(1,5)} (or \ccc{sew<3>(2,8)}, or + \ccc{sew<3>(3,7)}, or \ccc{sew<3>(4,6)}). Darts (1,5), (2,8), + (3,7) and (4,6) are linked together by $\beta_3$. The two 2-cells + $c_1=\{1,2,3,4\}$ and $c_2=\{5,6,7,8\}$ are merged after the sew + into the 2-cell $\{1,2,3,4,5,6,7,8\}$. We are in the case where + the two attributes are non NULL, thus the first one is kept, and + all the darts of $c_2$ are associated with the first attribute.} + \label{fig-exemple-sew} +\end{figure} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{itemize} +\item The \ccc{sew} and \ccc{unsew} methods iterate over two orbits in + order to link or unlink specific darts two by two. Intuitively, a + \ccc{sew} operation glues two $i$-cells by identifying two of + their $(i-1)$-cells (see example in Figure~\ref{fig-exemple-sew} + where \ccc{sew<3>} is used to glue two 3-cells along one 2-cell). + Reciprocally, a \ccc{unsew} operation un-glues two $i$-cells which + were glued along one of their $(i-1)$-cells. + These methods guarantee that given a valid combinatorial map and a + possible operation we obtain a valid combinatorial map as result of + the operation. + +\begin{ccAdvanced} +\item The \ccc{link_beta} and \ccc{unlink_beta} methods only modify + the pointer of two darts: the obtained combinatorial maps may be not + valid. These operations can be useful to use low level operations + in a specific algorithm, for example to modify locally a + combinatorial map in a really fast way. In such a case, additional + operations may be needed to restore these validity conditions. +\end{ccAdvanced} +\end{itemize} + +Linking two darts $d_1$ and $d_2$ by $\beta_i$, with $2\leq i\leq d$ +and $d_1 \neq d_2$, consists in modifying two $\beta_i$ pointers such that +$\beta_i(d_1)=d_2$ and $\beta_i(d_2)=d_1$. For $i=1$, the modification +is $\beta_1(d_1)=d_2$ (and thus $\beta_0(d_2)=d_1$ by definition of +$\beta_0$); in this case we can have $d_1=d_2$ (a dart linked with +itself corresponds to an edge which is a loop). + +Reciprocally, unlinking a given dart $d_0$ by $\beta_i$, with $2\leq +i\leq d$, consists in modifying two $\beta_i$ pointers +such that $\beta_i(\beta_i(d_0))=\varnothing$ and +$\beta_i(d_0)=\varnothing$. For $i=1$, the modification is +$\beta_1(d_0)=\varnothing$ (and thus +$\beta_0(\beta_1(d_0))=\varnothing$ by definition of $\beta_0$). Note +that is it possible to unlink a given dart for $\beta_i$ only if it is +not $i$-free. + +The \ccc{sew(dh1,dh2)} methods consist mainly to link two by two +several darts by $\mb{i}$. This operation is possible only if there is +a bijection $f$ between all the darts of the orbit +$D_1=\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}(d_1)$ and +$D_2=\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}(d_2)$ +satisfying: $f(d_1)=d_2$, and for all $d'_1 \in D_1$, for all $j\in +\{1,\ldots,i-2,i+2,\ldots,d\}$, +$f(\mb{j}(d'_1))=\mb{j}^{-1}(f(d'_1))$. Intuitively, this condition +ensures the validity of the combinatorial map by verifying that +condition discussed in Section~\ref{ssec-combimap-validity} will be +satisfied after the operation. This can be tested by using the method +\ccc{is_sewable(dh1,dh2)}. For example, the function +\ccc{is_sewable} would return \ccc{false} if we tried to sew a +triangular facet with a quad facet. Note that given two darts $d_1$ +and $d_2$, if there is such a bijection, it is uniquely defined. So giving +the two darts as arguments of the \ccc{sew} is enough to retrieve +all the pairs of darts to link. + +If such a bijection exists, the \ccc{sew(dh1,dh2)} operation +consists only in linking by $\beta_i$ each couple of darts $d_1$ and +$d_2$ such that $d_2=f(d_1)$. + +% links by $\beta_i$ two by two all the darts of +% the orbit $\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}(d1)$ +% and $\orb{\mb{0},\mb{2},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}(d2)$ +% by using the $\beta$ links of each orbit in the same order +% (i.e., if we use the $k^{\mbox{th}}$ $\beta$ in the first +% orbit, we use also the $k^{\mbox{th}}$ $\beta$ in the second one). +% This ensures the validity of the combinatorial map after the +% operation. Before using a sew operation between two darts, it is +% possible to check if this operation is possible (i.e., it will +% produce a valid combinatorial map) or not, by using the method +% \ccc{is_sewable(dh1,dh2)}. +% For example, the function \ccc{is_sewable} would +% return \ccc{false} if we tried to sew a triangular facet with a quad facet. + + +In addition, the sew operations update the associations between darts +and non void attributes in order to guarantee that all the darts +belonging to a given cell are associated with the same attribute +(which is a condition of combinatorial map validity). For each couple +of $j$-cells $c_1$ and $c_2$ that are merged into one $j$-cell during +the sew, we have to update the two associated attributes $attr_1$ and +$attr_2$. If both are NULL, there is nothing to do. If one is NULL +and the other not, we only associate the non NULL attribute to all the +darts of the resulting cell. When the two attributes are non NULL, we +first apply functor \ccc{On_merge} on the two attributes $attr_1$ and +$attr_2$ (see Section~\ref{ssec-attributes}). Then, we associate the +attribute $attr_1$ to all darts of the resulting $j$-cell. Finally, +attribute $attr_2$ is removed from the combinatorial map. + +Note that when the two attributes are non NULL, the first one is +kept. But user can customize this behavior in order to update the +information contained in the attributes according to its needs. For +that, we can define a specific functor, and use it as template +argument for \ccc{OnMerge} parameter of the \ccc{Cell_attribute} +definition. This functor can for example copy the information of the +second attribute in the information of the first one to make as if the +second attribute is kept. + +For example, in Figure~\ref{fig-exemple-sew}, we want to 3-sew the two +initial volumes. \ccc{sew<3>(1,5)} links by $\mb{3}$ the pairs of +darts $(1,5)$, $(2,8)$, $(3,7)$ and $(4,6)$, thus the combinatorial map +obtained is valid. 2-attributes are updated so that all the darts +belonging to the 2-cell containing dart $1$ become associated to the +same 2-attribute after the operation. +% + +Similarly, \ccc{unsew} operations unlink $\mb{i}$ for all the darts +in the orbit $\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}(d_0)$, +and thus guarantee to obtain a valid combinatorial map. This +operation is possible for any non $i$-free dart. + +As for the sew operations, attributes are updated to +guarantee that two darts belonging to two different $j$-cells are +associated to two different $j$-attributes. If the unsew operation +splits a $j$-cell $c$ in two $j$-cells $c_1$ and $c_2$, and if $c$ is +associated to a $j$-attribute $attr_1$, then this attribute is duplicated +into $attr_2$, and all the darts belonging to $c_2$ are associated +with this new attribute. Finally, we call the functor \ccc{On_split} +on the two attributes $attr_1$ and $attr_2$ (see +Section~\ref{ssec-attributes}). + +Let us consider the combinatorial map given in +Figure~\ref{fig-exemple-sew} (Right). If we call \ccc{unsew<3>(2)}, we +obtain the combinatorial map in Figure~\ref{fig-exemple-sew} (Left) +(except for the color of the attribute associated to the +2-cell $\{5,6,7,8\}$ which would be \texttt{\#00ff00}). The \ccc{unsew<3>} +operation has duplicated the 2-attribute associated to the 2-cell +$\{1,2,3,4,5,6,7,8\}$ since this 2-cell is split in two after the +unsew operation. + +\begin{ccAdvanced} + If one wants to modify a combinatorial map \emph{manually}, it is + possible to switch off the updating between + darts and attributes by passing \ccc{false} as last argument of + \ccc{sew(dh1,dh2,update_attributes=true)} and + \ccc{unsew(dh1,update_attributes=true)}. In these cases, the + combinatorial map obtained may be no longer valid due to incorrect + associations between darts and attributes. + + In Figure~\ref{fig-exemple-sew} (Left), if we call + \ccc{sew<3>(1,5,false)}, the resulting combinatorial map is similar + to the combinatorial map of Figure~\ref{fig-exemple-sew} (Right) + (we have linked by $\mb{3}$ the pairs of darts (1,5), (2,8), + (3,7) and (4,6)), but associations between darts and attributes + are not valid. Indeed, we have kept the four initial attributes + and all the associations between darts and attributes, thus two + darts belonging to the same 2-cell (for example darts 1 and 5) are + associated with two different attributes. + + We can also use the + \ccc{link_beta(dh1,dh2,update_attributes=true)} which links + \ccc{d1} and \ccc{d2} by $\beta_i$ without modifying the other + links. + % The combinatorial map obtained may no longer satisfy the third + % validity condition (see Section~\ref{ssec-combimap-validity}). + Association between darts and attributes are only modified for darts + \ccc{d1} and \ccc{d2}, and similarly as for \ccc{sew}, this + updating can be avoided by passing \ccc{false} as last argument of + \ccc{link_beta(dh1,dh2,update_attributes)}. Lastly, we can use + \ccc{unlink_beta(dh1)} to unlink \ccc{d1} for $\beta_i$. In this + last case, there is no modification of association between darts and + attributes. + + In Figure~\ref{fig-exemple-sew} (Left), if we call + \ccc{link_beta<3>(1,5)}, in the resulting combinatorial map we have + now $\mb{3}(1)=5$ and $\mb{3}(5)=1$. This combinatorial map is no + longer valid (for example dart 2 is 3-free and we should have + $\mb{3}(2)=8$). + +\end{ccAdvanced} + +\subsection{Removal and Insertion Operations}\label{ssec-operations} + +The following high level operations are defined as global functions +taking an instance \ccc{cm} of \ccc{CombinatorialMap} as first +argument. All these methods ensure that given a valid combinatorial +map and a possible operation, the modified combinatorial map is also +valid. + +% \subsubsection{Contruction Operations} +% \begin{figure} +% \begin{ccTexOnly} +% \centerline{\includegraphics[width=.75\textwidth] +% {Combinatorial_map/fig/pdf/creations}} +% \end{ccTexOnly} +% \begin{ccHtmlOnly} +%
+% +% +%
+% \end{ccHtmlOnly} +% \caption{Example of basic objets creation: \ccc{make_segment}, \ccc{make_triangle}, \ccc{make_square}, \ccc{make_tetrahedron} and \ccc{make_cube}.} +% \label{fig-basic-creation} +% \end{figure} + +The first one is \ccc{remove_cell(cm,dh0)} which modifies the +combinatorial map to remove the $i$-cell containing dart \ccc{d0}, +with $0 \leq i \leq d$. This operation is possible if $i==d$ or if the given +$i$-cell is incident to at most two $(i+1)$-cells which can be tested +thanks to \ccc{is_removable(cm,dh0)}. If the removed $i$-cell +was incident to two different $(i+1)$-cells, these two cells are +merged into one $(i+1)$-cell. In this case, the \ccc{On_merge} functor +is called if two $(i+1)$-attributes are associated to the two +$(i+1)$-cells. If the $i$-cell is associated with a non void +attribute, it is removed from the combinatorial map (see three +examples on Figures~\ref{fig-insert-vertex}, \ref{fig-insert-edge} and +\ref{fig-insert-face}). +\begin{figure}[htb] + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=.75\textwidth]{Combinatorial_map/fig/pdf/insert-vertex} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ \end{ccHtmlOnly} + \caption{Example of \ccc{insert_cell_0_in_cell_1} and + \ccc{remove_cell<0>} operations. \textbf{Left}:~Initial + combinatorial map. \textbf{Right}:~After the insertion of a + 0-cell in the 1-cell containing dart \ccc{d1}. Now if we remove + the 0-cell containing dart \ccc{d2}, we obtain the initial + combinatorial map.} + \label{fig-insert-vertex} +\end{figure} + +The inverse operation of the removal is the insertion operation. +Several versions exist, sharing a common principle. They consist in +adding a new $i$-cell ``inside'' an existing $j$-cell, $i}, is it not possible to define a unique +\ccc{insert_cell_i_in_cell_j} function because parameters +are different depending on $i$ and $j$. + +%The following versions exist: +% \begin{itemize} +% \item +\ccc{insert_cell_0_in_cell_1(cm,dh0)} adds a 0-cell in +the 1-cell containing dart \ccc{d0}. The 1-cell is split in two. This +operation is possible if \ccc{d0}$\in$\ccc{cm.darts()} (see +example on Figure~\ref{fig-insert-vertex}). + +\begin{figure}[htb] + \begin{ccTexOnly} + \centerline{\includegraphics[width=.85\textwidth] + {Combinatorial_map/fig/pdf/triangulation}} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ \end{ccHtmlOnly} + \caption{Example of \ccc{insert_cell_0_in_cell_2} operation.} + \label{fig-triangulate} +\end{figure} +%\item + \ccc{insert_cell_0_in_cell_2(cm,dh0)} adds a 0-cell in + the 2-cell containing dart \ccc{d0}. The 2-cell is split in + triangles, one for each initial edge of the facet. This operation + is possible if \ccc{d0}$\in$\ccc{cm.darts()} (see example on + Figure~\ref{fig-triangulate}). + +\begin{figure}[htb] + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=.72\textwidth]{Combinatorial_map/fig/pdf/insert-edge} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ \end{ccHtmlOnly} + \caption{Example of \ccc{insert_cell_1_in_cell_2} and + \ccc{remove_cell<1>} operations. \textbf{Left}:~Initial + combinatorial map. \textbf{Right}:~After the insertion of two + 1-cells: a first one between the two 0-cells containing darts + \ccc{d1} and \ccc{d2}, and a second one between the two 0-cells + containing darts \ccc{d3} and \ccc{d4}. Now if we remove the two + 1-cells containing darts \ccc{d5} and \ccc{d6}, we obtain the + initial combinatorial map.} + \label{fig-insert-edge} +\end{figure} +%\item +\ccc{insert_cell_1_in_cell_2(cm,dh1,dh2)} adds a 1-cell in +the 2-cell containing darts \ccc{d1} and \ccc{d2}, between the two +0-cells containing darts \ccc{d1} and \ccc{d2}. The 2-cell is split +in two. This operation is possible if $d1 \in \orb{\beta_1}(d2)$ +which can be tested thanks to +\ccc{is_insertable_cell_1_in_cell_2(cm,dh1,dh2)}. In the example on +Figure~\ref{fig-insert-edge}, it is possible to insert an edge +between darts $d1$ and $d2$, and between $d3$ and $d4$, but it is +not possible to insert an edge between $d1$ and $d3$. + +%\item +\ccc{insert_dangling_cell_1_in_cell_2(cm,dh0)} adds a 1-cell in +the 2-cell containing dart \ccc{d0}, the 1-cell being attached by only +one of its vertex to the 0-cell containing dart \ccc{d0}. +This operation is possible if \ccc{d0}$\in$\ccc{cm.darts()}. + +\begin{figure}[htb] + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=.75\textwidth]{Combinatorial_map/fig/pdf/insert-facet} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ \end{ccHtmlOnly} + \caption{Example of \ccc{insert_cell_2_in_cell_3} and + \ccc{remove_cell<2>} operations. \textbf{Left}:~Initial + combinatorial map. \textbf{Right}:~After the insertion of a + 2-cell along the path of 1-cells containing respectively + \ccc{d1,d2,d3,d4}. Now if we remove the 2-cell containing dart + \ccc{d5}, we obtain the initial combinatorial map.} + \label{fig-insert-face} +\end{figure} +% \item +\ccc{insert_cell_2_in_cell_3(cm,itbegin,itend)} adds a +2-cell in the 3-cell containing all the darts between +\ccc{itbegin} and \ccc{itend}, along the path of 1-cells +containing the darts between the two iterators. The 3-cell is +split in two. This operation is possible if +\ccc{is_insertable_cell_2_in_cell_3(cm,itbegin,itend)} returns +\ccc{true} (see example on Figure~\ref{fig-insert-face}). +%\end{itemize} + +Some examples of use of these operations are given in +Section~\ref{ssec-exemple-operations}. + +\section{Examples} + +\subsection{A 3D Combinatorial Map}\label{ssec-example-3DCM} +In this example, a 3-dimensional combinatorial map is constructed. Two +combinatorial tetrahedra are created, then the numbers of cells of the +combinatorial map are displayed, and the validity of the combinatorial +map is checked. Then, we illustrate the use of ranges to iterate over +specific darts. The first loop enumerates all the darts of the first +tetrahedron by using the range \ccc{Dart_of_orbit_range<1,2>}, and the +second loop enumerates all the darts of the facet incident to dart +\ccc{dh1} and to the first tetrahedron by using the range +\ccc{Dart_of_orbit_range<1>}. + +\begin{ccExampleCode} + typedef CGAL::Combinatorial_map<3> CMap_3; + typedef CMap_3::Dart_const_handle Dart_const_handle; + + int main() + { + CMap_3 cm; + + // Create two tetrahedra. + Dart_const_handle dh1 = CGAL::make_combinatorial_tetrahedron(cm); + Dart_const_handle dh2 = CGAL::make_combinatorial_tetrahedron(cm); + + // Display the combinatorial map characteristics. + cm.display_characteristics(std::cout); + std::cout<<", valid="< in 3D is equivalent to + // CMap_3::Dart_of_cell_range<3>. + for (CMap_3::Dart_of_orbit_range<1,2>::const_iterator + it(cm.darts_of_orbit<1,2>(dh1).begin()), + itend(cm.darts_of_orbit<1,2>(dh1).end()); it!=itend; ++it) + ++res; + + std::cout<<"Number of darts of the first tetrahedron: " + <::const_iterator + it(cm.darts_of_orbit<1>(dh2).begin()), + itend(cm.darts_of_orbit<1>(dh1).end()); it!=itend; ++it) + ++res; + + std::cout<<"Number of darts of the facet containing dh2: " + <(dh1).end()} +again and again as in the following example (which is a bad +solution): +\begin{ccExampleCode} + for (CMap_3::Dart_of_orbit_range<1,2>::const_iterator + it(cm.darts_of_orbit<1,2>(dh1).begin()); + it!=cm.darts_of_orbit<1,2>(dh1).end()); ++it) + {...} +\end{ccExampleCode} +%\end{ccAdvanced} + +\subsection{High Level Operations} +\label{ssec-exemple-operations} +This example shows some uses of high level operations. First we +create a combinatorial hexahedron, the combinatorial map obtained is shown in +Figure~\ref{fig_exemple_ope} (Left). Then we insert two 1-cells along +two opposite 2-cells of the hexahedron. The combinatorial map +obtained is shown in Figure~\ref{fig_exemple_ope} (Middle). Finally, we +insert a 2-cell in the diagonal of the hexahedron in order to split +it into two parts. We obtain the combinatorial map shown in +Figure~\ref{fig_exemple_ope} (Right). We display the characteristics +of the combinatorial map and check its validity. + +The second part of this example removes the inserted elements. First +we remove the inserted 2-cell, then the two inserted 1-cells. We get +back the initial combinatorial hexahedron, which is verified by displaying once +again the characteristics of the combinatorial map. + +\begin{ccExampleCode} +typedef CGAL::Combinatorial_map<3> CMap_3; +typedef CMap::Dart_handle Dart_handle; + +int main() +{ + CMap cm; + + // Create a cuboidal cell. + Dart_handle dh1 = CGAL::make_hexahedral_cell(cm); + + // Add two 1-cells along two opposite 2-cells. + CGAL_assertion( CGAL::is_insertable_cell_1_in_cell_2 + (cm,dh1->beta(1),dh1->beta(0)) ); + + CGAL::insert_cell_1_in_cell_2(cm,dh1->beta(1),dh1->beta(0)); + CGAL_assertion( cm.is_valid() ); + + Dart_handle dh2=dh1->beta(2)->beta(1)->beta(1)->beta(2); + CGAL_assertion( CGAL::is_insertable_cell_1_in_cell_2 + (cm,dh2,dh2->beta(1)->beta(1)) ); + + CGAL::insert_cell_1_in_cell_2(cm,dh2,dh2->beta(1)->beta(1)); + CGAL_assertion( cm.is_valid() ); + + // Insert a 2-cell along these two new 1-cells + // plus two initial 1-cells of the cuboidal cell. + std::vector path; + path.push_back(dh1->beta(1)); + path.push_back(dh1->beta(0)->beta(2)->beta(1)); + path.push_back(dh2->beta(0)); + path.push_back(dh2->beta(2)->beta(1)); + + CGAL_assertion( CGAL::is_insertable_cell_2_in_cell_3 + (cm,path.begin(),path.end()) ); + + Dart_handle dh3=CGAL::insert_cell_2_in_cell_3 + (cm,path.begin(),path.end()); + CGAL_assertion( cm.is_valid() ); + + // Display the combinatorial map characteristics. + cm.display_characteristics(std::cout) + << ", valid=" << cm.is_valid() << std::endl; + + // We use the removal operations to get back + // to the initial cuboidal cell. + CGAL_assertion( CGAL::is_removable(cm,dh3) ); + CGAL::remove_cell(cm,dh3); + CGAL_assertion( cm.is_valid() ); + + CGAL_assertion( CGAL::is_removable(cm,dh1->beta(1)) ); + CGAL::remove_cell(cm,dh1->beta(1)); + CGAL_assertion( cm.is_valid() ); + + CGAL_assertion( CGAL::is_removable(cm,dh2->beta(0)) ); + CGAL::remove_cell(cm,dh2->beta(0)); + CGAL_assertion( cm.is_valid() ); + + // Display the combinatorial map characteristics. + cm.display_characteristics(std::cout) + << ", valid=" << cm.is_valid() << std::endl; + + return EXIT_SUCCESS; +} +\end{ccExampleCode} + +The output is: +\begin{verbatim} +#Darts=36, #0-cells=8, #1-cells=14, #2-cells=9, #3-cells=2, #ccs=1, valid=1 +#Darts=24, #0-cells=8, #1-cells=12, #2-cells=6, #3-cells=1, #ccs=1, valid=1 +\end{verbatim} + +The first line gives the characteristics of the combinatorial map +after all the insertions (the combinatorial map drawn in +Figure~\ref{fig_exemple_ope} (Right)). There are two 3-cells (since +the combinatorial hexahedron was split in two by the 2-cell +insertion), nine 2-cells (since two 2-cells of the original hexahedron +were split in two by the two 1-cell insertions, and a new 2-cell was +created during the 2-cell insertion), fourteen 1-cells (since there +are two new 1-cells created by the 1-cell insertion) while the number +of 0-cells remains unchanged. + +The second line is the result after the removal operations. We +retrieve the original combinatorial hexahedron since we have removed +all the inserted elements. + +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FIGURE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\largFig{.25\textwidth}% +\begin{figure} + \begin{ccTexOnly} + \begin{center} + \includegraphics[width=\largFig]{Combinatorial_map/fig/pdf/ope1}\qquad + \includegraphics[width=\largFig]{Combinatorial_map/fig/pdf/ope2}\qquad + \includegraphics[width=\largFig]{Combinatorial_map/fig/pdf/ope3} + \end{center} + \end{ccTexOnly} + \begin{ccHtmlOnly} +
+ + + +
+ \end{ccHtmlOnly} + \caption{Example of high level operations. + \textbf{Left}:~Initial 3D combinatorial map after the cuboidal + cell creation. \textbf{Middle}:~Combinatorial map obtained after + the two 1-cell insertions. The two 2-cells were split in two. + \textbf{Right}:~Combinatorial map obtained after the 2-cell + insertion. The 3-cell was split in two.} + \label{fig_exemple_ope} +\end{figure} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FIGURE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\subsection{A 4D Combinatorial Map} +In this example, a 4-dimensional combinatorial map is used. Two +tetrahedral cells are created and sewn by $\beta_4$. Then the numbers +of cells of the combinatorial map are displayed, and its validity is +checked. + +By looking at these numbers of cells, we can see that the 4D +combinatorial map contains only one 3-cell. Indeed, the $sew<4>$ +operation has identified by pairs all the darts of the two 3-cells +by definition of the sew operation (see Section~\ref{ssec-link-darts}) +which, in 4D, links by $\beta_3$ all the darts in +$\orb{\mb{1},\mb{2}}(d_1)$ and in $\orb{\mb{1},\mb{2}}(d_2)$. The +situation is similar (but in higher dimension) to the +configuration where we have two triangles in a 3D combinatorial map, +and you use $sew<3>$ between these two triangles. The two triangles +are identified since all their darts are linked by $\beta_3$, thus we +obtain a 3D combinatorial map containing only one 3-cell. Note that +this 3-cell is unbounded since the darts of the two triangles are all +2-free. In the 4D case, the 4-cell is unbounded since all its darts +are 3-free. + +In this example, we also illustrate how to use the basic methods to +build ``by hand'' some specific configuration in a combinatorial +map. In fact, these functions are already present in the package: +function \ccc{make_triangle(cm)} is equivalent to +\ccc{CGAL::make_combinatorial_polygon(cm,3)} and +\ccc{make_tetrahedron(cm)} is equivalent to +\ccc{make_combinatorial_tetrahedron(cm)}. If we want to create a 4D +simplex, we must create five 3D simplexes, and sew them correctly +two by two by $\beta_3$ (and so on if you want to create higher +dimensional combinatorial map). + +\begin{ccExampleCode} +typedef CGAL::Combinatorial_map<4> CMap_4; +typedef CMap_4::Dart_handle Dart_handle; + +Dart_handle make_triangle(CMap_4& amap) +{ + Dart_handle d1 = amap.create_dart(); + Dart_handle d2 = amap.create_dart(); + Dart_handle d3 = amap.create_dart(); + amap.link_beta<1>(d1,d2); + amap.link_beta<1>(d2,d3); + amap.link_beta<1>(d3,d1); + return d1; +} + +Dart_handle make_tetrahedron(CMap_4& amap) +{ + Dart_handle d1 = make_triangle(amap); + Dart_handle d2 = make_triangle(amap); + Dart_handle d3 = make_triangle(amap); + Dart_handle d4 = make_triangle(amap); + amap.link_beta<2>(d1, d2); + amap.link_beta<2>(d3, d2->beta(0)); + amap.link_beta<2>(d1->beta(1), d3->beta(0)); + amap.link_beta<2>(d4, d2->beta(1)); + amap.link_beta<2>(d4->beta(0), d3->beta(1)); + amap.link_beta<2>(d4->beta(1), d1->beta(0)); + return d1; +} + +int main() +{ + CMap_4 cm; + Dart_handle d1 = make_tetrahedron(cm); + Dart_handle d2 = make_tetrahedron(cm); + + cm.sew<4>(d1,d2); + + cm.display_characteristics(std::cout); + std::cout<<", valid="<} as type of dart, and +\ccc{CGAL::Cell_attribute} +as attributes which contain an \ccc{int} and which are associated to +2-cells of the combinatorial map. + +Functors \ccc{Sum_functor} and \ccc{Divide_by_two_functor} define a +custom behavior: when two attributes \ccc{ca1} and \ccc{ca2} are +merged into \ccc{ca1}, the value of \ccc{ca1} is the sum of the +two initial values. When an attribute \ccc{ca1} is split in the two +attributes \ccc{ca1} and \ccc{ca2}, the value of each attribute is +half of the first value. + +\begin{ccExampleCode} +struct Sum_functor +{ + template + void operator()(Cell_attribute& ca1,Cell_attribute& ca2) + { ca1.info()=ca1.info()+ca2.info(); } +}; +struct Divide_by_two_functor +{ + template + void operator()(Cell_attribute& ca1,Cell_attribute& ca2) + { + ca1.info()=(ca1.info()/2); + ca2.info()=(ca1.info()); + } +}; + +struct Myitem +{ + template + struct Dart_wrapper + { + typedef CGAL::Dart<3, CMap> Dart; + typedef CGAL::Cell_attribute + Facet_attribute; + typedef CGAL::cpp0x::tuple Attributes; + }; +}; + +typedef CGAL::Combinatorial_map<3,Myitem> CMap_3; +typedef CMap_3::Dart_handle Dart_handle; + +int main() +{ + CMap_3 cm; + + // Create 2 cubes. + Dart_handle dh1 = CGAL::make_hexahedral_cell(cm); + Dart_handle dh2 = CGAL::make_hexahedral_cell(cm); + + // 1) Create all 2-attributes and associate them to darts. + for (CMap_3::Dart_range::iterator + it=cm.darts().begin(), itend=cm.darts().end(); + it!=itend; ++it) + { + if ( it->attribute<2>()==NULL ) + cm.set_attribute<2>(it, cm.create_attribute<2>()); + } + + // 2) Set the info of all facets of the first cube to 7 + for (CMap_3::Cell_of_cell_range<2, 3>::iterator + it=cm.cells_of_cell<2,3>(dh1).begin(), + itend=cm.cells_of_cell<2,3>(dh1).end(); it!=itend; ++it) + { it->attribute<2>()->info()=7; } + + // 3) Set the info of all facets of the second cube to 13 + for (CMap_3::Cell_of_cell_range<2, 3>::iterator it= + cm.cells_of_cell<2,3>(dh2).begin(), + itend=cm.cells_of_cell<2,3>(dh2).end(); it!=itend; ++it) + { it->attribute<2>()->info()=13; } + + // 4) 3-Sew the two cubes along one facet + cm.sew<3>(dh1->beta(1)->beta(1)->beta(2), dh2->beta(2)); + + // 5) Display all the values of 2-attributes + for (CMap_3::Attribute_range<2>::type::iterator + it=cm.attributes<2>().begin(), itend=cm.attributes<2>().end(); + it!=itend; ++it) + { + std::cout<info()<<"; "; + } + std::cout<beta(2)); + + // 7) Display all the values of 2-attributes + for (CMap_3::Attribute_range<2>::type::iterator + it=cm.attributes<2>().begin(), itend=cm.attributes<2>().end(); + it!=itend; ++it) + { + std::cout<info()<<"; "; + } + std::cout< +% +% +% +% +% \end{ccHtmlOnly} +% \caption{2D combinatorial map example. \textbf{Left}:~A planar +% graph embedded in the plane. \textbf{Right}:~The corresponding +% 2D combinatorial map. Darts are drawn with arrows numbered from +% $1$ to $11$. Two darts linked by $\beta_2$ are drawn parallel, +% in reverse orientations, with a little gray segment between the +% two darts (for example $\beta_2(1)=8$). Two darts linked by +% $\beta_1$ are drawn consecutively (for example $\beta_1(1)=2$).} +% \label{fig-plane-graph} +% \end{figure} +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % + +% The combinatorial map drawn in Figure~\ref{fig-plane-graph}(b) is +% composed of 3 facets (for example the facet incident to dart $1$ is +% $\orb{\beta_1}(1)=\{1,2,3,4\}$), 9 edges (for example the edge incident to +% dart $1$ is $\orb{\beta_2}(1)=\{1,8\}$ and the edge incident to dart $2$ +% is $\orb{\beta_2}(2)=\{2\}$), and 7 vertices (for example the vertex +% incident to dart $1$ is $\orb{\beta_1 \circ \beta_2}(1)=\{1,5,9\}$). + +% \subsection{In 3D} +% In 3D, a 3-map is $M=(D,\beta_1,\beta_2,\beta_3)$ where $\beta_1$ is a +% partial permutation, and $\beta_2$ and $\beta_3$ are two partial +% involutions. Condition~\ref{cond-composition} of the combinatorial map +% definition becomes: $\beta_0 \circ \beta_3$ and $\beta_1 \circ \beta_3$ +% are two partial involutions. These conditions guarantee that when two +% volumes are adjacent, they share an entire facet and not only some +% parts of a facet. Cells are: vertices (corresponding to group $\orb{\beta_1 +% \circ \beta_2, \beta_1 \circ \beta_3, \beta_2 \circ \beta_3}$); edges +% (group $\orb{\beta_2,\beta_3}$); facets (group $\orb{\beta_1,\beta_3}$), and +% volumes (group $\orb{\beta_1,\beta_2}$). + +% \subsection{In 4D} +% In 4D, a 4-map is $M=(D,\beta_1,\beta_2,\beta_3,\beta_4)$ where +% $\beta_1$ is a partial permutation, and $\beta_2$, $\beta_3$ and +% $\beta_4$ are three partial involutions. Condition~\ref{cond-composition} of +% the combinatorial map definition becomes: $\beta_0 \circ \beta_3$, +% $\beta_1 \circ \beta_3$, $\beta_0 \circ \beta_4$, $\beta_1 \circ +% \beta_4$ and $\beta_2 \circ \beta_4$ are partial involutions. +% Cells are: 0-cells: +% $\orb{\beta_1 \circ \beta_2, \beta_1 \circ \beta_3, \beta_1 \circ \beta_4, \beta_2 \circ \beta_3, \beta_2 \circ \beta_4, \beta_3 \circ \beta_4}$); +% 1-cells: $\orb{\beta_2,\beta_3,\beta_4}$); +% 2-cells: $\orb{\beta_1,\beta_3,\beta_4}$); +% 3-cells: $\orb{\beta_1,\beta_2,\beta_4}$); +% and 4-cells: $\orb{\beta_1,\beta_2,\beta_3}$. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +%\end{ccAdvanced} + +\section{Design and Implementation History} +% +The code of this package is inspired by Moka, a 3D topological modeler +mainly developed by Fr\'ed\'eric Vidil and Guillaume Damiand +(\ccAnchor{http://moka-modeller.sourceforge.net/}{http://moka-modeller.sourceforge.net/}). +However, Moka was based on Generalized maps (and not Combinatorial +maps), and the design was not \cgal\ ``compatible''. Thus, Guillaume +Damiand started to develop a totally new package by mixing ideas taken +from Moka with the design of the Halfedge data structure package of +\cgal. Andreas Fabri and S\'ebastien Loriot contributed to the +design, the coding, and to the documentation of the package, and +Laurent Rineau helped for the design. Monique Teillaud and Bernd +Gaertner contributed to the manual by giving useful remarks, really +numerous and detailled for Monique. diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/PkgDescription.tex b/Combinatorial_map/doc_tex/Combinatorial_map/PkgDescription.tex new file mode 100644 index 00000000000..56775fbde53 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map/PkgDescription.tex @@ -0,0 +1,17 @@ + +\begin{ccPkgDescription}{Combinatorial Maps\label{Pkg:CombinatorialMaps}} + \ccPkgHowToCiteCgal{cgal:d-cm-09} \ccPkgSummary{This package + implements Combinatorial Maps in $d$-dimension. A combinatorial + map is a mathematical model allowing to represent an object in any + dimension by describing the subdivision of the object in vertices, + edges, faces, volumes, ... and the incidence and adjacency + relationships on them. + + In 2D, a combinatorial map is equivalent to a halfedge data + structure.} + +\ccPkgIntroducedInCGAL{3.8} +\ccPkgLicense{\ccLicenseLGPL} +% \ccPkgDemo{2D Combinatorial Map}{combinatorial_map_2.zip} +% \ccPkgDemo{3D Combinatorial Map}{combinatorial_map_3.zip} +\end{ccPkgDescription} diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/Diagramme_class.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/Diagramme_class.fig new file mode 100644 index 00000000000..788771387bf Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/Diagramme_class.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte-3d-sew.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte-3d-sew.fig new file mode 100644 index 00000000000..4b519b92c9c Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte-3d-sew.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte-3d-sew2.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte-3d-sew2.fig new file mode 100644 index 00000000000..02455582451 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte-3d-sew2.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte2-3d.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte2-3d.fig new file mode 100644 index 00000000000..1096bfaa627 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/exemple-carte2-3d.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-edge.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-edge.fig new file mode 100644 index 00000000000..872c8151628 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-edge.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-facet.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-facet.fig new file mode 100644 index 00000000000..6001d11fbaa Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-facet.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-vertex.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-vertex.fig new file mode 100644 index 00000000000..2ee6d688ec9 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/insert-vertex.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-map.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-map.fig new file mode 100644 index 00000000000..361b7bb51e6 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-map.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-map2d.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-map2d.fig new file mode 100644 index 00000000000..2585971dbea Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-map2d.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-zoom.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-zoom.fig new file mode 100644 index 00000000000..90c5ca3ea8d Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-zoom.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-zoom2.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-zoom2.fig new file mode 100644 index 00000000000..2b717d58269 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example-zoom2.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example.fig new file mode 100644 index 00000000000..62091796069 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/intuitif-example.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/map2d-with-attrib.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/map2d-with-attrib.fig new file mode 100644 index 00000000000..dffdb1e0c92 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/map2d-with-attrib.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/object2d-nonmanifold.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/object2d-nonmanifold.fig new file mode 100644 index 00000000000..68141b7ee77 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/object2d-nonmanifold.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/object2d.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/object2d.fig new file mode 100644 index 00000000000..4e6f4397946 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/object2d.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d-nonmanifold.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d-nonmanifold.fig new file mode 100644 index 00000000000..3bc28bc254b Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d-nonmanifold.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d-nonmanifold2.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d-nonmanifold2.fig new file mode 100644 index 00000000000..1134cf33b39 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d-nonmanifold2.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d.fig new file mode 100644 index 00000000000..688d08aa27e Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/object3d.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/ope1.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/ope1.fig new file mode 100644 index 00000000000..2c79b3e06a7 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/ope1.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/ope2.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/ope2.fig new file mode 100644 index 00000000000..95e1824bea9 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/ope2.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/ope3.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/ope3.fig new file mode 100644 index 00000000000..43819cae3b7 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/ope3.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pb-carte3D.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pb-carte3D.fig new file mode 100644 index 00000000000..41db188125f Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pb-carte3D.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pb2-carte3D.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pb2-carte3D.fig new file mode 100644 index 00000000000..e6f8036916e Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pb2-carte3D.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/Diagramme_class.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/Diagramme_class.pdf new file mode 100644 index 00000000000..26bec700cc7 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/Diagramme_class.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte-3d-sew.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte-3d-sew.pdf new file mode 100644 index 00000000000..c79ab93e63c Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte-3d-sew.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte-3d-sew2.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte-3d-sew2.pdf new file mode 100644 index 00000000000..12b4afb7da6 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte-3d-sew2.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte2-3d.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte2-3d.pdf new file mode 100644 index 00000000000..9ed2c801ac1 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/exemple-carte2-3d.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-edge.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-edge.pdf new file mode 100644 index 00000000000..2602091c4cd Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-edge.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-facet.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-facet.pdf new file mode 100644 index 00000000000..49752700577 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-facet.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-vertex.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-vertex.pdf new file mode 100644 index 00000000000..392383d2b21 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/insert-vertex.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-map.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-map.pdf new file mode 100644 index 00000000000..fe891660670 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-map.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-map2d.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-map2d.pdf new file mode 100644 index 00000000000..f1ac2176b67 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-map2d.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-zoom.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-zoom.pdf new file mode 100644 index 00000000000..17b46eaa82f Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-zoom.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-zoom2.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-zoom2.pdf new file mode 100644 index 00000000000..903b0898af9 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example-zoom2.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example.pdf new file mode 100644 index 00000000000..520d8831d57 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/intuitif-example.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/map2d-with-attrib.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/map2d-with-attrib.pdf new file mode 100644 index 00000000000..094aad1daaa Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/map2d-with-attrib.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object2d-nonmanifold.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object2d-nonmanifold.pdf new file mode 100644 index 00000000000..605ae9d27a3 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object2d-nonmanifold.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object2d.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object2d.pdf new file mode 100644 index 00000000000..8a02acf6945 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object2d.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d-nonmanifold.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d-nonmanifold.pdf new file mode 100644 index 00000000000..f80331af5ce Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d-nonmanifold.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d-nonmanifold2.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d-nonmanifold2.pdf new file mode 100644 index 00000000000..b7ba2b87834 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d-nonmanifold2.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d.pdf new file mode 100644 index 00000000000..37b75fdeafd Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/object3d.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope1.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope1.pdf new file mode 100644 index 00000000000..76de12e8854 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope1.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope2.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope2.pdf new file mode 100644 index 00000000000..520b7bc27a5 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope2.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope3.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope3.pdf new file mode 100644 index 00000000000..de209315f90 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/ope3.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/pb-carte3D.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/pb-carte3D.pdf new file mode 100644 index 00000000000..f13b6d93ac5 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/pb-carte3D.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/pb2-carte3D.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/pb2-carte3D.pdf new file mode 100644 index 00000000000..f172331fce0 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/pb2-carte3D.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/quasivariete.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/quasivariete.pdf new file mode 100644 index 00000000000..b3665d10fe2 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/quasivariete.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/quasivarietea.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/quasivarietea.pdf new file mode 100644 index 00000000000..0fbd03e12bd Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/quasivarietea.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/triangulation.pdf b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/triangulation.pdf new file mode 100644 index 00000000000..50194783de9 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/pdf/triangulation.pdf differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/Diagramme_class.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/Diagramme_class.png new file mode 100644 index 00000000000..593b69be9af Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/Diagramme_class.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte-3d-sew.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte-3d-sew.png new file mode 100644 index 00000000000..2fecf91de11 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte-3d-sew.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte-3d-sew2.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte-3d-sew2.png new file mode 100644 index 00000000000..e8f3c23ea9a Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte-3d-sew2.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte2-3d.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte2-3d.png new file mode 100644 index 00000000000..f895e537cd6 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/exemple-carte2-3d.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-edge.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-edge.png new file mode 100644 index 00000000000..9e01e86791a Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-edge.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-facet.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-facet.png new file mode 100644 index 00000000000..094f99e7dee Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-facet.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-vertex.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-vertex.png new file mode 100644 index 00000000000..bc28a83d440 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/insert-vertex.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-map.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-map.png new file mode 100644 index 00000000000..eb5c168ba5b Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-map.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-map2d.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-map2d.png new file mode 100644 index 00000000000..7582bb4198b Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-map2d.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-zoom.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-zoom.png new file mode 100644 index 00000000000..0ebf0e962c0 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-zoom.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-zoom2.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-zoom2.png new file mode 100644 index 00000000000..70383249599 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example-zoom2.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example.png new file mode 100644 index 00000000000..f2ddb883c89 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/intuitif-example.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/map2d-with-attrib.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/map2d-with-attrib.png new file mode 100644 index 00000000000..740c5b71048 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/map2d-with-attrib.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object2d-nonmanifold.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object2d-nonmanifold.png new file mode 100644 index 00000000000..295cae1986d Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object2d-nonmanifold.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object2d.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object2d.png new file mode 100644 index 00000000000..138fdd6fdeb Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object2d.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d-nonmanifold.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d-nonmanifold.png new file mode 100644 index 00000000000..564a6b3739f Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d-nonmanifold.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d-nonmanifold2.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d-nonmanifold2.png new file mode 100644 index 00000000000..d0583dc5514 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d-nonmanifold2.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d.png new file mode 100644 index 00000000000..3ccebb93a5d Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/object3d.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope1.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope1.png new file mode 100644 index 00000000000..7dc131e0e2d Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope1.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope2.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope2.png new file mode 100644 index 00000000000..f087a726b24 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope2.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope3.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope3.png new file mode 100644 index 00000000000..2074d24b1ea Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/ope3.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/pb-carte3D.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/pb-carte3D.png new file mode 100644 index 00000000000..7bf718403f8 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/pb-carte3D.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/pb2-carte3D.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/pb2-carte3D.png new file mode 100644 index 00000000000..90ade07b5d3 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/pb2-carte3D.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/quasivariete.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/quasivariete.png new file mode 100644 index 00000000000..957b0c3553f Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/quasivariete.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/quasivarietea.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/quasivarietea.png new file mode 100644 index 00000000000..f3c5e3012f9 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/quasivarietea.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/triangulation.png b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/triangulation.png new file mode 100644 index 00000000000..d6bf811cf43 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/png/triangulation.png differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/quasivariete.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/quasivariete.fig new file mode 100644 index 00000000000..be44ae52cc3 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/quasivariete.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/quasivarietea.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/quasivarietea.fig new file mode 100644 index 00000000000..42d45bc3d6b Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/quasivarietea.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/fig/triangulation.fig b/Combinatorial_map/doc_tex/Combinatorial_map/fig/triangulation.fig new file mode 100644 index 00000000000..5556caf0a41 Binary files /dev/null and b/Combinatorial_map/doc_tex/Combinatorial_map/fig/triangulation.fig differ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map/main.tex b/Combinatorial_map/doc_tex/Combinatorial_map/main.tex new file mode 100644 index 00000000000..053cde7db39 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map/main.tex @@ -0,0 +1,11 @@ + +\ccUserChapter{Combinatorial Maps\label{ChapterCombinatorialMap}} +\ccChapterAuthor{Guillaume Damiand} + +\input{Combinatorial_map/PkgDescription.tex} +\minitoc + + +\input{Combinatorial_map/Combinatorial_map.tex} + + diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/CellAttribute.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/CellAttribute.tex new file mode 100644 index 00000000000..75ebd9ff520 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/CellAttribute.tex @@ -0,0 +1,115 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: CellAttribute.tex +% +------------------------------------------------------------------------+ +% | 04.02.2010 Guillaume Damiand +% | Package: Combinatorial_map +% +------------------------------------------------------------------------+ +\ccRefPageBegin +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ +\begin{ccRefConcept}{CellAttribute} +%\ccRefLabel{CGAL::CellAttribute} + +\ccDefinition + +The concept \ccRefName\ represents a non void attribute associated +with a cell of a combinatorial map. It can keep a handle to one +dart of its associated cell, and can contain any information. + +% . The attribute keeps a handle to one dart +% of its associated cell when the template parameter \ccc{Tag} is +% \ccc{Tag_true} (bi-directional association between darts and +% attributes). If \ccc{Tag} is \ccc{Tag_false}, the attribute does not +% know a dart of its associated cell (uni-directional association from +% darts to attributes). + +% \ccParameters +% \ccc{Refs} must be a model of the \ccc{CombinatorialMap} concept defining +% \ccc{Dart_handle} and \ccc{Dart_const_handle} types.\\ +% \ccc{Tag} \ccc{Tag_true} to enable the storage of a +% \ccc{Dart_handle} of the associated cell, \ccc{Tag_false} otherwise.\\ +% \ccc{FunctorOnMerge} functor called when two attributes are merged. +% Must be a model of the \ccc{AttributeFunctor} concept.\\ +% \ccc{FunctorOnSplit} functor called when one attribute is split in two. +% Must be a model of the \ccc{AttributeFunctor} concept. + +\ccTypes +\ccNestedType{Dart_handle}{Dart handle type.} +\ccGlue +\ccNestedType{Dart_const_handle}{Dart const handle type.} + +\ccNestedType{Info}{Type of the information contained in the attribute. + If \ccc{void}, the cell attribute does not have any information.} + +\ccNestedType{Supports_cell_dart} + {Equals to \ccc{Tag_true} to enable the storage of a + \ccc{Dart_handle} of the associated cell, \ccc{Tag_false} otherwise.} + +\ccNestedType{On_merge}{Functor called before merging two attributes. Must be + a model of the \ccc{Binary Function} concept having two references + to a model of \ccc{CellAttribute} as type of both arguments and \ccc{void} as + return type.} +\ccGlue +\ccNestedType{On_split}{Functor called after an attribute was split in two. + Must be a model of the \ccc{Binary Function} concept having two references + to a model of \ccc{CellAttribute} as type of both arguments and \ccc{void} as + return type.} +%the \ccc{AttributeFunctor} concept + +% +-----------------------------------+ +\ccCreation +\ccCreationVariable{ca} + +\ccConstructor{CellAttribute();}{} + +\ccConstructor{Cell_attribute(const Info& info);} + {Constructor initializing the information of \ccc{ca} by the + copy contructor \ccc{Info(info)}. + Defined only if \ccc{Info} is different from \ccc{void}.} + +% +-----------------------------------+ +\ccHeading{Access Member Functions} + +\ccMethod{Dart_handle dart();} + {Returns one dart of the cell associated to attribute \ccc{ca}. + NULL if \ccc{Supports_cell_dart} is equal to \ccc{Tag_false}.} +\ccGlue +\ccMethod{Dart_const_handle dart() const;} + {Returns one dart of the cell associated to attribute \ccc{ca}, + when \ccc{ca} is const. + NULL if \ccc{Supports_cell_dart} is equal to \ccc{Tag_false}.} + +\ccMethod{void set_dart(Dart_handle ahandle);} + {Sets the dart of the cell associated to attribute \ccc{ca} to \ccc{ahandle}, + if \ccc{Supports_cell_dart} is equal to \ccc{Tag_true}. + Otherwise, this method does nothing. + \ccPrecond{\ccc{ahandle} belongs to the cell associated to \ccc{ca}.} +} + +\ccMethod{Info& info();} + {Returns the information of \ccc{ca}. + Defined only if \ccc{Info} is different from \ccc{void}.} + +\ccMethod{const Info& info() const;} + {Returns the information of \ccc{ca}, when \ccc{ca} is const. + Defined only if \ccc{Info} is different from \ccc{void}.} + +\ccHasModels +\ccRefIdfierPage{CGAL::Cell_attribute} +%\ccRefIdfierPage{CGAL::Cell_attribute_with_info}\\ + +% \ccRefIdfierPage{CGAL::Cell_with_point}\\ +% \ccRefIdfierPage{CGAL::Cell_with_point_and_attribute}\\ + + +\ccSeeAlso +%\ccRefConceptPage{CGAL::AttributeFunctor}\\ +\ccRefConceptPage{CombinatorialMap}\\ +\ccRefConceptPage{CombinatorialMapItems} + +\end{ccRefConcept} +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +\ccRefPageEnd +% EOF +% +------------------------------------------------------------------------+ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/Cell_attribute.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Cell_attribute.tex new file mode 100644 index 00000000000..9ff565d5472 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Cell_attribute.tex @@ -0,0 +1,90 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Cell_attribute.tex +% +------------------------------------------------------------------------+ +% | 04.02.2010 Guillaume Damiand +% | Package: Combinatorial_map +% +------------------------------------------------------------------------+ +\ccRefPageBegin +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ +\begin{ccRefClass}{Cell_attribute} +\ccRefLabel{CGAL::Cell_attribute} + +\ccInclude{CGAL/Cell_attribute.h} + +\ccDefinition + +The class \ccRefName\ represents an attribute containing (or not) an information. + +\ccIsModel +\ccRefConceptPage{CellAttribute} + +\ccParameters +\ccc{CMap} must be a model of the \ccc{CombinatorialMap}.\\ +\ccc{Info_} is the type of the information contained in the attribute.\\ +% If \ccc{void}, the cell attribute does not have any information.\\ +\ccc{Tag} is \ccc{Tag_true} to enable the storage of a + \ccc{Dart_handle} of the associated cell, \ccc{Tag_false} otherwise.\\ +\ccc{OnMerge} is the type of the functor called before two attributes are merged.\\ +% Must +% be either \ccc{Null_functor}, or a model of the +% \ccc{Binary Function} concept having +% \ccc{Cell_attribute} as type of +% both arguments and \ccc{void} as return type.\\ +\ccc{OnSplit} is the type of the functor called after one attribute is split in two. + % Must be either \ccc{Null_functor}, or a model of the + % \ccc{Binary Function} concept having + % \ccc{Cell_attribute} as type of both + % arguments and \ccc{void} as return type. + + By default, \ccc{OnMerge} and \ccc{OnSplit} are equal to + \ccc{Null_functor}; \ccc{Tag} is equal to + \ccc{Tag_true}; and \ccc{Info_} is equal to \ccc{void}. + +\ccTypes +\ccThree{typedef CMap::Dart_const_handle}{}{} +\ccTypedef{typedef Info_ Info;}{} +\ccGlue +\ccTypedef{typedef Tag Supports_cell_dart;}{} +\ccGlue +\ccTypedef{typedef OnMerge On_merge;}{} +\ccGlue +\ccTypedef{typedef OnSplit On_split;}{} + +\ccTypedef{typedef CMap::Dart_handle Dart_handle;}{} +\ccGlue +\ccTypedef{typedef CMap::Dart_const_handle Dart_const_handle;}{} + +% +-----------------------------------+ +% \ccCreation +% \ccCreationVariable{ca} + +% \ccConstructor{Cell_attribute();}{} + +% \ccConstructor{Cell_attribute(const Info& info);} +% {Constructor initializing the information of \ccc{ca} by the +% copy contructor \ccc{Info(info)}. +% Defined only if \ccc{Info} is different from \ccc{void}.} + +% % +-----------------------------------+ +% \ccHeading{Access Member Functions} + +% \ccMethod{Info& info();} +% {Returns the information of \ccc{cawi}. +% Defined only if \ccc{Info} is different from \ccc{void}.} + +% \ccMethod{const Info& info() const;} +% {Returns the information of \ccc{cawi}, when \ccc{cawi} is const. +% Defined only if \ccc{Info} is different from \ccc{void}.} + +\ccSeeAlso +%\ccRefIdfierPage{CGAL::Void_functor}\\ +%\ccRefIdfierPage{CGAL::Cell_attribute_with_info}\\ +\ccRefIdfierPage{CGAL::Combinatorial_map} + +\end{ccRefClass} +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +\ccRefPageEnd +% EOF +% +------------------------------------------------------------------------+ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/CombinatorialMap.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/CombinatorialMap.tex new file mode 100644 index 00000000000..ecc79f3411f --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/CombinatorialMap.tex @@ -0,0 +1,493 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: CombinatorialMap.tex +% +------------------------------------------------------------------------+ +% | 04.02.2010 Guillaume Damiand +% | Package: Combinatorial_map +% +------------------------------------------------------------------------+ +\ccRefPageBegin +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ +\begin{ccRefConcept}{CombinatorialMap} +%\ccRefLabel{CGAL::CombinatorialMap} + +\ccDefinition + +The concept \ccRefName\ defines a $d$-dimensional combinatorial map. + +%\ccParameters +%\ccc{d} an integer for the dimension of the map.\\ +%\ccc{Items} must be a model of the \ccc{CombinatorialMapItems} concept. \\ +%\ccc{Alloc} must be a standard allocator for \stl\ container classes. + +%\ccIsModel + +\ccCreation +\ccCreationVariable{cm} +\ccConstructor{CombinatorialMap();}{Default constructor.} + +%%%%%%%%%%%%% TYPES +\ccTypes +\ccNestedType{Dart}{Dart type, a model of the \ccc{Dart} concept.} +\ccGlue +\ccNestedType{Dart_handle}{Dart handle type, equal to \ccc{Dart::Dart_handle}.} +\ccGlue +\ccNestedType{Dart_const_handle}{Dart const handle type, equal to \ccc{Dart::Dart_const_handle}.} +\ccGlue +\ccNestedType{size_type}{Size type (an unsigned integral type).} + + +% +-----------------------------------+ +\ccConstants +\ccVariable{static unsigned int dimension;}{The dimension $d$ of \ccc{cm}, equal to \ccc{Dart::dimension.}} +\ccGlue +\ccVariable{static size_type NB_MARKS;}{The number of available Boolean marks of \ccc{cm}.} +\ccGlue +\ccVariable{static Dart_handle null_dart_handle;}{The null dart handle constant: a dart \ccc{d0} + is $i$-free if \ccc{d0.beta(i)==null_dart_handle}. + Note that \ccc{*null_dart_handle}$\notin$ \ccc{cm.darts()}.} + + +% \ccGlue +% \ccNestedType{Dart_container}{dart container type.} + +%\ccNestedType{Items}{the items class provided as template parameter.} +\ccHeading{Types for attributes} + +\ccNestedType{Attributes} +{The tuple of attributes, containing at most + $dimension+1$ types (one for each possible cell of the combinatorial + map). Each type of the tuple must be either a model of the + \ccc{CellAttribute} concept or \ccc{void}. + The first type corresponds to 0-attributes, + the second to 1-attributes and so on. + If the $i^{\mbox{th}}$ type in the tuple is \ccc{void}, + $(i-1)$-attributes are disabled. Otherwise, $(i-1)$-attributes are enabled and + have the given type. If the size of the tuple is $k$, + with $k < dimension+1$, $\forall i: k \leq i \leq dimension$, + $i$-attributes are disabled.} + +\ccNestedType{template Attribute_type::type} + {Type of $i$-attributes, a model of \ccc{CellAttribute} concept. + \ccc{Attribute_type::type::Dart_handle} is equal to \ccc{Dart_handle}, and + \ccc{Attribute_type::type::Dart_const_handle} is equal to \ccc{Dart_const_handle}. + \ccPrecond{$0 \leq i \leq dimension$ and $i$-attributes are non void.}} +\ccGlue +\ccNestedType{template Attribute_handle::type} + {Handle to $i$-attributes, equal to \ccc{Dart::Attribute_handle::type}. + \ccPrecond{$0 \leq i \leq dimension$ and $i$-attributes are non void.}} +\ccGlue +\ccNestedType{template Attribute_const_handle::type} + {Const handle to $i$-attributes, equal to \ccc{Dart::Attribute_const_handle::type}. + \ccPrecond{$0 \leq i \leq dimension$ and $i$-attributes are non void.}} + +\ccHeading{Range types} +\ccNestedType{Dart_range}{Range of all the darts of \ccc{cm}. + This type is a model of \ccc{Range} concept, its iterator type is bidirectional and its value type is \ccc{Dart}.} +\ccGlue +\ccNestedType{Dart_const_range}{Const range of all the darts of \ccc{cm}. + This type is a model of \ccc{ConstRange} concept, its iterator type is bidirectional and its value type is \ccc{Dart}.} + +\ccNestedType{template Attribute_range::type} +{Range of all the $i$-attributes (which must be non void), with $0 \leq i \leq dimension$. + This type is a model of \ccc{Range} concept, its iterator type is bidirectional and its value type is \ccc{Attribute_type::type}.} +\ccGlue +\ccNestedType{template Attribute_const_range::type} +{Const range of all the $i$-attributes (which must be non void), with $0 \leq i \leq dimension$. + This type is a model of \ccc{ConstRange} concept, its iterator type is bidirectional and its value type is \ccc{Attribute_type::type}.} + +% +\ccNestedType{template Dart_of_orbit_range} +{Range of all the darts of the \ccc{} orbit. + This type is a model of \ccc{Range} concept, its iterator type is forward and its value type is \ccc{Dart}.} +\ccGlue +\ccNestedType{template Dart_of_orbit_const_range} +{Const range of all the darts of the \ccc{} orbit. + This type is a model of \ccc{ConstRange} concept, its iterator type is forward and its value type is \ccc{Dart}.} + +\ccNestedType{template Dart_of_cell_range} +{Range of all the darts of an $i$-cell in $dim$ dimension + (with $0\leq i \leq dim+1$ and $0 \leq dim \leq dimension$). If $i==dim+1$, + range of all the darts of a connected component. + This type is a model of \ccc{Range} concept, its iterator type is forward and its value type is \ccc{Dart}.} +\ccGlue +\ccNestedType{template Dart_of_cell_const_range} +{Const range of all the darts of the $i$-cell in $dim$ dimension + (with $0\leq i \leq dim+1$ and $0 \leq dim \leq dimension$). If $i==dim+1$, + range of all the darts of a connected component. + This type is a model of \ccc{ConstRange} concept, its iterator type is forward and its value type is \ccc{Dart}.} + +\ccNestedType{template + One_dart_per_incident_cell_range} +{Range of one dart of each $i$-cell incident to one $j$-cell. + Cells are considered in $dim$ dimension + (with $0\leq i \leq dim+1$, $0\leq j \leq dim+1$ and + $0 \leq dim \leq dimension$). If $i==dim+1$, + consider each connected component instead of each $i$-cell. If $j==dim+1$, + consider one connected component instead of one $j$-cell. + This type is a model of \ccc{Range} concept, its iterator type is forward and its value type is \ccc{Dart}.} +\ccGlue +\ccNestedType{template + One_dart_per_incident_cell_const_range} +{Const range of one dart of each $i$-cell incident to one $j$-cell. + Cells are considered in $dim$ dimension + (with $0\leq i \leq dim+1$, $0\leq j \leq dim+1$ and + $0 \leq dim \leq dimension$). If $i==dim+1$, + consider each connected component instead of each $i$-cell. If $j==dim+1$, + consider one connected component instead of one $j$-cell. + This type is a model of \ccc{ConstRange} concept, its iterator type is forward and its value type is \ccc{Dart}.} + +\ccNestedType{template One_dart_per_cell_range} +{Range of one dart of each $i$-cell of \ccc{cm}. + Cells are considered in $dim$ dimension + (with $0\leq i \leq dim+1$ and $0 \leq dim \leq dimension$). If $i==dim+1$, + consider each connected component instead of each $i$-cell. + This type is a model of \ccc{Range} concept, its iterator type is forward and its value type is \ccc{Dart}.} +\ccGlue +\ccNestedType{template One_dart_per_cell_const_range} +{Const range of one dart of each $i$-cell of \ccc{cm}. + Cells are considered in $dim$ dimension + (with $0\leq i \leq dim+1$ and $0 \leq dim \leq dimension$). If $i==dim+1$, + consider each connected component instead of each $i$-cell. + This type is a model of \ccc{ConstRange} concept, its iterator type is forward and its value type is \ccc{Dart}.} + +% +-----------------------------------+ +\ccHeading{Access Member Functions} + +\ccMethod{bool is_empty() const;} {Returns true iff \ccc{cm} is empty, + i.e. it contains no dart.} + +\ccMethod{bool is_valid() const;} + {Returns true iff \ccc{cm} is valid.} +A combinatorial map \ccc{cm} is valid (see Sections~\ref{ssec-combi-map-and-darts} and \ref{ssec-combimap-validity}) if for all dart handle $dh$ such that +\ccc{*dh} $\in$\ccc{cm.darts()}:\\ +\begin{itemize} +\item \ccc{dh->is_free(0)}, or \ccc{dh->beta(0)->beta(1)==dh}; +\item \ccc{dh->is_free(1)}, or \ccc{dh->beta(1)->beta(0)==dh}; +\item $\forall i$, $2\leq i\leq dimension$: + \ccc{dh->is_free(i)}, or \ccc{dh->beta(i)->beta(i)==dh}; +\item $\forall i, j$, $0\leq ibeta(i)->beta(j)==null_dart_handle} or + \ccc{dh->beta(i)->beta(j)->beta(i)->beta(j)==dh}; +\item $\forall i$, $0\leq i\leq dimension$ such that $i$-attributes are non void: + $\forall dh2$ such that \ccc{*dh2} belong to the same $i$-cell than \ccc{*dh}: + \ccc{dh2->attribute()==dh->attribute()}. + \end{itemize} + +\ccMethod{bool is_without_boundary(unsigned int i) const;} + {Returns true iff \ccc{cm} is wihout $i$-boundary + (i.e. there is no \ccc{i}-free dart). + \ccPrecond{$0\leq i \leq dimension$.}} + +\ccMethod{bool is_without_boundary() const;} + {Returns true iff \ccc{cm} is without boundary in all dimensions.} + +\ccMethod{size_type number_of_darts() const;} + {Returns the number of darts in \ccc{cm}.} + +\ccMethod{Dart_handle dart_handle(Dart& adart);} + {Returns the dart handle of \ccc{adart}.} +\ccGlue +\ccMethod{Dart_const_handle dart_handle(const Dart& adart) const;} + {Returns the dart const handle of \ccc{adart}.} + +% \ccMethod{template static bool are_attributes_enabled();} +% {Returns true iff $i$-attributes are non voidin \ccc{cm}. +% \ccPrecond{$0 \leq i \leq dimension$.}} + +\ccMethod{template size_type number_of_attributes() const;} + {Returns the number of $i$-attributes in \ccc{cm}. + \ccPrecond{$0 \leq i \leq dimension$, and $i$-attributes are non void.}} + +\ccMethod{template bool is_sewable(Dart_const_handle dh1, Dart_const_handle dh2) const;} + {Returns true iff \ccc{dh1} can be $i$-sewn with \ccc{dh2} by + keeping \ccc{cm} valid, i.e. if there is + a bijection $f$ between all the darts of the orbit + $D_1=\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}(dh1)$ and + $D_2=\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}(dh2)$ + satisfying: $f(dh1)=dh2$, and for all $d'_1 \in D_1$, for all $j\in + \{1,\ldots,i-2,i+2,\ldots,d\}$, + $f(\mb{j}(d'_1))=\mb{j}^{-1}(f(d'_1))$. + \ccPrecond{$0 \leq i \leq dimension$, \ccc{*dh1}$\in$\ccc{cm.darts()}, + and \ccc{*dh2}$\in$\ccc{cm.darts()}.}} + +\ccMethod{std::ostream& display_characteristics(std::ostream & os) const;} +{Displays on \ccc{os} the characteristics of \ccc{cm}: its number of darts, + its number of $i$-cells, for each $i$, $0\leq i\leq CMap::dimension$, + and its number of connected components.} +Example of output for a 3D combinatorial map containing two disjoint +combinatorial tetrahedra:\\ +\texttt{\#Darts=24, \#0-cells=8, \#1-cells=12, \#2-cells=8, \#3-cells=2, \#ccs=2} + + +% +-----------------------------------+ +\ccHeading{Range Access Member Functions} + +\ccMethod{Dart_range& darts();} + {Returns a range of all the darts in \ccc{cm}.} +\ccGlue +\ccMethod{Dart_const_range& darts() const;} + {Returns a const range of all the darts in \ccc{cm}.} + +\ccMethod{template Attribute_range::type & attributes();} + {Returns a range of all the $i$-attributes in \ccc{cm}. + \ccPrecond{$0 \leq i \leq dimension$, and $i$-attributes are non void.}} +\ccGlue +\ccMethod{template Attribute_const_range::type & attributes() const;} + {Returns a const range of all the $i$-attributes in \ccc{cm}. + \ccPrecond{$0 \leq i \leq dimension$, and $i$-attributes are non void.}} + +% \ccMethod{std::vector count_cells(const std::vector& acells) const;} +% {count the number of $i$-cells of the combinatorial map, for each $i$ in the +% \ccc{std::vector} \ccc{acells}, with $0 \leq i \leq dimension+1$ +% (for $i=dimension+1$, count the number of connected component). +% Return a \ccc{std::vector} of size $dimension+2$ containing, for each +% $i$ in \ccc{acells}, the number of $i$-cell.} + +\ccMethod{template Dart_of_orbit_range darts_of_orbit(Dart_handle dh);} + {Returns a range of all the darts of the orbit \ccc{(dh)}. + \ccPrecond{\ccc{*dh}$\in$\ccc{cm.darts()} and \ccc{Beta...} is a + sequence of integers $i_1,\ldots,i_k$, such that each $i_j \in + \{0,\ldots,dimension\}$, with $i_1 Dart_of_orbit_const_range darts_of_orbit(Dart_const_handle dh) const;} + {Returns a const range of all the darts of the orbit \ccc{(dh)}. + \ccPrecond{Same as for the non const version.}} + +\ccMethod{template Dart_of_cell_range darts_of_cell(Dart_handle dh);} + {Returns a range of all the darts of the $i$-cell containing \ccc{dh}. + $i$-cells are considered in $dim$ dimension. If $i==dim+1$, + range of all the darts of the connected component containing \ccc{dh}. + \ccPrecond{\ccc{*dh}$\in$\ccc{cm.darts()}, + $0\leq i \leq dim+1$ and $0 \leq dim \leq dimension$.}} +\ccGlue +\ccMethod{template Dart_of_cell_const_range darts_of_cell(Dart_const_handle dh) const;} + {Returns a const range of all the darts of the $i$-cell containing \ccc{dh}. + $i$-cells are considered in $dim$ dimension. If $i==dim+1$, + const range of all the darts of the connected component containing \ccc{dh}. + \ccPrecond{Same as for the non const version.}} + +\ccMethod{template One_dart_per_incident_cell_range one_dart_per_incident_cell(Dart_handle dh);} + {Returns a range of one dart of each $i$-cell incident to the $j$-cell + containing \ccc{dh}. Cells are considered in $dim$ dimension. If $i==dim+1$, + consider each connected component instead of each $i$-cell. If $j==dim+1$, + consider the connected component containing \ccc{dh} instead of the $j$-cell. + \ccPrecond{\ccc{*dh}$\in$\ccc{cm.darts()}, $0\leq i \leq dim+1$, + $0\leq j \leq dim+1$ and $0\leq dim \leq dimension$.}} +\ccGlue +\ccMethod{template One_dart_per_incident_cell_const_range one_dart_per_incident_cell(Dart_const_handle dh) const;} + {Returns a const range of one dart of each $i$-cell incident to the $j$-cell + containing \ccc{dh}. Cells are considered in $dim$ dimension. If $i==dim+1$, + consider each connected component instead of each $i$-cell. If $j==dim+1$, + consider the connected component containing \ccc{dh} instead of the $j$-cell. + \ccPrecond{Same as for the non const version.}} + +\ccMethod{template One_dart_per_cell_range one_dart_per_cell();} + {Returns a range of one dart of each $i$-cell in \ccc{cm}. + Cells are considered in $dim$ dimension. If $i==dim+1$, + range of one dart of each connected component in \ccc{cm}. + \ccPrecond{$0\leq i \leq dim+1$ and $0\leq dim \leq dimension$.}} +\ccGlue +\ccMethod{template One_dart_per_cell_const_range one_dart_per_cell() const;} + {Returns a const range of one dart of each $i$-cell in \ccc{cm}. + Cells are considered in $dim$ dimension. If $i==dim+1$, + const range of one dart of each connected component in \ccc{cm}. + \ccPrecond{Same as for the non const version.}} + +% +-----------------------------------+ +\ccHeading{Modifiers} +\ccMethod{Dart_handle create_dart();} + {Creates a new dart in \ccc{cm}, and returns the corresponding handle. + A new dart is initialized to be $i$-free, + $\forall i$: $0 \leq i \leq dimension$, and to have no associated + attribute for each non void attribute. + } +\ccMethod{void erase_dart(Dart_handle dh);} + {Removes \ccc{dh} from \ccc{cm}.} + +\ccMethod{template Attribute_handle::type create_attribute();} +{Creates a new $i$-attribute in \ccc{cm}, and returns the corresponding handle. + \ccPrecond{$0 \leq i \leq dimension$, and $i$-attributes are non void.}} + +\ccMethod{template Attribute_handle::type + create_attribute(const A&a);} +{Creates a new $i$-attribute in \ccc{cm} initialized + by the constructor \ccc{A(a)}, and returns the corresponding handle. \ccc{A} must be + a type compatible with the information contained in the $i$-attributes + (compatible means that there is a constructor for the information type + taking an $A$ as parameter). + \ccPrecond{$0 \leq i \leq dimension$, and $i$-attributes are non void.}} + +\ccMethod{template void erase_attribute(Attribute_handle::type ah);} +{Removes the $i$-attribute \ccc{ah} from \ccc{cm}. + \ccPrecond{$0 \leq i \leq dimension$, $i$-attributes are non void, + and \ccc{*ah}$\in$\ccc{cm.attributes()}.}} + +\ccMethod{template void set_attribute(Dart_handle dh, Attribute_handle::type ah);} + {Associates the $i$-attribute of all the darts of the $i$-cell + containing \ccc{dh} to \ccc{ah}. + \ccPrecond{\ccc{*dh}$\in$\ccc{cm.darts()}, $0 \leq i \leq dimension$, + $i$-attributes are non void, and \ccc{*ah}$\in$\ccc{cm.attributes()}.}} + +\ccMethod{void clear();} + {Deletes all the darts and all the attributes of \ccc{cm}.} +% +-----------------------------------+ +\ccOperations + +\ccMethod{template void sew(Dart_handle dh1, + Dart_handle dh2, bool update_attributes=true);} {Links by $\beta_i$ + two by two all the darts of the orbit + $D_1=\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}$(\ccc{dh1}) and + $D_2=\orb{\mb{0},\mb{2},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}$(\ccc{dh2}) + such that $d_2=f(d_1)$, $f$ being the bijection between $D_1$ and $D_2$ + satisfying: $f(dh1)=dh2$, and for all $d'_1 \in D_1$, for all $j\in + \{1,\ldots,i-2,i+2,\ldots,d\}$, + $f(\mb{j}(d'_1))=\mb{j}^{-1}(f(d'_1))$. + + If \ccc{update_attributes} is \ccc{true}, when necessary, non void + attributes are updated to ensure the validity of \ccc{cm}: for each + $j$-cells $c_1$ and $c_2$ which are merged into one $j$-cell during + the sew, the two associated attributes $attr_1$ and $attr_2$ are + considered. If one attribute is + NULL and the other not, the non NULL attribute is associated to all + the darts of the resulting cell. When the two attributes are non + NULL, functor \ccc{Attribute_type::type::On_merge} is called on + the two attributes $attr_1$ and $attr_2$. Then, the attribute + $attr_1$ is associated to all darts of the resulting + $j$-cell. Finally, attribute $attr_2$ is removed from \ccc{cm}. + \ccPrecond{\ccc{cm.is_sewable(dh1,dh2)}.} + \begin{ccAdvanced} + If \ccc{update_attributes} is \ccc{false}, non void attributes are + not updated; thus \ccc{cm} can be no more valid after this + modification. + \end{ccAdvanced} +} + +\ccMethod{template void unsew(Dart_handle dh, bool + update_attributes=true);} {Unlinks by $\beta_i$ all the darts in the + orbit + $\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}$(\ccc{dh}). If + \ccc{update_attributes} is \ccc{true}, when necessary, non void + attributes are updated to ensure the validity of \ccc{cm}: for each + $j$-cell $c$ split in two $j$-cells $c_1$ and $c_2$ by the + operation, if $c$ is associated to a $j$-attribute $attr_1$, then + this attribute is duplicated into $attr_2$, and all the darts + belonging to $c_2$ are associated with this new attribute. Finally, + the functor \ccc{Attribute_type::type::On_split} is called on the + two attributes $attr_1$ and $attr_2$. + \ccPrecond{$0 \leq i \leq dimension$, \ccc{*dh}$\in$\ccc{cm.darts()} and + \ccc{dh} is not $i$-free.} +\begin{ccAdvanced} + If \ccc{update_attributes} is \ccc{false}, non void attributes are + not updated thus \ccc{cm} can be no more valid after this + modification. +\end{ccAdvanced}} + +\begin{ccAdvanced} + +\ccMethod{template void link_beta(Dart_handle dh1, Dart_handle dh2, bool update_attributes=true);} +{Links \ccc{dh1} and \ccc{dh2} by $\beta_i$. + \ccc{cm} can be no more valid after this modification. If + \ccc{update_attributes} is true, non void attributes of \ccc{dh1} and + \ccc{dh2} are updated: if one dart has an attribute and the second + dart not, the non null attribute is associated to the dart having a null attribute. + If both darts have an attribute, + the attribute of \ccc{dh1} is associated to \ccc{dh2}. + \ccPrecond{$0 \leq i \leq dimension$, \ccc{*dh1}$\in$\ccc{cm.darts()}, + \ccc{*dh2}$\in$\ccc{cm.darts()} and ($i<2$ or \ccc{dh1}$\neq$\ccc{dh2}).}} + + +% \ccMethod{template void link_beta(Dart_handle dh1, +% Dart_handle dh2);} +% {link the two given darts for the given dimension $i$ +% (with $0 \leq i \leq n$). Put in relation dh1 with dh2 +% and dh2 with dh1.} + +% \ccMethod{void unlink_beta(Dart_handle dh, unsigned int i);} +% {remove the relation between dh and its neighbor for the given +% dimension $i$ (with $2 \leq i \leq n$). Remove the link in both +% directions (for dh and for its neighbor).} + +\ccMethod{template void unlink_beta(Dart_handle dh);} + {Unlinks \ccc{dh} and $\beta_i($\ccc{dh}$)$ by $\beta_i$ . + \ccc{cm} can be no more valid after this modification. + Attributes of \ccc{dh} and $\beta_i$(\ccc{dh}) + are not modified. + \ccPrecond{$0 \leq i \leq dimension$, \ccc{*dh}$\in$\ccc{cm.darts()}, + and \ccc{dh} is not $i$-free.}} + +% \ccMethod{template +% void topo_sew(Dart_handle dh1, Dart_handle dh2);} +% {Links by $\beta_i$ two by two all the darts of the orbit +% $\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}$ for darts \ccc{dh1} +% and \ccc{dh2}. +% \ccPrecond{\ccc{cm.is_sewable(dh1,dh2)}.} +% } + +% \ccMethod{template void topo_unsew(Dart_handle dh);} +% {Unlinks by $\beta_i$ all the darts in the orbit +% $\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}$ for \ccc{dh}. +% Non Void attributes are not updated thus \ccc{cm} +% can be no more valid after this modification. +% \ccPrecond{$0 \leq i \leq dimension$, \ccc{dh}$\in$\ccc{cm.darts()}, +% and \ccc{dh} is not $i$-free.}} +\end{ccAdvanced} + +% +-----------------------------------+ +\begin{ccAdvanced} +\ccHeading{Boolean marks} + +\ccMethod{int get_new_mark() const;}{Reserves a new mark. Returns its + index. Returns -1 if there is no more available free mark.} + +\ccMethod{bool is_reserved(int amark) const;} + {Returns true iff \ccc{amark} is a reserved mark of \ccc{cm}. + \ccPrecond{$amark \geq 0$ and $amark <$ \ccc{NB_MARKS}.}} + +\ccMethod{bool is_marked(Dart_const_handle dh, int amark) const;} + {Returns true iff \ccc{dh} is marked for \ccc{amark}. + \ccPrecond{\ccc{is_reserved(amark)} and \ccc{*dh}$\in$\ccc{cm.darts()}.}} + +\ccMethod{void mark(Dart_const_handle dh, int amark) const;} + {Marks \ccc{dh} for \ccc{amark}. + \ccPrecond{\ccc{is_reserved(amark)} and \ccc{*dh}$\in$\ccc{cm.darts()}.}} + +\ccMethod{void unmark(Dart_const_handle dh, int amark) const;} + {Unmarks \ccc{dh} for the mark \ccc{amark}. + \ccPrecond{\ccc{is_reserved(amark)} and \ccc{*dh}$\in$\ccc{cm.darts()}.}} + +\ccMethod{void negate_mark(int amark) const;} + {Inverse the mark \ccc{amark} for all the darts of \ccc{cm}. + All the marked darts become unmarked and all the unmarked darts + become marked. + \ccPrecond{\ccc{is_reserved(amark)}.}} + +\ccMethod{void unmark_all(int amark) const;} + {Unmarks all the darts of \ccc{cm} for \ccc{amark}. + \ccPrecond{\ccc{is_reserved(amark)}.}} + +\ccMethod{size_type number_of_marked_darts(int amark) const;} + {Returns the number of marked darts for \ccc{amark}. + \ccPrecond{\ccc{is_reserved(amark)}.}} + +\ccMethod{size_type number_of_unmarked_darts(int amark) const;} + {Return the number of unmarked darts for \ccc{amark}. + \ccPrecond{\ccc{is_reserved(amark)}.}} + +\ccMethod{void free_mark(int amark) const;} + {Frees \ccc{amark}. + \ccPrecond{\ccc{is_reserved(amark)}.}} +\end{ccAdvanced} + +\ccHasModels +\ccRefIdfierPage{CGAL::Combinatorial_map} + +% \ccSeeAlso +% \ccRefIdfierPage{CGAL::CombinatorialMapWithPoints} + +\end{ccRefConcept} +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +\ccRefPageEnd +% EOF +% +------------------------------------------------------------------------+ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/CombinatorialMapItems.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/CombinatorialMapItems.tex new file mode 100644 index 00000000000..3d12a473ce3 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/CombinatorialMapItems.tex @@ -0,0 +1,119 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: CombinatorialMapItems.tex +% +------------------------------------------------------------------------+ +% | 04.02.2010 Guillaume Damiand +% | Package: Combinatorial_map +% +------------------------------------------------------------------------+ +\ccRefPageBegin +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + +\begin{ccRefConcept}{CombinatorialMapItems} +%\ccRefLabel{CGAL::CombinatorialMapItems} + +\ccDefinition + +The concept \ccRefName\ allows to customize a $d$D combinatorial map +by choosing the type of darts, and by enabling and disabling some +attributes. For that, it defines an inner class template named +\ccc{Dart_wrapper}, with one template parameter, \ccc{CMap}, a model +of the \ccc{CombinatorialMap} concept. This inner class must define +two types: \ccc{Dart} and \ccc{Attributes}. + +% A \ccRefName\ contains one static const unsigned +% int \ccc{NB_MARKS} for the number of Boolean marks. It contains also +% one member class template named \ccc{Dart_wrapper}, with one template +% parameter, \ccc{Refs}. \ccc{Refs} must be a model of +% \ccc{CombinatorialMap} concept. The \ccc{Dart_wrapper} member class +% template provides a local type named \ccc{Dart} which must be a model +% of \ccc{Dart} concept, and a local type named \ccc{Attributes_enabled} +% which must be a tuple of types, each one being a model of +% \ccc{CellAttribute} concept, or equal to \ccc{Disabled}. + +% The tuple \ccc{Attributes_enabled} must contain at most $d+1$ types +% (one for each possible cell of the $d$-map). The first type +% corresponds to 0-cell attributes, the second to 1-cell attributes and +% so on. If a type is \ccc{CGAL::Disabled}, the corresponding cell +% attribute is disabled. If the size of the tuple is $k < d+1$, each +% $i$-cell attributes, $\forall i: k \leq d+1$, is disabled (see +% examples below). + +% \ccConstants +% \ccVariable{static unsigned int NB_MARKS;}{The number of Boolean marks.} + +\begin{ccClass}{CombinatorialMapItems::Dart_wrapper} +\ccCreationVariable{dw} + +\ccHeading{% + Types in \ccc{CombinatorialMapItems::Dart_wrapper}} + +\ccNestedType{Dart} + {The type of dart, a model of the \ccc{Dart} concept.} + +\ccNestedType{Attributes} +{The tuple of attributes, containing at most + $dimension+1$ types (one for each possible cell of the combinatorial + map). Each type of the tuple must be either a model of the + \ccc{CellAttribute} concept or \ccc{void}. + The first type corresponds to 0-attributes, + the second to 1-attributes and so on. + If the $i^{\mbox{th}}$ type in the tuple is \ccc{void}, + $(i-1)$-attributes are disabled. Otherwise, $(i-1)$-attributes are enabled and + have the given type. If the size of the tuple is $k$, + with $k < dimension+1$, $\forall i: k \leq i \leq dimension$, + $i$-attributes are disabled.} +\end{ccClass} + +\ccExample +The following examples show two possible models of the +\ccc{CombinatorialMapItems} concept: the first one for a 4D +combinatorial map without enabled attributes, the second one for a 3D +combinatorial map with edge attributes enabled, and associated with a +\ccc{Cell_attribute} containing an \ccc{int}. + +\begin{ccExampleCode} +struct Exemple_Item_4 +{ + template < class CMap > + struct Dart_wrapper + { + typedef CGAL::Dart<4, CMap> Dart; + typedef CGAL::cpp0x::tuple<> Attributes; + }; +}; +\end{ccExampleCode} + +\begin{ccExampleCode} +struct Exemple_Item_3 +{ + template < class CMap > + struct Dart_wrapper + { + typedef CGAL::Dart<3, CMap> Dart; + typedef Cell_attribute Edge_attrib; + typedef CGAL::cpp0x::tuple Attributes; + }; +}; +\end{ccExampleCode} + +\ccHasModels +\ccRefIdfierPage{CGAL::Combinatorial_map_min_items} + +\ccSeeAlso +% \ccRefConceptPage{HalfedgeDS}\\ +% \ccRefConceptPage{HalfedgeDSVertex}\\ +% \ccRefConceptPage{HalfedgeDSHalfedge}\\ +% \ccRefConceptPage{HalfedgeDSFace}\\ +% \ccRefConceptPage{PolyhedronItems_3}\\ +% \ccRefIdfierPage{CGAL::HalfedgeDS_vertex_base}\\ +% \ccRefIdfierPage{CGAL::HalfedgeDS_halfedge_base}\\ +\ccRefConceptPage{CombinatorialMap}\\ +\ccRefConceptPage{Dart} + +\end{ccRefConcept} +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +\ccRefPageEnd +% EOF +% +------------------------------------------------------------------------+ + diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map.tex new file mode 100644 index 00000000000..0d0f3647107 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map.tex @@ -0,0 +1,73 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Combinatorial_map.tex +% +------------------------------------------------------------------------+ +% | 04.02.2010 Guillaume Damiand +% | Package: Combinatorial_map +% +------------------------------------------------------------------------+ +\ccRefPageBegin +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + +\begin{ccRefClass}{Combinatorial_map} +\ccRefLabel{CGAL::Combinatorial_map} + +\ccInclude{CGAL/Combinatorial_map.h} + +\ccDefinition + +The class \ccRefName\ represents a $d$D combinatorial map. + +Darts and non void attributes are stored in memory using +\ccc{CGAL::Compact_container}, using \ccc{Alloc} as allocator. + +\ccIsModel +\ccRefConceptPage{CombinatorialMap} + +\ccParameters +\ccc{d} an integer for the dimension of the map.\\ +\ccc{Items} must be a model of the \ccc{CombinatorialMapItems} concept. \\ +\ccc{Alloc} must be a standard allocator for \stl\ container classes. + +There are two default template arguments: +\ccc{Combinatorial_map_min_items} for \ccc{Items} and +\ccc{CGAL_ALLOCATOR(int)} for \ccc{Alloc}. + +\ccTypes +\ccThree{typedef Combinatorial_map}{}{} +\ccTypedef{typedef Combinatorial_map Self;}{} +\ccGlue +\ccTypedef{typedef Items::Dart_wrapper::Dart Dart;}{} + +\ccHeading{Complexity} + +The complexity of \ccc{sew} and \ccc{unsew} is in $O(|S|\times |c|)$, $S$ +being the set of darts of the orbit +$\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}$ for the +considered dart, and $c$ the biggest $j$-cell merged or +split during the sew such that $j$-attributes are non void. + +% The complexity of \ccc{topo_sew}, and \ccc{topo_unsew} are in +% $O(|S|\times c)$, $S$ being the set of darts of the orbit +% $\orb{\mb{1},\ldots,\mb{i-2},\mb{i+2},\ldots,\mb{d}}$ for the +% considered dart. + +The complexity of \ccc{set_attribute} is in $O(|c|)$, $c$ being the +$i$-cell containing the considered dart. + +The complexity of \ccc{unmark_all} and \ccc{free_mark} is in $O(1)$ if +all the darts of the combinatorial map have the same mark, and in +$O(|D|)$ otherwise, $D$ being the set of darts of the combinatorial +map. + +Other methods have all a constant time complexity. + +\ccSeeAlso +\ccRefConceptPage{CombinatorialMapItems}\\ +\ccRefConceptPage{Dart}\\ + +\end{ccRefClass} +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +\ccRefPageEnd +% EOF +% +------------------------------------------------------------------------+ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_constructors.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_constructors.tex new file mode 100644 index 00000000000..d28b75db9e9 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_constructors.tex @@ -0,0 +1,107 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Combinatorial_map_constructors.tex +% +------------------------------------------------------------------------+ +% | 04.02.2010 Guillaume Damiand +% | Package: Combinatorial_map +% +------------------------------------------------------------------------+ +\ccRefPageBegin +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{make_edge} +\ccInclude{CGAL/Combinatorial_map_constructors.h}\\ + +\ccFunction{template < class CMap > + typename CMap::Dart_handle make_edge(CMap& cm);} +{Creates an isolated edge (two darts linked by $\beta_2$) and adds it in \ccc{cm}. + Returns a handle on one dart of this edge. + \ccPrecond{\ccc{CMap::dimension}$\geq 2$.} +% \ccCommentHeading{Template parameter}\\ +% \ccc{CMap} must be a model of the \ccc{CombinatorialCMap} concept. +% \ccCommentHeading{Parameters} \\ +% \ccc{cm}: the combinatorial map used. +% \ccCommentHeading{Returns} \\ +% a handle to one dart part of the edge created. +} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::make_combinatorial_polygon}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_tetrahedron}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_hexahedron}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{make_combinatorial_polygon} +\ccInclude{CGAL/Combinatorial_map_constructors.h}\\ + +\ccFunction{template < class CMap > typename CMap::Dart_handle + make_combinatorial_polygon(CMap& cm, unsigned int alg);} +{Creates a combinatorial polygon of length \ccc{alg} (\ccc{alg} darts + linked by $\beta_1$), and adds it in \ccc{cm}. + Returns a handle on one dart of this combinatorial polygon. + \ccPrecond{\ccc{CMap::dimension}$\geq 1$ and \ccc{alg}$>0$.} + % \ccCommentHeading{Template parameter}\\ + % \ccc{CMap} must be a model of the \ccc{CombinatorialCMap} concept. + % \ccCommentHeading{Parameters} \\ + % \ccc{cm}: the combinatorial map used. + % \ccCommentHeading{Returns} \\ + % a handle to a dart which is part of the triangle created. +} +\ccSeeAlso +\ccRefIdfierPage{CGAL::make_edge}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_tetrahedron}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_hexahedron}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{make_combinatorial_tetrahedron} +\ccInclude{CGAL/Combinatorial_map_constructors.h}\\ + +\ccFunction{template < class CMap > + typename CMap::Dart_handle make_combinatorial_tetrahedron(CMap& cm);} +{Creates a combinatorial tetrahedron (four combinatorial triangles linked + together by $\beta_2$), and adds it in \ccc{cm}. + Returns a handle on one dart of this combinatorial tetrahedron. +% \ccCommentHeading{Template parameter}\\ +% \ccc{CMap} must be a model of the \ccc{CombinatorialCMap} concept. +% \ccCommentHeading{Parameters} \\ +% \ccc{cm}: the combinatorial map used. +% \ccCommentHeading{Returns} \\ +% a handle to a dart which is part of the tetrahedron created. + \ccPrecond{\ccc{CMap::dimension}$\geq 2$.} +} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::make_edge}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_polygon}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_hexahedron}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{make_combinatorial_hexahedron} +\ccInclude{CGAL/Combinatorial_map_constructors.h}\\ + +\ccFunction{template < class CMap > + typename CMap::Dart_handle make_combinatorial_hexahedron(CMap& cm);} +{Creates an combinatorial hexahedron (six combinatorial quadrangles linked + together by $\beta_2$), and adds it in \ccc{cm}. + Returns a handle on one dart of this combinatorial hexahedron. +% \ccCommentHeading{Template parameter}\\ +% \ccc{CMap} must be a model of the \ccc{CombinatorialCMap} concept. +% \ccCommentHeading{Parameters} \\ +% \ccc{cm}: the combinatorial map used. +% \ccCommentHeading{Returns} \\ +% a handle to a dart which is part of the hexahedron created. + \ccPrecond{\ccc{CMap::dimension}$\geq 2$.} +} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::make_edge}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_polygon}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_tetrahedron}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- + +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +\ccRefPageEnd +% EOF +% +------------------------------------------------------------------------+ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_min_items.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_min_items.tex new file mode 100644 index 00000000000..7b4ce46e1b7 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_min_items.tex @@ -0,0 +1,63 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Combinatorial_map_min_items.tex +% +------------------------------------------------------------------------+ +% | 04.02.2010 Guillaume Damiand +% | Package: Combinatorial_map +% +------------------------------------------------------------------------+ +\ccRefPageBegin +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + +\begin{ccRefClass}{Combinatorial_map_min_items} +\ccRefLabel{CGAL::Combinatorial_map_min_items} + +\ccInclude{CGAL/Combinatorial_map_min_items.h} + +\ccDefinition + +The class \ccRefName\ is a model of the \ccc{CombinatorialMapItems} +concept. It defines the type of darts which is a +\ccc{CGAL::Dart}. The \ccRefName\ has a +template argument for the dimension of the combinatorial map. +In this class, no attribute is enabled. + +\ccIsModel +\ccRefConceptPage{CombinatorialMapItems} + +\ccExample + +The following example shows the implementation of the +\ccc{CGAL::Combinatorial_map_min_items} class. + +\begin{ccExampleCode} +template +struct Combinatorial_map_min_items +{ + template + struct Dart_wrapper + { + typedef CGAL::Dart Dart; + typedef CGAL::cpp0x::tuple<> Attributes; + }; +}; +\end{ccExampleCode} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::Combinatorial_map}\\ +\ccRefIdfierPage{CGAL::Dart} + +% \ccRefIdfierPage{CGAL::HalfedgeDS_items_2}\\ +% \ccRefIdfierPage{CGAL::Polyhedron_items_3}\\ +% \ccRefConceptPage{HalfedgeDS}\\ +% \ccRefConceptPage{PolyhedronItems_3}\\ +% \ccRefIdfierPage{CGAL::HalfedgeDS_vertex_min_base}\\ +% \ccRefIdfierPage{CGAL::HalfedgeDS_halfedge_min_base}\\ +% \ccRefIdfierPage{CGAL::HalfedgeDS_face_min_base} + +\end{ccRefClass} + +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +\ccRefPageEnd +% EOF +% +------------------------------------------------------------------------+ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_operations.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_operations.tex new file mode 100644 index 00000000000..84f84ca9ac0 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Combinatorial_map_operations.tex @@ -0,0 +1,357 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Combinatorial_map_operations.tex +% +------------------------------------------------------------------------+ +% | 04.02.2010 Guillaume Damiand +% | Package: Combinatorial_map +% +------------------------------------------------------------------------+ +\ccRefPageBegin +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + +%-------------------------------------------------------------------------------- +% \ccFunction{template < class CMap > +% void remove_vertex_2(CMap& cm, typename CMap::Dart_handle dh);} +% { +% Remove a 2D vertex, and merge eventually both incident edges.\\ +% \ccCommentHeading{Parameters} \\ +% \ccc{cm}: the combinatorial map used;\\ +% \ccc{dh}: a dart belonging to the vertex to remove. +% } +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{is_removable} +\ccInclude{CGAL/Combinatorial_map_operations.h}\\ +\ccFunction{template + bool is_removable(const CMap& cm, typename CMap::Dart_const_handle dh);} + {Returns true iff the $i$-cell containing \ccc{dh} can be removed, + i.e. if $i==CMap::dimension$ or if + $i==CMap::dimension-1$ or + if $i}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{remove_cell} +\ccInclude{CGAL/Combinatorial_map_operations.h}\\ + +\ccFunction{template + unsigned int remove_cell(CMap& cm, typename CMap::Dart_handle dh);} +{Removes the $i$-cell containing \ccc{dh}. + Returns the number of darts removed from \ccc{cm}. + \ccPrecond{\ccc{is_removable(cm,dh)}.}\\ + See examples in Figures~\ref{fig-insert-vertex}, \ref{fig-insert-edge} and \ref{fig-insert-face}. \\ +% +% \begin{ccAdvanced} + If $i::type::On_merge}($a_1$,$a_2$) is + called, with $a_1$ the $(i+1)$-attribute associated to \ccc{dh}, + and $a_2$ the $(i+1)$-attribute associated to $\beta_{i+1}(dh)$.\\ + % + If a $j$-cell is disconnected in two $j$-cells during the + operation, and if $j$-attributes are non void, + \ccc{Attribute_type::type::On_split}($a$,$a'$) is called + with $a$ the original $j$-attribute and $a'$ the new + $j$-attribute created due to the disconnection. +% \end{ccAdvanced} +} + % \ccCommentHeading{Template parameter}\\ + % \ccc{Map} must be a model of the \ccc{CombinatorialMap} + % concept. + % \ccCommentHeading{Parameters} \\ + % \ccc{cm}: the combinatorial map used;\\ + % \ccc{dh}: a dart belonging to the edge to remove. + % \ccPrecond{\ccc{cm.can_remove(dh)}} + % \ccCommentHeading{Returns} \\ + % the number of deleted darts. } + +% \def\LargFig{.8\textwidth} +% %\begin{figure} +% \begin{ccTexOnly} +% \begin{center} +% \includegraphics[width=\LargFig]{Combinatorial_map_ref/fig/pdf/insert-vertex} +% \end{center} +% \end{ccTexOnly} +% \begin{ccHtmlOnly} +%
+% +% +%
+% \end{ccHtmlOnly} +% \centerline{Example of \ccc{insert_cell_0_in_cell_1} and \ccc{remove_cell<0>} functions.} +% % \label{fig-exemple-remove_vertex} +% %\end{figure} + +% \def\LargFig{.8\textwidth} +% %\begin{figure} +% \begin{ccTexOnly} +% \begin{center} +% \includegraphics[width=\LargFig]{Combinatorial_map_ref/fig/pdf/insert-edge} +% \end{center} +% \end{ccTexOnly} +% \begin{ccHtmlOnly} +%
+% +% +%
+% \end{ccHtmlOnly} +% \centerline{Example of \ccc{:insert_cell_1_in_cell_2} and +% \ccc{remove_cell<1>} functions.} +% % \label{fig-exemple-remove_edge} +% %\end{figure} + +% \def\LargFig{.8\textwidth} +% %\begin{figure} +% \begin{ccTexOnly} +% \begin{center} +% \includegraphics[width=\LargFig]{Combinatorial_map_ref/fig/pdf/insert-facet} +% \end{center} +% \end{ccTexOnly} +% \begin{ccHtmlOnly} +%
+% +% +%
+% \end{ccHtmlOnly} +% \centerline{Example of \ccc{insert_cell_2_in_cell_3} and +% \ccc{remove_cell<2>} functions.} +% % \label{fig-exemple-remove_facet} +% %\end{figure} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::is_removable}\\ +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_1}\\ +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_dangling_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_2_in_cell_3}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{is_insertable_cell_1_in_cell_2} +\ccInclude{CGAL/Combinatorial_map_operations.h}\\ + +\ccFunction{template < class CMap > + bool is_insertable_cell_1_in_cell_2(const CMap & cm, + typename CMap::Dart_const_handle dh1, + typename CMap::Dart_const_handle dh2);} +{Returns true iff it is possible to insert a 1-cell in \ccc{cm} + between \ccc{dh1} and \ccc{dh2}, + i.e. if $dh1 \neq dh2$ and $dh1 \in <\beta_1>(dh2)$. + \ccPrecond{\ccc{CMap::dimension}$\geq 2$, + \ccc{*dh1}$\in$\ccc{cm.darts()}, and \ccc{*dh2}$\in$\ccc{cm.darts()}.} +} +% \ccCommentHeading{Template parameter}\\ +% \ccc{Map} must be a model of the \ccc{CombinatorialMap} concept. +% \ccCommentHeading{Parameters} \\ +% \ccc{cm}: the combinatorial map used;\\ +% \ccc{dh1, dh2}: the two given darts. +% \ccCommentHeading{Returns} \\ +% true iff it is possible to insert an edge between dh1 and dh2. + +\ccSeeAlso +\ccRefIdfierPage{CGAL::insert_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::is_insertable_cell_2_in_cell_3}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{is_insertable_cell_2_in_cell_3} +\ccInclude{CGAL/Combinatorial_map_operations.h}\\ + +\ccFunction{template + bool is_insertable_cell_2_in_cell_3(const CMap & cm, + InputIterator afirst, InputIterator alast);} +{Returns true iff it is possible to insert a 2-cell in \ccc{cm} along the path + of darts given by the range \ccc{[afirst,alast)]}. The 2-cell can be inserted + iff each couple of consecutive darts of the path $a_1$ and $a_2$ belong to the + same vertex and the same volume, and if the path is closed. + \ccPrecond{\ccc{CMap::dimension}$\geq 3$.} + % \ccCommentHeading{Template parameter}\\ + % \ccc{Map} must be a model of the \ccc{CombinatorialMap} concept. + % \ccCommentHeading{Parameters} \\ + % \ccc{cm}: the combinatorial map used;\\ + % \ccc{afirst}: an iterator on the beginining of the path of darts. + % \ccc{alast}: an iterator to the end of the path of darts. + % \ccCommentHeading{Returns} \\ + % true iff it is possible to insert a facet along apath. } +} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::insert_cell_2_in_cell_3}\\ +\ccRefIdfierPage{CGAL::is_insertable_cell_1_in_cell_2}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{insert_cell_0_in_cell_1} +\ccInclude{CGAL/Combinatorial_map_operations.h}\\ + +\ccFunction{template < class CMap > + typename CMap::Dart_handle insert_cell_0_in_cell_1(CMap& cm, + typename CMap::Dart_handle dh);} +{Inserts a 0-cell in the 1-cell containing \ccc{dh}. + Returns a handle on one dart of this cell. + \ccPrecond{\ccc{CMap::dimension}$\geq 1$ and \ccc{*dh}$\in$\ccc{cm.darts()}.}\\ + See example in Figure~\ref{fig-insert-vertex}.\\ +% \begin{ccAdvanced} + If 1-attributes are non void, + \ccc{Attribute_type<1>::type::On_split}($a$,$a'$) is called, with $a$ the original 1-attribute associated + with $dh$ and $a'$ the new 1-attribute created during the operation. +% \end{ccAdvanced} +} +% \ccCommentHeading{Template parameter}\\ +% \ccc{CMap} must be a model of the \ccc{CombinatorialMap} concept. +% \ccCommentHeading{Parameters} \\ +% \ccc{cm}: the combinatorial map used;\\ +% \ccc{dh}: a dart belonging to the edge. +% \ccPrecond{\ccc{can_insert_vertex(cm,dh)}} +% \ccCommentHeading{Returns} \\ +% a dart of the new vertex. +% } + +\ccSeeAlso +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_dangling_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_2_in_cell_3}\\ +\ccRefIdfierPage{CGAL::remove_cell}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{insert_cell_0_in_cell_2} +\ccInclude{CGAL/Combinatorial_map_operations.h}\\ + +\ccFunction{template + typename CMap::Dart_handle insert_cell_0_in_cell_2(CMap & cm, + typename CMap::Dart_handle dh);} +{Inserts a 0-cell in the 2-cell containing \ccc{dh}. + The 2-cell is split in triangles, one for each initial edge of the facet. + Returns a handle on one dart belonging to the new 0-cell. + \ccPrecond{\ccc{CMap::dimension}$\geq 2$ and \ccc{*dh}$\in$\ccc{cm.darts()}.}\\ + See example in Figure~\ref{fig-triangulate}.\\ +% \begin{ccAdvanced} + If 2-attributes are non void, + \ccc{Attribute_type<2>::type::On_split}($a$,$a'$) is called, with $a$ the original 2-attribute associated + with $dh$ and $a'$ each new 2-attribute created during the operation. +% \end{ccAdvanced} +% \ccCommentHeading{Template parameter}\\ +% \ccc{CMap} must be a model of the \ccc{CombinatorialMap} concept. +% Operation defined here is purely combinatorial, there is no geometry modification. +% \ccCommentHeading{Parameters} \\ +% \ccc{cm}: the combinatorial map used;\\ +% \ccc{dh}: a dart belonging to the facet to triangulate. +% \ccCommentHeading{Returns} \\ +% a dart created during the triangulation, and incident to the new vertex. +} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_dangling_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_2_in_cell_3}\\ +\ccRefIdfierPage{CGAL::remove_cell}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{insert_cell_1_in_cell_2} +\ccInclude{CGAL/Combinatorial_map_operations.h}\\ + +\ccFunction{template < class CMap > + typename CMap::Dart_handle insert_cell_1_in_cell_2(CMap& cm, + typename CMap::Dart_handle dh1,typename CMap::Dart_handle dh2);} +{Inserts a 1-cell in the 2-cell containing \ccc{dh1} and \ccc{dh2}. + Returns a handle on one dart of this cell. + \ccPrecond{\ccc{is_insertable_cell_1_in_cell_2(cm,dh1,dh2)}.}\\ + See example in Figure~\ref{fig-insert-edge}.\\ +% \begin{ccAdvanced} + If 2-attributes are non void, + \ccc{Attribute_type<2>::type::On_split}($a$,$a'$) is called, with $a$ the original 2-attribute associated + with $dh$ and $a'$ the new 2-attribute created during the operation. +% \end{ccAdvanced} +} +% \ccCommentHeading{Template parameter}\\ +% \ccc{CMap} must be a model of the \ccc{CombinatorialMap} concept. +% \ccCommentHeading{Parameters} \\ +% \ccc{cm}: the combinatorial map used;\\ +% \ccc{dh1}: a first dart belonging to the facet. +% \ccc{dh2}: a second dart belonging to the facet. +% \ccPrecond{\ccc{can_insert_edge(cm,dh1,dh2)}} +% \ccCommentHeading{Returns} \\ +% a dart of the new edge.} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::is_insertable_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_1}\\ +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_dangling_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_2_in_cell_3}\\ +\ccRefIdfierPage{CGAL::remove_cell}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{insert_dangling_cell_1_in_cell_2} +\ccInclude{CGAL/Combinatorial_map_operations.h}\\ + +\ccFunction{template < class CMap > + typename CMap::Dart_handle insert_dangling_cell_1_in_cell_2(CMap& cm, + typename CMap::Dart_handle dh);} +{Inserts a 1-cell in a the 2-cell containing \ccc{dh}, the 1-cell +being attached only by one of its extremity to the 0-cell containing \ccc{dh}. + Returns a handle on one dart belonging to the new 0-cell. + \ccPrecond{\ccc{CMap::dimension}$\geq 2$ and \ccc{*dh}$\in$\ccc{cm.darts()}.}\\ + See example in Figure~\ref{fig-insert-edge}. +} +% \ccCommentHeading{Template parameter}\\ +% \ccc{CMap} must be a model of the \ccc{CombinatorialMap} concept. +% \ccCommentHeading{Parameters} \\ +% \ccc{cm}: the combinatorial map used;\\ +% \ccc{dh}: a dart belonging to the facet. +% \ccCommentHeading{Returns} \\ +% a dart of the new edge and incident to the new vertex.} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_1}\\ +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_2_in_cell_3}\\ +\ccRefIdfierPage{CGAL::remove_cell}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- +\begin{ccRefFunction}{insert_cell_2_in_cell_3} +\ccInclude{CGAL/Combinatorial_map_operations.h}\\ + +\ccFunction{template + typename CMap::Dart_handle insert_cell_2_in_cell_3(CMap & cm, + InputIterator afirst, InputIterator alast);} +{Inserts a 2-cell along the path of 1-cell incident to darts given + by the range \ccc{[afirst,alast)]} + Returns a handle on one dart of this cell. + \ccPrecond{\ccc{is_insertable_cell_2_in_cell_3(cm,afirst,alast)}.}\\ + See example in Figure~\ref{fig-insert-face}.\\ +% \begin{ccAdvanced} + If 3-attributes are non void, + \ccc{Attribute_type<3>::type::On_split}($a$,$a'$) is called, with $a$ the original 3-attribute associated + with $dh$ and $a'$ the new 3-attribute created during the operation. +% \end{ccAdvanced} +} +% \ccCommentHeading{Template parameter}\\ +% \ccc{CMap} must be a model of the \ccc{CombinatorialMap} concept. +% \ccCommentHeading{Parameters} \\ +% \ccc{cm}: the combinatorial map used;\\ +% \ccc{afirst}: an iterator on the beginining of the path of darts. +% \ccc{alast}: an iterator to the end of the path of darts. +% \ccPrecond{\ccc{can_insert_facet(cm,afirst,alast)}} +% \ccCommentHeading{Returns} \\ +% a dart of the new facet.} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::is_insertable_cell_2_in_cell_3}\\ +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_1}\\ +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_dangling_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::remove_cell}\\ +\end{ccRefFunction} +%-------------------------------------------------------------------------------- + +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +\ccRefPageEnd +% EOF +% +------------------------------------------------------------------------+ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/Dart.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Dart.tex new file mode 100644 index 00000000000..6930cf14888 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Dart.tex @@ -0,0 +1,147 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Dart.tex +% +------------------------------------------------------------------------+ +% | 04.02.2010 Guillaume Damiand +% | Package: Combinatorial_map +% +------------------------------------------------------------------------+ +\ccRefPageBegin +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ +\begin{ccRefConcept}{Dart} +%\ccRefLabel{CGAL::Dart} + +\ccDefinition + +The concept \ccRefName\ defines a $d$-dimensional dart. A dart mainly +stores handles to the darts linked with itself by $\beta_i$, $\forall +i$, $0 \leq i \leq d$. Moreover, it stores also handles to each +non void attribute associated with itself. + +% \ccParameters +% \ccc{d} is the dimension of the combinatorial map.\\ +% \ccc{CMap} must be a model of the \ccc{CombinatorialMap} concept. + +\ccCreation +\ccCreationVariable{d0} +A dart \ccc{d0} is never constructed directly, but always created +within a combinatorial map \ccc{cm} by using the method +\ccc{cm.create_dart();} A new dart is initialized to be $i$-free, +$\forall i$: $0 \leq i \leq dimension$, and having all its attribute +handles initialized to NULL, for each non void attribute. + +\ccConstants +\ccVariable{static unsigned int dimension;}{The dimension of \ccc{d0}.} + +\ccTypes +\ccTwo{Dart:: Dart_const_handle_}{}{} +% +\ccNestedType{Dart_handle}{Dart handle type.} +\ccGlue +\ccNestedType{Dart_const_handle}{Dart const handle type.} + +\ccNestedType{template Attribute_handle::type} + {Handle to $i$-attributes, with $0 \leq i \leq dimension$.} +\ccGlue +\ccNestedType{template Attribute_const_handle::type} + {Const handle to $i$-attributes, with $0 \leq i \leq dimension$.} + +\ccHeading{Access Member Functions} +\ccThree{Dart_const_handle}{beta(unsigned int i) const}{} +% +\ccMethod{Dart_handle beta(unsigned int i);} + {Returns $\beta_i$(\ccc{d0}). + \ccPrecond{$0 \leq i \leq dimension$.}} +\ccGlue +\ccMethod{Dart_const_handle beta(unsigned int i) const;} + {Returns $\beta_i$(\ccc{d0}) when \ccc{d0} is const. + \ccPrecond{$0 \leq i \leq dimension$.}} + +\ccMethod{Dart_handle beta_inv(unsigned int i);} + {Returns $\beta_i^{-1}$(\ccc{d0}). + \ccPrecond{$0 \leq i \leq dimension$.}} +\ccGlue +\ccMethod{Dart_const_handle beta_inv(unsigned int i) const;} + {Returns $\beta_i^{-1}$(\ccc{d0}) when \ccc{d0} is const. + \ccPrecond{$0 \leq i \leq dimension$.}} + +\ccMethod{bool is_free(unsigned int i) const;} + {Returns true iff \ccc{d0} is $i$-free. + \ccPrecond{$0 \leq i \leq dimension$.}} + +\ccMethod{int highest_nonfree_dimension() const;} + {Returns the highest dimension $i$ such that \ccc{d0} is not $i$-free. + -1 if \ccc{d0} is free for any dimension.} + +\ccMethod{Dart_handle opposite();} + {Returns a handle to a dart belonging to the same edge + than \ccc{d0}, and not to the same vertex. + NULL if such a dart does not exist.} +\ccGlue +\ccMethod{Dart_const_handle opposite() const;} + {Returns a handle to a dart belonging to the same edge + than \ccc{d0}, and not to the same vertex, when \ccc{d0} is const. + NULL if such a dart does not exist.} + +\ccMethod{Dart_handle other_extremity();} + {Returns a handle to a dart belonging to the other vertex of + the edge containing \ccc{d0} (but contrary to \ccc{opposite()} not + necessarily to the same edge). NULL if such a dart does not exist.} +\ccGlue +\ccMethod{Dart_const_handle other_extremity() const;} + {Returns a \ccc{Dart_const_handle} to a dart belonging to the other vertex of + the edge containing \ccc{d0}, when \ccc{d0} is const (but contrary to + \ccc{opposite()} not necessarily to the same edge). + NULL if such a dart does not exist.} + +% \ccMethod{template static bool are_attributes_enabled();} +% {Returns true iff $i$-attributes are enabled. +% \ccPrecond{$0 \leq i \leq dimension$.}} + +\ccMethod{template Attribute_handle::type attribute();} + {Returns the $i$-attribute associated to \ccc{d0}. + \ccPrecond{$0 \leq i \leq dimension$, and $i$-attributes are non void.}} +\ccGlue +\ccMethod{template + Attribute_const_handle::type attribute() const;} + {Returns the $i$-attribute associated to \ccc{d0}, + when \ccc{d0} is const. + \ccPrecond{$0 \leq i \leq dimension$, and $i$-attributes are non void.}} + +% \ccMethod{Dart_handle beta(unsigned int ai, unsigned int aj);} +% {return the neighbor of this dart for $\mb{ai}$ then $\mb{aj}$.} +% \ccMethod{Dart_consthandle beta(unsigned int ai, unsigned int aj) const;} +% {return the neighbor of this dart for $\mb{ai}$ then $\mb{aj}$.} + +% \ccMethod{Dart_handle beta(unsigned int ai, unsigned int aj, unsigned int ak);} +% {return the neighbor of this dart for $\mb{ai}$ then $\mb{aj}$ +% then $\mb{ak}$.} +% \ccMethod{Dart_const_handle beta(unsigned int ai, unsigned int aj, unsigned int ak) const;} +% {return the neighbor of this dart for $\mb{ai}$ then $\mb{aj}$ +% then $\mb{ak}$.} + +% \ccMethod{Dart_handle beta(unsigned int ai, unsigned int aj, unsigned int ak, unsigned int al);} +% {return the neighbor of this dart for $\mb{ai}$ then $\mb{aj}$ +% then $\mb{ak}$ then $\mb{al}$.} +% \ccMethod{Dart_const_handle beta(unsigned int ai, unsigned int aj, unsigned int ak, unsigned int al) const;} +% {return the neighbor of this dart for $\mb{ai}$ then $\mb{aj}$ +% then $\mb{ak}$ then $\mb{al}$.} + +% +-----------------------------------+ +% \ccOperations + +% \ccMethod{void link_beta(Dart_handle dh, unsigned int adimension);} +% {link this dart to dh for the given dimension (only in one direction).} + +% \ccMethod{void unlink_beta(unsigned int adimension);} +% {remove the relation between this dart and its neighbor for +% the given dimension (only in one direction).} + +\ccHasModels +\ccRefIdfierPage{CGAL::Dart} + +\end{ccRefConcept} +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +\ccRefPageEnd +% EOF +% +------------------------------------------------------------------------+ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/Dart_base.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Dart_base.tex new file mode 100644 index 00000000000..ec3139bc84a --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/Dart_base.tex @@ -0,0 +1,63 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Dart.tex +% +------------------------------------------------------------------------+ +% | 04.02.2010 Guillaume Damiand +% | Package: Combinatorial_map +% +------------------------------------------------------------------------+ +\ccRefPageBegin +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ +\begin{ccRefClass}{Dart} + +\ccInclude{CGAL/Dart.h} + +\ccDefinition + +The class \ccRefName\ represents a $d$D dart. + +$\beta_i$ pointers are coded in a array of $d+1$ \ccc{Dart_handle} +(because we describe also the $\beta_0$ link). Attributes are +associated to each dart by \ccc{Attribute_handle}, one for each +non void $i$-attribute. + +\ccIsModel +\ccRefConceptPage{Dart} + +\ccParameters +\ccc{d} an integer for the dimension of the dart.\\ +\ccc{CMap} must be a model of the \ccc{CombinatorialMap} concept. + +% A dart \ccc{a} is never constructed directly, but always created withing a +% combinatorial map \ccc{cm} by using the method \ccc{cm.create_dart();} + +\ccTypes +\ccThree{typedef CMap::Attribute_const_handle::type}{}{} +\ccTypedef{typedef CMap::Dart_handle Dart_handle;}{} +\ccGlue +\ccTypedef{typedef CMap::Dart_const_handle Dart_const_handle;}{} + +\ccTypedef{typedef CMap::Attribute_handle::type Attribute_handle::type;}{} +\ccGlue +\ccTypedef{typedef CMap::Attribute_const_handle::type Attribute_const_handle::type;}{} + +\ccHeading{Complexity} + +Each $\beta_i$ link is initialized to \ccc{CMap::null_dart_handle}, and each +attribute handle of non void $i$-attribute is initialized to NULL +at the creation of the dart, thus the complexity of the creation is in +$O(d+1)$. + +The complexity of \ccc{opposite} and \ccc{other_extremity} methods is in +$O(d+1)$. + +Other methods have all a constant time complexity. + +\ccSeeAlso +\ccRefConceptPage{CombinatorialMap} + +\end{ccRefClass} +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +\ccRefPageEnd +% EOF +% +------------------------------------------------------------------------+ diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/intro.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/intro.tex new file mode 100644 index 00000000000..283d45b6f84 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/intro.tex @@ -0,0 +1,84 @@ +\ccRefChapter{Combinatorial map} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Classified Reference Pages} + +\subsection{Concepts} + +\ccRefConceptPage{CombinatorialMap}\\ +\ccRefConceptPage{Dart}\\ +%\ccRefConceptPage{CGAL::CombinatorialMapWithPoints} +\ccRefConceptPage{CellAttribute}\\ +%\ccRefConceptPage{CGAL::CellAttributeWithPoint} +%\ccRefConceptPage{CGAL::AttributeFunctor} +\ccRefConceptPage{CombinatorialMapItems} +%\ccRefConceptPage{CGAL::CombinatorialMapWithPointsItems} +%\ccRefConceptPage{CGAL::CombinatorialMapWithPointsTraits} + +\subsection{Classes} +\ccRefIdfierPage{CGAL::Combinatorial_map}\\ +\ccRefIdfierPage{CGAL::Dart}\\ +%\ccRefIdfierPage{CGAL::Combinatorial_map_with_points} +\ccRefIdfierPage{CGAL::Cell_attribute}\\ +%\ccRefIdfierPage{CGAL::Cell_attribute_with_info} +%\ccRefIdfierPage{CGAL::Cell_attribute_with_point} +%\ccRefIdfierPage{CGAL::Cell_attribute_with_point_and_info} +\ccRefIdfierPage{CGAL::Combinatorial_map_min_items} +%\ccRefIdfierPage{CGAL::Combinatorial_map_with_points_min_items} +%\ccRefIdfierPage{CGAL::Combinatorial_map_with_points_cartesian_traits} +%\ccRefIdfierPage{CGAL::Combinatorial_map_with_points_epik_traits} +%\ccRefIdfierPage{CGAL::Void_functor} +%\ccRefIdfierPage{CGAL::Disabled} + +\subsection{Global Functions} +\subsubsection{Constructions for Combinatorial maps} +\ccRefIdfierPage{CGAL::make_edge}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_polygon}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_tetrahedron}\\ +\ccRefIdfierPage{CGAL::make_combinatorial_hexahedron} + +% \subsubsection{Constructions for Combinatorial maps with Points} +% \ccRefIdfierPage{CGAL::make_segment}\\ +% \ccRefIdfierPage{CGAL::make_triangle}\\ +% \ccRefIdfierPage{CGAL::make_quadrilateral}\\ +% \ccRefIdfierPage{CGAL::make_rectangle}\\ +% \ccRefIdfierPage{CGAL::make_square}\\ +% \ccRefIdfierPage{CGAL::make_tetrahedron}\\ +% \ccRefIdfierPage{CGAL::make_hexahedron}\\ +% \ccRefIdfierPage{CGAL::make_cuboid}\\ +% \ccRefIdfierPage{CGAL::make_cube}\\ +% \ccRefIdfierPage{CGAL::import_from_plane_graph}\\ +% \ccRefIdfierPage{CGAL::import_from_triangulation_3}\\ +% \ccRefIdfierPage{CGAL::import_from_polyhedron} + + +\subsubsection{Operations for Combinatorial maps} +\ccRefIdfierPage{CGAL::is_removable}\\ +\ccRefIdfierPage{CGAL::remove_cell}\\ +\ccRefIdfierPage{CGAL::is_insertable_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::is_insertable_cell_2_in_cell_3}\\ +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_1}\\ +\ccRefIdfierPage{CGAL::insert_cell_0_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_dangling_cell_1_in_cell_2}\\ +\ccRefIdfierPage{CGAL::insert_cell_2_in_cell_3} +%\ccRefIdfierPage{CGAL::display_characteristics} + +% \ccRefIdfierPage{CGAL::create_facet_vertex}\\ +% \ccRefIdfierPage{CGAL::can_insert_vertex}\\ +% \ccRefIdfierPage{CGAL::can_insert_edge}\\ +% \ccRefIdfierPage{CGAL::can_insert_facet}\\ +% \ccRefIdfierPage{CGAL::insert_vertex}\\ +% \ccRefIdfierPage{CGAL::insert_edge}\\ +% \ccRefIdfierPage{CGAL::insert_dangling_edge}\\ +% \ccRefIdfierPage{CGAL::insert_facet}\\ + +% \subsubsection{Operations for Combinatorial maps with Points} +% \ccRefIdfierPage{CGAL::barycenter}\\ +% \ccRefIdfierPage{CGAL::compute_facet_normal}\\ +% \ccRefIdfierPage{CGAL::compute_vertex_normal}\\ +% \ccRefIdfierPage{CGAL::create_facet_center_vertex}\\ +% \ccRefIdfierPage{CGAL::insert_vertex}\\ +% \ccRefIdfierPage{CGAL::insert_dangling_edge} + + diff --git a/Combinatorial_map/doc_tex/Combinatorial_map_ref/main.tex b/Combinatorial_map/doc_tex/Combinatorial_map_ref/main.tex new file mode 100644 index 00000000000..1b4935684d8 --- /dev/null +++ b/Combinatorial_map/doc_tex/Combinatorial_map_ref/main.tex @@ -0,0 +1,51 @@ +% +------------------------------------------------------------------------+ +% | CBP Reference Manual: main.tex +% +------------------------------------------------------------------------+ +% | Automatically generated driver file for the reference manual chapter +% | of this package. Do not edit manually, you may loose your changes. +% +------------------------------------------------------------------------+ +\def\ccTagRmTrailingConst{\ccFalse} + +\input{Combinatorial_map_ref/intro.tex} + +% First: concepts +\input{Combinatorial_map_ref/CombinatorialMap.tex} +%\input{Combinatorial_map_ref/CombinatorialMapWithPoints.tex} + +\input{Combinatorial_map_ref/Dart.tex} + +\input{Combinatorial_map_ref/CellAttribute.tex} +%\input{Combinatorial_map_ref/CellAttributeWithPoint.tex} +%\input{Combinatorial_map_ref/AttributeFunctor.tex} + +\input{Combinatorial_map_ref/CombinatorialMapItems.tex} +%\input{Combinatorial_map_ref/CombinatorialMapWithPointsItems.tex} +%\input{Combinatorial_map_ref/CombinatorialMapWithPointsTraits.tex} + +% Second: classes +\input{Combinatorial_map_ref/Combinatorial_map.tex} +%\input{Combinatorial_map_ref/Combinatorial_map_with_points.tex} + +\input{Combinatorial_map_ref/Dart_base.tex} + +\input{Combinatorial_map_ref/Cell_attribute.tex} +%\input{Combinatorial_map_ref/Cell_attribute_with_info.tex} +%\input{Combinatorial_map_ref/Cell_attribute_with_point.tex} +%\input{Combinatorial_map_ref/Cell_attribute_with_point_and_info.tex} + +\input{Combinatorial_map_ref/Combinatorial_map_min_items.tex} +%\input{Combinatorial_map_ref/Combinatorial_map_with_points_min_items.tex} +%\input{Combinatorial_map_ref/Combinatorial_map_with_points_cartesian_traits.tex} +%\input{Combinatorial_map_ref/Combinatorial_map_with_points_epik_traits.tex} + +%\input{Combinatorial_map_ref/Disabled.tex} +%\input{Combinatorial_map_ref/Void_functor.tex} + +% Third: global functions. +\input{Combinatorial_map_ref/Combinatorial_map_constructors.tex} +%\input{Combinatorial_map_ref/Combinatorial_map_with_points_constructors.tex} + +\input{Combinatorial_map_ref/Combinatorial_map_operations.tex} +%\input{Combinatorial_map_ref/Combinatorial_map_with_points_operations.tex} + +%% EOF diff --git a/Combinatorial_map/doc_tex/wrapper.tex b/Combinatorial_map/doc_tex/wrapper.tex new file mode 100644 index 00000000000..a6d3d19af82 --- /dev/null +++ b/Combinatorial_map/doc_tex/wrapper.tex @@ -0,0 +1,52 @@ + +\documentclass{book} +\usepackage{Manual/cgal_manual} + +\usepackage{graphicx} +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{subfigure} +\usepackage{latexsym} +\usepackage{color} +\usepackage{dcolumn} + + +%%%%%%%%%%% +\graphicspath{ +% {Combinatorial_map/fig/eps/} + {Combinatorial_map/} + {Combinatorial_map/fig/pdf/} + {Combinatorial_map_ref/fig/pdf/} +} + +\gdef\lciManualTitle{Combinatorial\_map}% + +\makeindex + +% Make the table of contents use two columns +\lcHtml{\lcTwoColumnToc} + +\begin{document} + +\cgaltitlepage{Combinatorial\_map} + +\cleardoublepage +\pagenumbering{roman} +\setcounter{page}{1} +\ifthenelse{\boolean{useminitoc}}{\lcTex{\dominitoc}}{} +\tableofcontents +\cleardoublepage +\pagenumbering{arabic} +\setcounter{page}{1} + +\cgalchapters{ +% \entryleftright{\part{User Manual}\input{Combinatorial_map/main.tex}} +% {\part{Reference Manual}\input{Combinatorial_map_ref/main.tex}} + \packageleftright{Combinatorial_map}{Combinatorial_map_ref} +} +\bibliographystyle{alpha} +\bibliography{Manual/cgal_manual,Manual/geom,Combinatorial_map} + +\printindex + +\end{document} \ No newline at end of file diff --git a/Combinatorial_map/dont_submit b/Combinatorial_map/dont_submit new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Combinatorial_map/examples/Combinatorial_map/CMakeLists.txt b/Combinatorial_map/examples/Combinatorial_map/CMakeLists.txt new file mode 100644 index 00000000000..22ccc13909c --- /dev/null +++ b/Combinatorial_map/examples/Combinatorial_map/CMakeLists.txt @@ -0,0 +1,43 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + +# cmake ../ -DCMAKE_BUILD_TYPE=Debug +# ou +# cmake ../ -DCMAKE_BUILD_TYPE=Release + +project( Combinatorial_map_examples ) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.4.5) + +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) + +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -w -Wall -pedantic") # -Wextra") + +if ( COMMAND cmake_policy ) + cmake_policy( SET CMP0003 NEW ) +endif() + +# For the problem with valgrind +# add_definition(-DCGAL_DISABLE_ROUNDING_MATH_CHECK) + +find_package(CGAL QUIET COMPONENTS Core ) + +if ( CGAL_FOUND ) + + include( ${CGAL_USE_FILE} ) + + include( CGAL_CreateSingleSourceCGALProgram ) + include_directories(BEFORE ../../include) + + create_single_source_cgal_program( "map_3_simple_example.cpp" ) + create_single_source_cgal_program( "map_4_simple_example.cpp" ) + create_single_source_cgal_program( "map_3_with_colored_facets.cpp" ) + create_single_source_cgal_program( "map_3_operations.cpp" ) + create_single_source_cgal_program( "map_3_marks.cpp" ) +else() + + message(STATUS "This program requires the CGAL library, and will not be compiled.") + +endif() + diff --git a/Combinatorial_map/examples/Combinatorial_map/map_3_marks.cpp b/Combinatorial_map/examples/Combinatorial_map/map_3_marks.cpp new file mode 100644 index 00000000000..e61136f6d46 --- /dev/null +++ b/Combinatorial_map/examples/Combinatorial_map/map_3_marks.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Combinatorial_map<3> CMap_3; +typedef CMap_3::Dart_handle Dart_handle; + +int main() +{ + CMap_3 cm; + + // Reserve a mark + int mark = cm.get_new_mark(); + if ( mark==-1 ) + { + std::cerr<<"No more free mark, exit."<(dh1, dh2); + + // Mark the darts belonging to the first tetrahedron. + for (CMap_3::Dart_of_cell_range<3>::iterator + it(cm.darts_of_cell<3>(dh1).begin()), + itend(cm.darts_of_cell<3>(dh1).end()); it!=itend; ++it) + cm.mark(it, mark); + + // Remove the common 2-cell between the two cubes: + // the two tetrahedra are merged. + CGAL::remove_cell(cm, dh1); + + // Thanks to the mark, we know which darts come from the first tetrahedron. + unsigned int res=0; + for (CMap_3::Dart_range::iterator it(cm.darts().begin()), + itend(cm.darts().end()); it!=itend; ++it) + { + if ( cm.is_marked(it, mark) ) + ++res; + } + + std::cout<<"Number of darts from the first tetrahedron: "< +#include +#include +#include +#include + +typedef CGAL::Combinatorial_map<3> CMap_3; +typedef CMap_3::Dart_handle Dart_handle; + +int main() +{ + CMap_3 cm; + + // Create one . + Dart_handle d1 = CGAL::make_combinatorial_hexahedron(cm); + + // Add two edges along two opposite facets. + CGAL::insert_cell_1_in_cell_2(cm,d1->beta(1),d1->beta(0)); + CGAL_assertion( cm.is_valid() ); + + Dart_handle d2=d1->beta(2)->beta(1)->beta(1)->beta(2); + CGAL::insert_cell_1_in_cell_2(cm,d2,d2->beta(1)->beta(1)); + CGAL_assertion( cm.is_valid() ); + + // Insert a facet along these two new edges plus two initial edges of the cube. + std::vector path; + path.push_back(d1->beta(1)); + path.push_back(d1->beta(0)->beta(2)->beta(1)); + path.push_back(d2->beta(0)); + path.push_back(d2->beta(2)->beta(1)); + + Dart_handle d3=CGAL::insert_cell_2_in_cell_3(cm,path.begin(),path.end()); + CGAL_assertion( cm.is_valid() ); + + // Display the m characteristics. + cm.display_characteristics(std::cout) << ", valid=" << + cm.is_valid() << std::endl; + + // We use the removal operations to get back to the initial cube. + CGAL::remove_cell(cm,d3); + CGAL_assertion( cm.is_valid() ); + + CGAL::remove_cell(cm,d1->beta(1)); + CGAL_assertion( cm.is_valid() ); + + CGAL::remove_cell(cm,d2->beta(0)); + CGAL_assertion( cm.is_valid() ); + + // Display the m characteristics. + cm.display_characteristics(std::cout) << ", valid=" + << cm.is_valid() << std::endl; + + return EXIT_SUCCESS; +} + diff --git a/Combinatorial_map/examples/Combinatorial_map/map_3_simple_example.cpp b/Combinatorial_map/examples/Combinatorial_map/map_3_simple_example.cpp new file mode 100644 index 00000000000..007a79a7679 --- /dev/null +++ b/Combinatorial_map/examples/Combinatorial_map/map_3_simple_example.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +typedef CGAL::Combinatorial_map<3> CMap_3; +typedef CMap_3::Dart_const_handle Dart_const_handle; + + int main() + { + CMap_3 cm; + + // Create two tetrahedra. + Dart_const_handle dh1 = CGAL::make_combinatorial_tetrahedron(cm); + Dart_const_handle dh2 = CGAL::make_combinatorial_tetrahedron(cm); + + // Display the combinatorial map characteristics. + cm.display_characteristics(std::cout); + std::cout<<", valid="< in 3D is equivalent to + // CMap_3::Dart_of_cell_range<3>. + for (CMap_3::Dart_of_orbit_range<1,2>::const_iterator + it(cm.darts_of_orbit<1,2>(dh1).begin()), + itend(cm.darts_of_orbit<1,2>(dh1).end()); it!=itend; ++it) + ++res; + + std::cout<<"Number of darts of the first tetrahedron: " + <::const_iterator + it(cm.darts_of_orbit<1>(dh2).begin()), + itend(cm.darts_of_orbit<1>(dh1).end()); it!=itend; ++it) + ++res; + + std::cout<<"Number of darts of the facet containing dh2: " + < +#include +#include +#include +#include +#include +#include + +struct Sum_functor +{ + template + void operator()(Cell_attribute& ca1,Cell_attribute& ca2) + { ca1.info()=ca1.info()+ca2.info(); } +}; +struct Divide_by_two_functor +{ + template + void operator()(Cell_attribute& ca1,Cell_attribute& ca2) + { + ca1.info()=(ca1.info()/2); + ca2.info()=(ca1.info()); + } +}; + +struct Myitem +{ + template + struct Dart_wrapper + { + typedef CGAL::Dart<3, CMap> Dart; + typedef CGAL::Cell_attribute + Facet_attribute; + typedef CGAL::cpp0x::tuple Attributes; + }; +}; + +typedef CGAL::Combinatorial_map<3,Myitem> CMap_3; +typedef CMap_3::Dart_handle Dart_handle; + +int main() +{ + CMap_3 cm; + + // Create 2 cubes. + Dart_handle dh1 = make_combinatorial_hexahedron(cm); + Dart_handle dh2 = make_combinatorial_hexahedron(cm); + + // 1) Create all 2-attributes and associated them to darts. + for (CMap_3::Dart_range::iterator + it=cm.darts().begin(), itend=cm.darts().end(); + it!=itend; ++it) + { + if ( it->attribute<2>()==NULL ) + cm.set_attribute<2>(it, cm.create_attribute<2>()); + } + + // 2) Set the color of all facets of the first cube to 1 + for (CMap_3::One_dart_per_incident_cell_range<2, 3>::iterator + it=cm.one_dart_per_incident_cell<2,3>(dh1).begin(), + itend=cm.one_dart_per_incident_cell<2,3>(dh1).end(); it!=itend; ++it) + { it->attribute<2>()->info()=7; } + + // 3) Set the color of all facets of the second cube to 19 + for (CMap_3::One_dart_per_incident_cell_range<2, 3>::iterator it= + cm.one_dart_per_incident_cell<2,3>(dh2).begin(), + itend=cm.one_dart_per_incident_cell<2,3>(dh2).end(); it!=itend; ++it) + { it->attribute<2>()->info()=13; } + + // 4) 3-Sew the two cubes along one facet + cm.sew<3>(dh1->beta(1)->beta(1)->beta(2), dh2->beta(2)); + + // 5) Display all the values of 2-attributes + for (CMap_3::Attribute_range<2>::type::iterator + it=cm.attributes<2>().begin(), itend=cm.attributes<2>().end(); + it!=itend; ++it) + { + std::cout<info()<<"; "; + } + std::cout<beta(2)); + + // 7) Display all the values of 2-attributes + for (CMap_3::Attribute_range<2>::type::iterator + it=cm.attributes<2>().begin(), itend=cm.attributes<2>().end(); + it!=itend; ++it) + { + std::cout<info()<<"; "; + } + std::cout<, + class Alloc_=CGAL_ALLOCATOR(int) > + class Combinatorial_map_base + { + template + friend struct internal::sew_functor; + + template + friend struct internal::unsew_functor; + + template + friend struct Remove_cell_functor; + + template + friend typename Map::Dart_handle + insert_cell_0_in_cell_1(Map& amap, typename Map::Dart_handle adart); + + template + friend typename CMap::Dart_handle + insert_cell_1_in_cell_2(CMap& amap, typename CMap::Dart_handle adart1); + + template + friend + typename CMap::Dart_handle + insert_cell_1_in_cell_2(CMap& amap, + typename CMap::Dart_handle adart1, + typename CMap::Dart_handle adart2); + + template + friend + typename Map::Dart_handle + insert_cell_2_in_cell_3(Map& amap, InputIterator afirst, + InputIterator alast); + + template < class Map > + friend + typename Map::Dart_handle + insert_cell_0_in_cell_2(Map& amap, typename Map::Dart_handle adart); + + template + friend struct internal::Degroup_one_attribute_of_dart_functor; + + template + friend struct internal::Degroup_one_attribute_functor; + + template + friend struct internal::Test_is_valid_attribute_functor; + + template + friend struct internal::Group_attribute_functor_of_dart_run; + + template + friend struct internal::Group_attribute_functor_run; + + template + friend struct internal::Group_one_attribute_functor; + + template + friend struct internal::Degroup_attribute_functor_run; + + template + friend struct internal::Update_dart_of_attribute_functor; + + template + friend struct internal::Decrease_attribute_functor; + + public: + /// Types definition + typedef Combinatorial_map_base Self; + + typedef Items_ Items; + typedef Alloc_ Alloc; + + typedef typename Items::template Dart_wrapper Dart_wrapper; + typedef typename Dart_wrapper::Dart Dart; + + typedef typename Alloc::template rebind::other Dart_allocator; + typedef Compact_container Dart_container; + + typedef typename Dart_container::iterator Dart_handle; + typedef typename Dart_container::const_iterator Dart_const_handle; + typedef typename Dart_container::size_type size_type; + + /// The dimension of the combinatorial map. + static const unsigned int dimension = d_; + + /// Number of marks + static const size_type NB_MARKS = 32; + + typedef internal::Combinatorial_map_helper Helper; + + /// Typedef for Dart_range, a range through all the darts of the map. + typedef Dart_container Dart_range; + typedef const Dart_container Dart_const_range; + + typedef typename Dart_wrapper::Attributes Attributes; + + /// Typedef for attributes + template + struct Attribute_type: public Helper::template Attribute_type + {}; + template + struct Attribute_handle: public Helper::template Attribute_handle + {}; + template + struct Attribute_const_handle: + public Helper::template Attribute_const_handle + {}; + template + struct Attribute_range: public Helper::template Attribute_range + {}; + template + struct Attribute_const_range: + public Helper::template Attribute_const_range + {}; + + public: + /** Default Combinatorial_map constructor. + * The map is empty. + */ + Combinatorial_map_base() + { + CGAL_static_assertion_msg( Dart::dimension==dimension, + "Dimension of dart different from dimension of map"); + + CGAL_static_assertion_msg( Helper::nb_attribs<=dimension+1, + "Too many attributes in the tuple Attributes_enabled"); + + this->mnb_used_marks = 0; + this->mmask_marks.reset(); + this->mused_marks.reset(); + + for (size_type i = 0; i < NB_MARKS; ++i) + { + this->mfree_marks_stack[i] = (int)i; + this->mindex_marks[i] = i; + this->mnb_marked_darts[i] = 0; + } + + // We must do this ony once, but problem because null_dart_handle + // is static ! + if ( mnull_dart_container.empty() ) + { + null_dart_handle = + mnull_dart_container.emplace( std::bitset() ); + + for (unsigned int i=0; i<=dimension; ++i) + { + null_dart_handle->unlink_beta(i); + } + } + + CGAL_assertion(number_of_darts()==0); + } + + /** Clear the combinatorial map. Remove all darts and all attributes. + * Note that reserved marks are not free. + */ + void clear() + { + mdarts.clear(); + for (unsigned int i = 0; i < NB_MARKS; ++i) + this->mnb_marked_darts[i] = 0; + + internal::Clear_all::run(mattribute_containers); + } + + /** Test if the map is empty. + * @return true iff the map is empty. + */ + bool is_empty() const + { return mdarts.empty(); } + + /** Create a new dart and add it to the map. + * The marks of the darts are initialised with mmask_marks, i.e. the dart + * is unmarked for all the marks. + * @return a Dart_handle on the new dart. + */ + Dart_handle create_dart() + { return mdarts.emplace(mmask_marks); } + + /** Erase a dart from the list of darts. + * @param adart the dart to erase. + */ + void erase_dart(Dart_handle adart) + { + // 1) We update the number of marked darts. + for (unsigned int i = 0; i < mnb_used_marks; ++i) + { + if (is_marked(adart, mused_marks_stack[i])) + --mnb_marked_darts[mused_marks_stack[i]]; + } + + // 2) We update the attribute_ref_counting. + Helper::template Foreach_enabled_attributes + >::run(this,adart); + + // 3) We erase the dart. + mdarts.erase(adart); + } + + /// @return a Dart_range (range through all the darts of the map). + Dart_range& darts() { return mdarts;} + Dart_const_range& darts() const { return mdarts; } + + /** Get the first dart of this map. + * @return the first dart. + */ + Dart_handle first_dart() + { + if (darts().begin() == darts().end()) return null_dart_handle; + return mdarts.begin(); + } + Dart_const_handle first_dart() const + { + if (darts().begin() == darts().end()) return null_dart_handle; + return mdarts.begin(); + } + + /// @return the Dart_handle corresponding to the given dart. + Dart_handle dart_handle(Dart& adart) + { return mdarts.iterator_to(adart); } + Dart_const_handle dart_handle(const Dart& adart) const + { return mdarts.iterator_to(adart); } + + /** Count the number of used marks. + * @return the number of used marks. + */ + size_type number_of_used_marks() const + { return mnb_used_marks; } + + /** Test if a given mark is reserved. + * @return true iff the mark is reserved (ie in used). + */ + bool is_reserved(int amark) const + { + CGAL_assertion(amark>=0 && (size_type)amarkget_mark(amark)!=mmask_marks[(size_type)amark]; + } + + /** Set the mark of a given dart to a state (on or off). + * @param adart the dart. + * @param amark the given mark. + * @param astate the state of the mark (on or off). + */ + void set_mark_to(Dart_const_handle adart, int amark, + bool astate) const + { + CGAL_assertion( adart != null_dart_handle ); + CGAL_assertion( is_reserved(amark) ); + + if (is_marked(adart, amark) != astate) + { + if (astate) ++mnb_marked_darts[(size_type)amark]; + else --mnb_marked_darts[(size_type)amark]; + + adart->set_mark(amark, astate ^ mmask_marks[(size_type)amark]); + } + } + + /** Mark the given dart. + * @param adart the dart. + * @param amark the given mark. + */ + void mark(Dart_const_handle adart, int amark) const + { + CGAL_assertion( adart != null_dart_handle ); + CGAL_assertion( is_reserved(amark) ); + + if (is_marked(adart, amark)) return; + + ++mnb_marked_darts[(size_type)amark]; + adart->set_mark(amark, !mmask_marks[(size_type)amark]); + } + + /** Unmark the given dart. + * @param adart the dart. + * @param amark the given mark. + */ + void unmark(Dart_const_handle adart, int amark) const + { + CGAL_assertion( adart != null_dart_handle ); + CGAL_assertion( is_reserved(amark) ); + + if (!is_marked(adart, amark)) return; + + --mnb_marked_darts[(size_type)amark]; + adart->set_mark(amark, mmask_marks[(size_type)amark]); + } + + /** Unmark all the darts of the map for a given mark. + * If all the darts are marked or unmarked, this operation takes O(1) + * operations, otherwise it traverses all the darts of the map. + * @param amark the given mark. + */ + void unmark_all(int amark) const + { + CGAL_assertion( is_reserved(amark) ); + + if (is_whole_map_unmarked(amark)) return; + + if (is_whole_map_marked(amark)) + { + negate_mark(amark); + } + else + { + for (typename Dart_range::const_iterator it(darts().begin()), + itend(darts().end()); it!=itend; ++it) + unmark(it, amark); + } + CGAL_assertion(is_whole_map_unmarked(amark)); + } + + /** Free a given mark, previously calling unmark_all_darts. + * @param amark the given mark. + */ + void free_mark(int amark) const + { + CGAL_assertion( is_reserved(amark) ); + + unmark_all(amark); + mused_marks.set((size_type)amark, false); + + // 1) We remove amark from the array mused_marks_stack by + // replacing it with the last mark in this array. + mused_marks_stack[mindex_marks[(size_type)amark]] = + mused_marks_stack[--mnb_used_marks]; + mindex_marks[mused_marks_stack[mnb_used_marks]] = + mindex_marks[(size_type)amark]; + + // 2) We add amark in the array mfree_marks_stack and update its index. + mfree_marks_stack[ mnb_used_marks ] = amark; + mindex_marks[(size_type)amark] = mnb_used_marks; + } + + /** Test if this map is without boundary for a given dimension. + * @param i the dimension. + * @return true iff all the darts are not i-free. + * @pre 1<=i<=n + */ + bool is_without_boundary(unsigned int i) const + { + CGAL_assertion(1<=i && i<=dimension); + for (typename Dart_const_range::const_iterator it(darts().begin()), + itend(darts().end()); it!=itend; ++it) + if (it->is_free(i)) return false; + return true; + } + + /** Test if this map is without boundary for all the dimensions. + * @return true iff all the darts are non free. + */ + bool is_without_boundary() const + { + for (typename Dart_const_range::const_iterator it(darts().begin()), + itend(darts().end()); it!=itend; ++it) + for (unsigned int i = 1; i<=dimension; ++i) + if (it->is_free(i)) return false; + return true; + } + + /** Close the combinatorial map for a given dimension. + * @param i the dimension to close + * @return the number of new darts. + * @pre 2<=i<=n (TODO case i==1) + */ + unsigned int close(unsigned int i) + { + CGAL_assertion(2<=i && i<=dimension); + unsigned int res = 0; + Dart_handle d, d2; + + for (typename Dart_range::iterator it(darts().begin()); + it!=darts().end(); ++it) + { + if ( it->is_free(i) ) + { + d = create_dart(); + ++res; + link_beta(it, d, i); + + // Special cases for 0 and 1 + if ( !it->is_free(1) && !it->beta(1)->is_free(i) ) + link_beta<1>(it->beta(1)->beta(i),d); + if ( !it->is_free(0) && !it->beta(0)->is_free(i) ) + link_beta<0>(it->beta(0)->beta(i),d); + // General case for 2...dimension + for (unsigned int j=2; j<=dimension; ++j) + { + if ( j+1!=i && j!=i && j!=i+1 && + !it->is_free(j) && !it->beta(j)->is_free(i) ) + { + link_beta(it->beta(j)->beta(i), d, j); + } + } + + d2 = it; + while (d2 != null_dart_handle && !d2->is_free(i-1)) + { d2 = d2->beta(i-1)->beta(i); } + if (d2 != null_dart_handle) + { + if (i==2) link_beta<1>(d2, d); + else link_beta(d2, d, i-1); + } + } + } + return res; + } + + /** Test if the map is valid. + * @return true iff the map is valid. + */ + bool is_valid() const + { + bool valid = true; + unsigned int i = 0, j = 0; + std::vector marks(dimension+1); + for (i=0; i<=dimension; ++i) + marks[i] = -1; + + Helper::template + Foreach_enabled_attributes >:: + run(this,&marks); + + for (typename Dart_range::const_iterator it(darts().begin()), + itend(darts().end()); it!=itend; ++it) + { + if ( !valid ) + { // We continue the traversal to mark all the darts. + for (i=0; i<=dimension; ++i) + if (marks[i]!=-1) mark(it,marks[i]); + } + else + { + // beta0 must be the inverse of beta1 + if ((!it->is_free(0) && it->beta(0)->beta(1)!=it) || + (!it->is_free(1) && it->beta(1)->beta(0)!=it )) + { + std::cerr << "Map not valid: beta(0) " + "is not the inverse of beta(1) for " + <<&(*it) << std::endl; + valid = false; + } + + // Each beta(i>=2) must be an involution + for (i = 2; i <= dimension; ++i) + if (!it->is_free(i) && it->beta(i)->beta(i)!=it) + { + std::cerr << "Map not valid: beta(" << i + << ") is not an involution for " + <<&(*it) << std::endl; + valid = false; + } + + // beta1 o betai and beta0 o betai (i>=3) must be involutions + if (!it->is_free(0)) + { + for (i = 3; i <= dimension; ++i) + if ((it->is_free(i) != it->beta(0)->is_free(i)) || + (!it->is_free(i) && + it->beta(0)->beta(i)!=it->beta(i)->beta(1))) + { + std::cerr << "Map not valid: beta(0) o beta(" << i + << ") is not an involution for " + <<&(*it) << std::endl; + valid = false; + } + } + if (!it->is_free(1)) + { + for (i = 3; i <= dimension; ++i) + if ((it->is_free(i) != it->beta(1)->is_free(i)) || + (!it->is_free(i) && + it->beta(1)->beta(i)!=it->beta(i)->beta(0))) + { + std::cerr << "Map not valid: beta(1) o beta(" << i + << ") is not an involution for " + <<&(*it)<< std::endl; + valid = false; + } + } + + // beta(i>=2) o beta(j>=i+2) must be an involution + for (i = 2; i <= dimension; ++i) + { + if (!it->is_free(i)) + { + for (j = i + 2; j <= dimension; ++j) + if ((it->is_free(j)!=it->beta(i)->is_free(j)) || + (!it->is_free(j) && + it->beta(i)->beta(j)!=it->beta(j)->beta(i))) + { + std::cerr << "Map not valid: beta(" << i + << ") o beta(" << j + << ") is not an involution for " + << &(*it)<< std::endl; + valid = false; + } + } + } + Helper::template Foreach_enabled_attributes + >:: + run(this,it,&marks,&valid); + } + } + for (i=0; i<=dimension; ++i) + if ( marks[i]!=-1 ) + { + CGAL_assertion( is_whole_map_marked(marks[i]) ); + free_mark(marks[i]); + } + + return valid; + } + + /// @return the number of darts. + size_type number_of_darts() const + { return mdarts.size(); } + + /// @return an estimation of the bytes used by the combinatorial map. + size_type bytes() const + { + return mdarts.capacity() * sizeof(Dart) + + internal::Count_bytes_all_attributes_functor::run(*this); + } + + /** Write the content of the map: each dart and each beta links. + * @param os the ostream. + * @return the ostream. + */ + std::ostream& display_darts(std::ostream & os) const + { + unsigned int nb = 0; + for (typename Dart_range::const_iterator it=darts().begin(); + it!=darts().end(); ++it) + { + os << " dart " << &(*it) << "; beta[i]="; + for (unsigned int i=0; i<=dimension; ++i) + { + os << &(*it->beta(i)) << ",\t"; + if (it->is_free(i))os << "\t"; + } + os << std::endl; + ++nb; + } + os << "Number of darts: " << nb <<"(sizeofdarts=" + < + std::ostream& display_orbits(std::ostream & aos) const + { + CGAL_assertion( Ite::is_basic_iterator() ); + unsigned int nb = 0; + int amark = get_new_mark(); + for (typename Dart_range::const_iterator it1(darts().begin()), + itend(darts().end()); it1!=itend; ++it1) + { + if ( !is_marked(it1, amark) ) + { + ++nb; + for ( Ite it2(*this, it1, amark); it2.cont(); ++it2 ) + { + aos << &(**it2) << " - " << std::flush; + mark(*it2, amark); + } + aos << std::endl; + } + } + CGAL_assertion( is_whole_map_marked(amark) ); + free_mark(amark); + aos << "Number of orbits: " << nb << std::endl; + return aos; + } + + /** Write the content of each i-cell of the map. + * @param aos the ostream. + * @return the ostream. + */ + template < unsigned int i > + std::ostream& display_cells(std::ostream & aos) const + { + return display_orbits > + (aos); + } + + /** Write the number of darts and cells of the map into a given ostream. + * @param os the ostream. + * @return the ostream. + */ + std::ostream& display_characteristics(std::ostream & os) const + { + std::vector cells(dimension+2); + for (unsigned int i=0; i<=dimension+1; ++i) + { cells[i]=i; } + + std::vector res = count_cells(cells); + + os << "#Darts=" << number_of_darts(); + for (unsigned int i=0; i<=dimension; ++i) + os<<", #"< but i-attributes are disabled"); + return CGAL::cpp0x::get::value> + (mattribute_containers).emplace(); + } + + /// Create a new attribute by copy. + /// @return a handle on the new attribute. + template + typename Attribute_handle::type create_attribute(const A&a) + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "create_attribute but i-attributes are disabled"); + return CGAL::cpp0x::get::value> + (mattribute_containers).emplace(a); + } + + /// Erase an attribute. + /// @param h a handle to the attribute to erase. + template + void erase_attribute(typename Attribute_handle::type h) + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "erase_attribute but i-attributes are disabled"); + CGAL::cpp0x::get::value> + (mattribute_containers).erase(h); + } + + /// @return the number of attributes. + template + size_type number_of_attributes() const + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "number_of_attributes but i-attributes are disabled"); + return CGAL::cpp0x::get::value> + (mattribute_containers).size(); + } + + /// @return a Attributes_range (range through all the + /// attributes of the map). + template + typename Attribute_range::type & attributes() + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "attributes but i-attributes are disabled"); + return CGAL::cpp0x::get::value> + (mattribute_containers); + } + + template + typename Attribute_const_range::type & attributes() const + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "attributes but i-attributes are disabled"); + return CGAL::cpp0x::get::value> + (mattribute_containers); + } + + /** Double link a dart with beta i to a second dart, when i>=2. + * \em adart1 is i-linked to \em adart2 and \em adart2 is i-linked + * with \em adart1. Attributes are not updated, thus we can obtain + * a non-valid map with darts belonging to a same orbit and having + * different attributes. + * @param adart1 a first dart. + * @param adart2 a second dart. + * @param i the dimension of the beta + */ + void basic_link_beta(Dart_handle adart1, Dart_handle adart2, unsigned int i) + { + CGAL_assertion( i>=2 && i<=dimension ); + CGAL_assertion(adart1 != NULL && adart2 != NULL && adart1!=adart2); + CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle); + adart1->basic_link_beta(adart2, i); + adart2->basic_link_beta(adart1, i); + } + + /** Double link a dart with betai to a second dart. + * \em adart1 is i-linked to \em adart2 and \em adart2 is i^-1-linked + * with \em adart1. Attributes are not updated, thus we can obtain + * a non-valid map with darts belonging to a same orbit and having + * different attributes. + * @param adart1 a first dart. + * @param adart2 a second dart. + */ + template + void basic_link_beta(Dart_handle adart1, Dart_handle adart2) + { internal::basic_link_beta_functor::run(*this,adart1,adart2); } + + /** Double unlink a dart with beta0. + * beta0(\em adart) is 1-unlinked and \em adart is 0-unlinked. + * The attributes are not updated, thus we can obtain a non-valid map + * with darts belonging to different orbits and having the same + * attributes. + * @param adart a dart. + */ + template + void unlink_beta(Dart_handle adart) + { internal::unlink_beta_functor::run(*this,adart); } + + /** Double unlink a dart with beta i, for i>=2. + * betai(\em adart) is i-unlinked and \em adart is i-unlinked. + * The attributes are not updated, thus we can obtain a non-valid map + * with darts belonging to different orbits and having the same + * attributes. + * @param adart a dart. + * @param i the dimension of the beta + */ + void unlink_beta(Dart_handle adart, unsigned int i) + { + CGAL_assertion(adart!=NULL && adart!=null_dart_handle && + !adart->is_free(i)); + CGAL_assertion(2<=i && i<=dimension); + adart->beta(i)->unlink_beta(i); + adart->unlink_beta(i); + } + + /** Double link two darts, and update the NULL attributes. + * \em adart1 is i-linked to \em adart2 and \em adart2 is i^-1-linked + * with \em adart1. The NULL attributes of \em adart1 are updated to + * non NULL attributes associated to \em adart2, and vice-versa. + * We can obtain a non-valid map with darts belonging to a same cell + * and having different attributes. + * @param adart1 a first dart. + * @param adart2 a second dart. + */ + template + void link_beta(Dart_handle adart1, Dart_handle adart2) + { internal::link_beta_functor::run(*this,adart1,adart2); } + + /** Double link two darts, and update the NULL attributes. + * \em adart1 is i-linked to \em adart2 and \em adart2 is i^-1-linked + * with \em adart1. The NULL attributes of \em adart1 are updated to + * non NULL attributes associated to \em adart2, and vice-versa. + * We can obtain a non-valid map with darts belonging to a same cell + * and having different attributes. + * @param adart1 a first dart. + * @param adart2 a second dart. + * @param i the dimension of the beta. + * @pre 2<=i<=dimension + */ + void link_beta(Dart_handle adart1, Dart_handle adart2, unsigned int i) + { + CGAL_assertion(adart1 != NULL && adart2 != NULL && adart1!=adart2 ); + CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle); + CGAL_assertion( 2<=i && i<=dimension ); + adart1->basic_link_beta(adart2, i); + adart2->basic_link_beta(adart1, i); + Helper::template Foreach_enabled_attributes + >:: + run(this,adart1,adart2,i); + } + + /** Double link a dart with betai to a second dart. + * \em adart1 is i-linked to \em adart2 and \em adart2 is i^-1-linked + * with \em adart1. The NULL attributes of \em adart1 are updated to + * non NULL attributes associated to \em adart2, and vice-versa, only . + * if update_attributes==true. + * @param adart1 a first dart. + * @param adart2 a second dart. + * @param update_attributes a boolean to update the enabled attributes + */ + template + void link_beta(Dart_handle adart1, Dart_handle adart2, + bool update_attributes) + { + if ( update_attributes ) link_beta(adart1, adart2); + else basic_link_beta(adart1, adart2); + } + + /** Test if it is possible to sew by betai the two given darts + * @param adart1 the first dart. + * @param adart2 the second dart. + * @return true iff \em adart1 can be i-sewn with \em adart2. + */ + template + bool is_sewable(Dart_const_handle adart1, Dart_const_handle adart2) const + { return internal::is_sewable_functor::run(*this,adart1,adart2); } + + /** Topological sew by betai the two given darts plus all the required darts + * to satisfy the combinatorial map validity: but do not update attributes + * thus the map can be non valid. + * @param adart1 the first dart. + * @param adart2 the second dart. + * @pre is_sewable(adart1, adart2). + */ + template + void topo_sew(Dart_handle adart1, Dart_handle adart2) + { return internal::topo_sew_functor::run(*this,adart1,adart2); } + + /** Sew by betai the two given darts plus all the required darts + * to satisfy the combinatorial map validity, and updates enabled + * attributes when necessary so that the final map is valid. + * @param adart1 the first dart. + * @param adart2 the second dart. + * @pre is_sewable(adart1, adart2). + * @post is_valid() + */ + template + void sew(Dart_handle adart1, Dart_handle adart2) + { return internal::sew_functor::run(*this,adart1,adart2); } + + /** Sew by betai the two given darts plus all the required darts + * to satisfy the combinatorial map validity. Enabled attributes + * are updated only if update_attributes==true. + * @param adart1 the first dart. + * @param adart2 the second dart. + * @param update_attributes a boolean to update the enabled attributes + * @pre is_sewable(adart1, adart2). + */ + template + void sew(Dart_handle adart1, Dart_handle adart2, bool update_attributes) + { + if ( update_attributes ) sew(adart1, adart2); + else topo_sew(adart1, adart2); + } + + /** Topological unsew by betai the given dart plus all the required darts + * to satisfy the combinatorial map validity: but do not update attributes + * thus the map can be non valid + * @param adart first dart. + * @pre !adart->is_free(i). + */ + template + void topo_unsew(Dart_handle adart) + { return internal::topo_unsew_functor::run(*this,adart); } + + /** Unsew by betai the given dart plus all the required darts + * to satisfy the combinatorial map validity, and update enabled + * attributes when necessary so that the final map is valid. + * @param adart first dart. + * @pre !adart->is_free(i). + * @post is_valid() + */ + template + void unsew(Dart_handle adart) + { return internal::unsew_functor::run(*this,adart); } + + /** Unsew by betai the given dart plus all the required darts + * to satisfy the combinatorial map validity. Enabled attributes + * are updated only if update_attributes==true. + * @param adart first dart. + * @param update_attributes a boolean to update the enabled attributes + * @pre !adart->is_free(i). + */ + template + void unsew(Dart_handle adart, bool update_attributes) + { + if ( update_attributes ) unsew(adart); + else topo_unsew(adart); + } + + /** Count the marked cells (at least one marked dart). + * @param amark the mark to consider. + * @param avector containing the dimensions of the cells to count. + * @return a vector containing the number of cells. + */ + std::vector + count_marked_cells(int amark, const std::vector& acells) const + { + std::vector res(dimension+2); + std::vector marks(dimension+2); + + // Initialization of the result + for (unsigned int i=0; i,dimension+1>:: + run(this, it, &marks, &res); + } + } + + // Unmarking darts + std::vector tounmark; + for (unsigned int i=0; i 0 ) + { + for (typename Dart_range::const_iterator it(darts().begin()), + itend(darts().end()); it!=itend; ++it) + { + for (unsigned int i=0; i + count_cells(const std::vector& acells) const + { + std::vector res(dimension+1); + int m = get_new_mark(); + negate_mark(m); // We mark all the cells. + + res = count_marked_cells(m,acells); + + negate_mark(m); // We unmark the cells + free_mark(m); + + return res; + } + + protected: + /** Set simultaneously all the marks of a given dart. + * @param adart the dart. + * @param amarks the marks to set. + */ + void set_marks(Dart_handle adart, + const std::bitset & amarks) const + { + CGAL_assertion(adart != NULL && adart!=null_dart_handle); + adart->set_marks(amarks ^ mmask_marks); + } + + /** Get simultaneously all the marks of a given dart. + * @param adart the dart. + * @return allt the marks of adart. + */ + std::bitset get_marks(Dart_handle adart) const + { + CGAL_assertion(adart != NULL && adart!=null_dart_handle); + return adart->get_marks() ^ mmask_marks; + } + + /** Get the mask associated to a given mark. + * @param amark the mark. + * @return the mask associated to mark amark. + */ + bool get_mask_mark(int amark) const + { + CGAL_assertion(amark>=0 && (size_type)amark + void decrease_attribute_ref_counting(Dart_handle adart) + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "decrease_attribute_ref_counting but " + "i-attributes are disabled"); + if ( adart->template attribute()!=NULL ) + { + adart->template attribute()->dec_nb_refs(); + if ( adart->template attribute()->get_nb_refs()==0 ) + erase_attribute(adart->template attribute()); + } + } + + /** Update the dart of the given i-cell attribute onto a non marked dart. + * @param ah the attribute to update. + * @param amark the mark. + */ + template + void update_dart_of_attribute(Dart_handle ah, int amark) + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "update_dart_of_attribute but " + "i-attributes are disabled"); + CGAL_assertion(ah!=NULL && ah!=null_dart_handle); + + if ( ah->template attribute()==NULL || + ah->template attribute()->dart()==NULL || + !is_marked(ah->template attribute()->dart(),amark) ) + return; + + for (CMap_dart_iterator_of_cell it(*this, ah); it.cont(); ++it) + { + if (!is_marked(it,amark)) + { + ah->template attribute()->set_dart(it); + return; + } + } + ah->template attribute()->set_dart(NULL); + } + + /** Update the dart of all the cell-attributes incident to ah onto a non + * marked dart. This method is used before to remove a cell (which is + * marked), to put all the darts of the enabled cells onto surviving dart. + * @param ah the dart to update. + * @param amark the mark. + */ + void update_dart_of_all_attributes(Dart_handle ah, int amark) + { + Helper::template Foreach_enabled_attributes + >::run(this,ah,amark); + } + + /** Group the i cell-attributes of two darts. + * If the two i cell-attribute of \em adart1 and \em adart2 are different, + * we set the i cell-attribute of each dart belonging to the i-cell orbit + * of \em adart2 onto the i-cell of \em adart1. + * We use the functor On_merge and possibly remove the second + * cell-attribute if there is no more darts linked to it. + * @param adart1 the first dart. + * @param adart2 the second dart. + */ + template + void group_enabled_attribute( Dart_handle adart1, Dart_handle adart2) + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "group_enabled_attribute but " + "i-attributes are disabled"); + CGAL_assertion(adart1 != NULL && adart2 != NULL); + CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle); + CGAL_assertion(i<=dimension); + + typename Attribute_handle::type a1=adart1->template attribute(); + typename Attribute_handle::type a2=adart2->template attribute(); + + // If the two attributes are equal, nothing to do. + if ( a1 == a2 ) return; + + Dart_handle toSet = NULL; + + // If the attribute associated to adart1 is NULL, set it with + // the attribute associated to adart2 (necessarily != NULL) + if (a1 == NULL) + { toSet = adart1; a1 = a2; } + else + { + toSet = adart2; + if (a2 != NULL) + { + internal::Apply_cell_functor::run(*a1,*a2); + } + } + set_attribute(toSet, a1); + } + + /** Group all the attributes of adart1 and adart2. If both dart have a + * i-attribute, the attribute associated to adart1 is kept. + * @param adart1 the first dart. + * @param adart1 the second dart. + */ + template + void group_attribute(Dart_handle adart1, Dart_handle adart2) + { + internal::Group_one_attribute_functor::type>::run(this,adart1,adart2); + } + + /** Group the i cell-attributes of two darts. + * If the two i cell-attribute of \em adart1 and \em adart2 are different, + * we set the i cell-attribute of adart2 onto the attribute of adart1. + * @param adart1 the first dart. + * @param adart2 the second dart. + */ + template + void group_enabled_attribute_of_dart( Dart_handle dh1, Dart_handle dh2) + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "group_enabled_attribute_of_dart but " + "i-attributes are disabled"); + CGAL_assertion( dh1!=NULL && dh2!=NULL ); + CGAL_assertion( dh1!=null_dart_handle && dh2!=null_dart_handle ); + CGAL_assertion(i<=dimension); + + typename Attribute_handle::type a1=dh1->template attribute(); + typename Attribute_handle::type a2=dh2->template attribute(); + + // If the two attributes are equal, nothing to do. + if ( a1 == a2 ) return; + + if ( a1==NULL ) + set_attribute_of_dart(dh1, a2); + else + set_attribute_of_dart(dh2, a1); + } + + /** Group all the cells attributes of adart1 and adart2, except the + * adim-cell attribute. + * @param adart1 the first dart. + * @param adart1 the second dart. + * @param adim the dimension to not group (-1 to group all dimensions). + */ + void group_all_attributes_except(Dart_handle adart1, Dart_handle adart2, + int adim) + { + CGAL_assertion( adim==-1 || (1<=adim && (unsigned int)adim<=dimension) ); + Helper::template Foreach_enabled_attributes + >:: + run(this,adart1,adart2,adim); + } + + /** Degroup the i-cell attribute of the two given darts, if required. + * If the two darts are incident to the same attribute and do not belong to + * the same i-cell, we create a new attibute and link each dart + * belonging to the i-cell of adart2 onto this new attribute. + * The new attribute is initialized by copying the old one then by using + * the functor On_split from the original attribute. + * @param adart1 the first dart. + * @param adart2 the second dart. + * @return true iff the attribute is split. + */ + template + bool degroup_enabled_attribute(Dart_handle adart1, Dart_handle adart2) + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "degroup_enabled_attribute but " + "i-attributes are disabled"); + CGAL_assertion(adart1 != NULL && adart2 != NULL); + CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle); + + typename Attribute_handle::type a1=adart1->template attribute(); + typename Attribute_handle::type a2=NULL; + + // If the two attributes are not equal, nothing to do. + if ( a1 != adart2->template attribute() || a1 == NULL) return false; + + // If the two darts belong to the same cell, nothing to do. + if ( belong_to_same_cell(*this, adart1, adart2) ) + return false; + + // Here we create a new attribute + a2 = create_attribute(*a1); + + // We call the on_split functor + internal::Apply_cell_functor::run(*a1,*a2); + + // We set the dart of the cell a1 onto adart1. + a1->set_dart(adart1); + + // And we set all the dart of the cell of adart2 to v1. + set_attribute(adart2, a2); + + return true; + } + + template + bool degroup_attribute(Dart_handle adart1, Dart_handle adart2) + { + return internal::Degroup_one_attribute_functor::type>::run(this,adart1,adart2); + } + + /** Degroup all the cells attributes of adart1 and adart2, except the + * adim-cell attribute. + * @param adart1 the first dart. + * @param adart1 the second dart. + * @param adim the dimension to not degroup (-1 to degroup all). + */ + void degroup_all_attributes_except(Dart_handle adart1, Dart_handle adart2, + int adim) + { + CGAL_assertion( adim==-1 || (1<=adim && (unsigned int)adim<=dimension) ); + Helper::template Foreach_enabled_attributes + >:: + run(this,adart1,adart2,adim); + } + + /** Degroup all the cells attributes of adart1 and adart2. + * @param adart1 the first dart. + * @param adart1 the second dart. + */ + void degroup_all_attributes(Dart_handle adart1, Dart_handle adart2) + { degroup_all_attributes_except(adart1, adart2, -1); } + + /** Degroup the i-cell attribute of the two given darts, if required. + * We create a new attibute and link dart2 onto this new attribute. + * The new attribute is initialized by copying the old one then by using + * the functor On_split from the original attribute. + * @param adart1 the first dart. + * @param adart2 the second dart. + * @return true iff the attribute is split. + */ + template + bool degroup_enabled_attribute_of_dart( Dart_handle dh1, Dart_handle dh2) + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "group_enabled_attribute_of_dart but " + "i-attributes are disabled"); + CGAL_assertion( dh1!=NULL && dh2!=NULL ); + CGAL_assertion( dh1!=null_dart_handle && dh2!=null_dart_handle ); + CGAL_assertion(i<=dimension); + + typename Attribute_handle::type a1=dh1->template attribute(); + typename Attribute_handle::type a2=dh2->template attribute(); + + // If the two attributes are equal, nothing to do. + if ( a1==NULL || a1 != a2 ) return false; + + a2 = create_attribute(*a1); + + // We call the on_split functor + // internal::Apply_cell_functor::run(*a1,*a2); + + // We set the attribute of dh2 to a2. + for (typename Range::iterator it=Range(*this,dh2).begin(), + itend=Range(*this,dh2).end(); it!=itend; ++it) + { + set_attribute_of_dart(it, a2); + } + return true; + } + + template + bool degroup_attribute_of_dart(Dart_handle adart1, Dart_handle adart2) + { + return internal::Degroup_one_attribute_of_dart_functor::type, Range>::run(this,adart1,adart2); + } + + /** Test the validity of a i-cell-attribute. + * ie all the darts belonging to a i-cell are linked to the same attribute. + * @param adart a dart. + * @param amark a mark used to mark darts of the i-cell. + * @return true iff all the darts of the i-cell link to the same attribute. + */ + template + bool is_valid_attribute(Dart_const_handle adart, + unsigned int amark) const + { + CGAL_static_assertion_msg( Helper::template Dimension_index::value>=0, + "is_valid_attribute but i-attributes" + " are disabled"); + if ( is_marked(adart, amark) ) return true; + bool valid = true; + + typename Attribute_const_handle::type + a=adart->template attribute(); + + unsigned int nb = 0; + for (CMap_dart_const_iterator_basic_of_cell + it(*this,adart,amark); it.cont(); ++it) + { + if ( it->template attribute() != a ) + valid = false; + + mark(it, amark); + ++nb; + } + + if ( a!=NULL && a->get_nb_refs()!=nb ) + valid = false; + + return valid; + } + + /** Erase marked darts from the map. + * Marked darts are unlinked before to be removed, thus surviving darts + * are correctly linked, but the map is not necessarily valid depending + * on the configuration of removed darts. User must check carefully marked + * darts before calling this method. + * @param amark the mark of darts to erase. + * @return the number of removed darts. + */ + unsigned int erase_marked_darts(int amark) + { + unsigned int res = 0, i = 0; + Dart_handle d; + for (typename Dart_range::iterator it(darts().begin()), + itend(darts().end()); it!=itend; ) + { + d = it++; + if (is_marked(d, amark)) + { + for (i = 0; i <= dimension; ++i) + { if (!d->is_free(i)) unlink_beta(d, i); } + erase_dart(d); ++res; + } + } + return res; + } + + public: + /** Set the i th attribute of the given dart. + * @param adart a dart. + * @param ah the attribute to set. + */ + template + void set_attribute_of_dart(Dart_handle adart, + typename Attribute_handle::type ah) + { + CGAL_static_assertion_msg(Helper::template Dimension_index::value>=0, + "set_attribute_of_dart but " + "i-attributes are disabled"); + CGAL_assertion( adart!=NULL && adart!=null_dart_handle && ah!=NULL ); + if ( adart->template attribute()==ah ) return; + + decrease_attribute_ref_counting(adart); + + adart->set_attribute(ah); + ah->set_dart(adart); + } + + /** Set the i th attribute of all the darts of a given i-cell. + * @param adart a dart of the i-cell. + * @param ah the vertex to set. + */ + template + void set_attribute(Dart_handle adart, + typename Attribute_handle::type ah) + { + CGAL_static_assertion_msg(Helper::template Dimension_index::value>=0, + "set_attribute but i-attributes are disabled"); + CGAL_assertion( adart!=NULL && adart!=null_dart_handle && ah!=NULL ); + for (CMap_dart_iterator_of_cell it(*this, adart); + it.cont(); ++it) + { + if ( it->template attribute()!=ah ) + { + decrease_attribute_ref_counting(it); + it->set_attribute(ah); + } + } + ah->set_dart(adart); + } + +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + //**************************************************************************** + // Dart_of_orbit_range + template + struct Dart_of_orbit_range { + typedef CMap_dart_iterator_of_orbit iterator; + typedef CMap_dart_const_iterator_of_orbit const_iterator; + Dart_of_orbit_range(Self &amap, Dart_handle adart) : + mmap(amap), mdart(adart), msize(0) + {} + iterator begin() { return iterator(mmap,mdart); } + iterator end() { return iterator(mmap,NULL); } + const_iterator begin() const { return const_iterator(mmap,mdart); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for ( iterator it=begin(),itend=end(); it!=itend; ++it) + ++msize; + return msize; + } + bool empty() const + { return mdart==NULL; } + private: + Self & mmap; + Dart_handle mdart; + size_type msize; + }; + //**************************************************************************** + // Dart_of_orbit_const_range + template + struct Dart_of_orbit_const_range { + typedef CMap_dart_const_iterator_of_orbit const_iterator; + Dart_of_orbit_const_range(const Self &amap, Dart_const_handle adart) : + mmap(amap), mdart(adart), msize(0) + {} + const_iterator begin() const { return const_iterator(mmap,mdart); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for ( const_iterator it=begin(),itend=end(); it!=itend; ++it) + ++msize; + return msize; + } + bool empty() const + { return mdart==NULL; } + private: + const Self & mmap; + Dart_const_handle mdart; + size_type msize; + }; +#else + //**************************************************************************** + // Dart_of_orbit_range + template + struct Dart_of_orbit_range { + typedef CMap_dart_iterator_of_orbit + iterator; + typedef CMap_dart_const_iterator_of_orbit + const_iterator; + Dart_of_orbit_range(Self &amap, Dart_handle adart) : + mmap(amap), mdart(adart), msize(0) + {} + iterator begin() { return iterator(mmap,mdart); } + iterator end() { return iterator(mmap,NULL); } + const_iterator begin() const { return const_iterator(mmap,mdart); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for ( iterator it=begin(),itend=end(); it!=itend; ++it) + ++msize; + return msize; + } + bool empty() const + { return mdart==NULL; } + private: + Self & mmap; + Dart_handle mdart; + size_type msize; + }; + //**************************************************************************** + // Dart_of_orbit_const_range + template + struct Dart_of_orbit_const_range { + typedef CMap_dart_const_iterator_of_orbit + const_iterator; + Dart_of_orbit_const_range(const Self &amap, Dart_const_handle adart) : + mmap(amap), mdart(adart), msize(0) + {} + const_iterator begin() const { return const_iterator(mmap,mdart); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for ( const_iterator it=begin(),itend=end(); it!=itend; ++it) + ++msize; + return msize; + } + bool empty() const + { return mdart==NULL; } + private: + const Self & mmap; + Dart_const_handle mdart; + size_type msize; + }; +#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + //**************************************************************************** + // Dart_of_cell_range + template + struct Dart_of_cell_range { + typedef CMap_dart_iterator_of_cell iterator; + typedef CMap_dart_const_iterator_of_cell const_iterator; + Dart_of_cell_range(Self &amap, Dart_handle adart) : + mmap(amap), mdart(adart), msize(0) + {} + iterator begin() { return iterator(mmap,mdart); } + iterator end() { return iterator(mmap,NULL); } + const_iterator begin() const { return const_iterator(mmap,mdart); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for ( iterator it=begin(); it!=end(); ++it) + ++msize; + return msize; + } + bool empty() const + { return mdart==NULL; } + private: + Self & mmap; + Dart_handle mdart; + size_type msize; + }; + //**************************************************************************** + // Dart_of_cell_const_range + template + struct Dart_of_cell_const_range { + typedef CMap_dart_const_iterator_of_cell const_iterator; + Dart_of_cell_const_range(const Self &amap, Dart_const_handle adart) : + mmap(amap), mdart(adart), msize(0) + {} + const_iterator begin() const { return const_iterator(mmap,mdart); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for ( const_iterator it=begin(); it!=end(); ++it) + ++msize; + return msize; + } + bool empty() const + { return mdart==NULL; } + private: + const Self & mmap; + Dart_const_handle mdart; + size_type msize; + }; + //**************************************************************************** + +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + /// @return a range on all the darts of the given orbit + template + Dart_of_orbit_range darts_of_orbit(Dart_handle adart) + { return Dart_of_orbit_range(*this,adart); } + + template + Dart_of_orbit_const_range + darts_of_orbit(Dart_const_handle adart) const + { return Dart_of_orbit_const_range(*this,adart); } +#else + /// @return a range on all the darts of the given orbit + Dart_of_orbit_range<> darts_of_orbit(Dart_handle adart) + { return Dart_of_orbit_range<>(*this,adart); } + Dart_of_orbit_const_range<> darts_of_orbit(Dart_const_handle adart) const + { return Dart_of_orbit_const_range<>(*this,adart); } + + template + Dart_of_orbit_range darts_of_orbit(Dart_handle adart) + { return Dart_of_orbit_range(*this,adart); } + template + Dart_of_orbit_const_range darts_of_orbit(Dart_const_handle + adart) const + { return Dart_of_orbit_const_range(*this,adart); } + + template + Dart_of_orbit_range darts_of_orbit(Dart_handle adart) + { return Dart_of_orbit_range(*this,adart); } + template + Dart_of_orbit_const_range darts_of_orbit(Dart_const_handle + adart) const + { return Dart_of_orbit_const_range(*this,adart); } + + template + Dart_of_orbit_range darts_of_orbit(Dart_handle adart) + { return Dart_of_orbit_range(*this,adart); } + template + Dart_of_orbit_range darts_of_orbit(Dart_const_handle adart) const + { return Dart_of_orbit_range(*this,adart); } + + template + Dart_of_orbit_range darts_of_orbit(Dart_handle adart) + { return Dart_of_orbit_range(*this,adart); } + template + Dart_of_orbit_const_range + darts_of_orbit(Dart_const_handle adart) const + { return Dart_of_orbit_const_range(*this,adart); } + + template + Dart_of_orbit_range darts_of_orbit(Dart_handle adart) + { return Dart_of_orbit_range(*this,adart); } + template + Dart_of_orbit_const_range + darts_of_orbit(Dart_const_handle adart) const + { return Dart_of_orbit_const_range(*this,adart); } + + template + Dart_of_orbit_range darts_of_orbit(Dart_handle adart) + { return Dart_of_orbit_range(*this,adart); } + template + Dart_of_orbit_const_range + darts_of_orbit(Dart_const_handle adart) const + { return Dart_of_orbit_const_range(*this,adart); } + + template + Dart_of_orbit_range darts_of_orbit(Dart_handle adart) + { return Dart_of_orbit_range(*this,adart); } + template + Dart_of_orbit_const_range + darts_of_orbit(Dart_const_handle adart) const + { return Dart_of_orbit_const_range(*this,adart); } + + template + Dart_of_orbit_range darts_of_orbit + (Dart_handle adart) + { return Dart_of_orbit_range(*this,adart); } + template + Dart_of_orbit_const_range + darts_of_orbit(Dart_const_handle adart) const + { return Dart_of_orbit_const_range(*this,adart); } + + template + Dart_of_orbit_range + darts_of_orbit(Dart_handle adart) + { return Dart_of_orbit_range(*this,adart); } + template + Dart_of_orbit_const_range + darts_of_orbit(Dart_const_handle adart) const + { return Dart_of_orbit_const_range + (*this,adart); } +#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + + /// @return a range on all the darts of the given i-cell + template + Dart_of_cell_range darts_of_cell(Dart_handle adart) + { return Dart_of_cell_range(*this,adart); } + + template + Dart_of_cell_const_range darts_of_cell(Dart_const_handle adart) const + { return Dart_of_cell_const_range(*this,adart); } + + template + Dart_of_cell_range darts_of_cell(Dart_handle adart) + { return darts_of_cell(adart); } + + template + Dart_of_cell_const_range + darts_of_cell(Dart_const_handle adart) const + { return darts_of_cell(adart); } + + //************************************************************************** + // One_dart_per_incident_cell_range + template + struct One_dart_per_incident_cell_range { + typedef CMap_one_dart_per_incident_cell_iterator iterator; + typedef CMap_one_dart_per_incident_cell_const_iterator + const_iterator; + One_dart_per_incident_cell_range(Self &amap, Dart_handle adart) : + mmap(amap), mdart(adart),msize(0) + {} + iterator begin() { return iterator(mmap,mdart); } + iterator end() { return iterator(mmap,NULL); } + const_iterator begin() const { return const_iterator(mmap,mdart); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for ( iterator it=begin(); it!=end(); ++it) + ++msize; + return msize; + } + bool empty() const + { return mdart==NULL; } + private: + Self & mmap; + Dart_handle mdart; + size_type msize; + }; + //************************************************************************** + // One_dart_per_incident_cell_const_range + template + struct One_dart_per_incident_cell_const_range { + typedef CMap_one_dart_per_incident_cell_const_iterator + const_iterator; + One_dart_per_incident_cell_const_range(const Self &amap, + Dart_const_handle adart) : + mmap(amap), mdart(adart), msize(0) + {} + const_iterator begin() const { return const_iterator(mmap,mdart); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for ( const_iterator it=begin(); it!=end(); ++it) + ++msize; + return msize; + } + bool empty() const + { return mdart==NULL; } + private: + const Self & mmap; + Dart_const_handle mdart; + size_type msize; + }; + //************************************************************************** + // One_dart_per_cell_range + template + struct One_dart_per_cell_range { + typedef CMap_one_dart_per_cell_iterator iterator; + typedef CMap_one_dart_per_cell_const_iterator const_iterator; + One_dart_per_cell_range(Self &amap) : mmap(amap), msize(0) + {} + iterator begin() { return iterator(mmap); } + iterator end() { return iterator(mmap,NULL); } + const_iterator begin() const { return const_iterator(mmap); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for ( iterator it=begin(); it!=end(); ++it) + ++msize; + return msize; + } + bool empty() const + { return mmap.is_empty(); } + private: + Self & mmap; + size_type msize; + }; + //************************************************************************** + // One_dart_per_cell_const_range + template + struct One_dart_per_cell_const_range { + typedef CMap_one_dart_per_cell_const_iterator const_iterator; + One_dart_per_cell_const_range(const Self &amap) : mmap(amap), msize(0) + {} + const_iterator begin() const { return const_iterator(mmap); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for ( const_iterator it=begin(); it!=end(); ++it) + ++msize; + return msize; + } + bool empty() const + { return mmap.is_empty(); } + private: + const Self & mmap; + size_type msize; + }; + //************************************************************************** + // Dart_of_involution_range + template + struct Dart_of_involution_range { + typedef CMap_dart_iterator_of_involution iterator; + typedef CMap_dart_const_iterator_of_involution const_iterator; + Dart_of_involution_range(Self &amap, Dart_handle adart) : + mmap(amap), mdart(adart), msize(0) + {} + iterator begin() { return iterator(mmap,mdart); } + iterator end() { return iterator(mmap,NULL); } + const_iterator begin() const { return const_iterator(mmap,mdart); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for (iterator it=begin(); it!=end(); ++it) + ++msize; + return msize; + } + bool empty() const + { return mmap.is_empty(); } + private: + Self & mmap; + Dart_handle mdart; + size_type msize; + }; + //************************************************************************** + // Dart_of_involution_const_range + template + struct Dart_of_involution_const_range { + typedef CMap_dart_const_iterator_of_involution const_iterator; + Dart_of_involution_const_range(const Self &amap, Dart_const_handle adart) : + mmap(amap), mdart(adart), msize(0) + {} + const_iterator begin() const { return const_iterator(mmap,mdart); } + const_iterator end() const { return const_iterator(mmap,NULL); } + size_type size() + { + if (msize==0) + for (const_iterator it=begin(); it!=end(); ++it) + ++msize; + return msize; + } + bool empty() const + { return mmap.is_empty(); } + private: + const Self & mmap; + Dart_const_handle mdart; + size_type msize; + }; + //************************************************************************** + + /// @return a range on the i-cells incindent to the given j-cell. + template + One_dart_per_incident_cell_range + one_dart_per_incident_cell(Dart_handle adart) + { return One_dart_per_incident_cell_range(*this,adart); } + + template + One_dart_per_incident_cell_const_range + one_dart_per_incident_cell(Dart_const_handle adart) const + { return One_dart_per_incident_cell_const_range(*this,adart); } + + template + One_dart_per_incident_cell_range + one_dart_per_incident_cell(Dart_handle adart) + { return one_dart_per_incident_cell(adart); } + + template + One_dart_per_incident_cell_const_range + one_dart_per_incident_cell(Dart_const_handle adart) const + { return one_dart_per_incident_cell(adart); } + + /// @return a range on all the i-cells + template + One_dart_per_cell_range one_dart_per_cell() + { return One_dart_per_cell_range(*this); } + + template + One_dart_per_cell_const_range one_dart_per_cell() const + { return One_dart_per_cell_const_range(*this); } + + template + One_dart_per_cell_range one_dart_per_cell() + { return one_dart_per_cell(); } + + template + One_dart_per_cell_const_range one_dart_per_cell() const + { return one_dart_per_cell(); } + + public: + /// Void dart. A dart d is i-free if beta_i(d)=null_dart_handle. + static Dart_handle null_dart_handle; + + private: + /// Dart container. + Dart_container mdarts; + + /// Container for the null_dart_handle, static data member. + static Dart_container mnull_dart_container; + + /// Array of reserved marks: mused_marks[i] true <=> mark number i is + /// in used, otherwise the mark is free. + mutable std::bitset mused_marks; + + /// Mask marks to know the value of unmark dart, for each index i. + mutable std::bitset mmask_marks; + + /// Number of used marks. + mutable size_type mnb_used_marks; + + /// Index of each mark, in mfree_marks_stack or in mfree_marks_stack. + mutable size_type mindex_marks[NB_MARKS]; + + /// "Stack" of free marks. + mutable int mfree_marks_stack[NB_MARKS]; + + /// "Stack" of used marks. + mutable int mused_marks_stack[NB_MARKS]; + + /// Number of marked darts for each used marks. + mutable size_type mnb_marked_darts[NB_MARKS]; + + /// Tuple of attributes containers + typename Helper::Attribute_containers mattribute_containers; + }; + + /// Allocation of static data members + /// mnull_dart_container + template < unsigned int d_, class Refs, class Items_, class Alloc_ > + typename Combinatorial_map_base::Dart_container + Combinatorial_map_base::mnull_dart_container; + + /// null_dart_handle + template < unsigned int d_, class Refs, class Items_, class Alloc_ > + typename Combinatorial_map_base::Dart_handle + Combinatorial_map_base::null_dart_handle; + // = mnull_dart_container.emplace( std::bitset() ); + // Does not work on windows => segfault + // Thus we initialize null_dart_handle in the Combinatorial_map constructor + // Not thread safe ! + + template < unsigned int d_, + class Items_=Combinatorial_map_min_items, + class Alloc_=CGAL_ALLOCATOR(int) > + class Combinatorial_map : + public Combinatorial_map_base, + Items_, Alloc_ > + { + public: + typedef Combinatorial_map Self; + typedef Combinatorial_map_base Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Dart_const_handle Dart_const_handle; + typedef typename Base::Alloc Alloc; + }; + + +} // namespace CGAL + +#endif // CGAL_COMBINATORIAL_MAP_H // +// EOF // diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_basic_operations.h b/Combinatorial_map/include/CGAL/Combinatorial_map_basic_operations.h new file mode 100644 index 00000000000..e6c06b7d696 --- /dev/null +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_basic_operations.h @@ -0,0 +1,340 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (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; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// 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) : Guillaume Damiand +// +#ifndef CGAL_COMBINATORIAL_MAP_BASIC_OPERATIONS_H +#define CGAL_COMBINATORIAL_MAP_BASIC_OPERATIONS_H 1 + +namespace CGAL { + +/** @file Combinatorial_map_basic_operations.h + * Basic operations on a combinatorial map. + */ + +/** Test if the two given darts belong to the same given orbit. + * @param amap a combinatorial map. + * @param adart1 the first dart. + * @param adart2 the second dart. + * @return true iff the two darts belong to the same orbit. + */ +template < class Map, class Iterator > +bool belong_to_same_orbit(const Map & amap, + typename Map::Dart_const_handle adart1, + typename Map::Dart_const_handle adart2) +{ + CGAL_assertion( (!Iterator::is_basic_iterator()) ); + bool found = false; + + for (Iterator it(amap, adart1); !found && it.cont(); ++it) + { + if (it == adart2) found = true; + } + + return found; +} + +/** Test if all the darts of a given orbit are marked. + * @param amap a combinatorial map. + * @param adart a dart of the orbit. + * @param amark the mark. + * @return true iff all the darts are marked. + */ +template < class Map, class Iterator > +bool is_whole_orbit_marked(const Map & amap, + typename Map::Dart_const_handle adart, + int amark) +{ + CGAL_assertion( !Iterator::is_basic_iterator() ); + bool res = true; + + for ( Iterator it(amap, adart); res && it.cont(); ++it ) + { + if (!amap.is_marked(it, amark)) res = false; + } + + return res; +} + +/** Test if all the darts of a given orbit are unmarked. + * @param amap a combinatorial map. + * @param adart a dart of the orbit. + * @param amark the mark. + * @return true iff all the darts are unmarked. + */ +template < class Map, class Iterator > +bool is_whole_orbit_unmarked(const Map & amap, + typename Map::Dart_const_handle adart, + int amark) +{ + amap.negate_mark(amark); + bool res = is_whole_orbit_marked(amap, adart, amark); + amap.negate_mark(amark); + return res; +} + +/** Mark a given orbit with a given mark. + * @param amap a combinatorial map. + * @param adart a dart of the orbit. + * @param amark the mark. + * @return the number of darts of the marked orbit. + * @pre The whole orbit must be unmarked. + */ +template < class Map, class Iterator > +typename Map::size_type mark_orbit(const Map & amap, + typename Map::Dart_const_handle adart, + unsigned int amark) +{ + CGAL_assertion( Iterator::is_basic_iterator() ); + CGAL_assertion( (is_whole_orbit_unmarked > + (amap, adart, amark)) ); + typename Map::size_type res = 0; + + for (Iterator it(amap, adart, amark); it.cont(); ++it) + { + amap.mark(it, amark); + ++res; + } + + return res; +} + +/** Unmark a given orbit with a given mark. + * @param amap a combinatorial map. + * @param adart a dart of the orbit. + * @param amark the mark. + * @return the number of darts of the unmarked orbit. + * @pre The whole orbit must be marked. + */ +template < class Map, class Iterator > +typename Map::size_type unmark_orbit(const Map & amap, + typename Map::Dart_const_handle adart, + int amark) +{ + amap.negate_mark(amark); + typename Map::size_type res = mark_orbit(amap, adart, amark); + amap.negate_mark(amark); + return res; +} + +/** Test if the two given darts belong to the same cell. + * @param amap a combinatorial map. + * @param adart1 the first dart. + * @param adart2 the second dart. + * @return true iff the two darts belong to the same cell. + */ + template < class Map, unsigned int i, unsigned int d> + bool belong_to_same_cell(const Map & amap, + typename Map::Dart_const_handle adart1, + typename Map::Dart_const_handle adart2) +{ + return belong_to_same_orbit > + (amap, adart1, adart2); +} + + template < class Map, unsigned int i> + bool belong_to_same_cell(const Map & amap, + typename Map::Dart_const_handle adart1, + typename Map::Dart_const_handle adart2) +{ + return belong_to_same_cell(amap,adart1,adart2); +} + + +/** Test if all the darts of a given cell are marked. + * @param amap a combinatorial map. + * @param adart a dart of the cell. + * @param amark the mark. + * @return true iff all the darts are marked. + */ +template < class Map, unsigned int i, unsigned int d> +bool is_whole_cell_marked(const Map & amap, + typename Map::Dart_const_handle adart, + unsigned int amark) +{ + return is_whole_orbit_marked > + (amap, adart, amark); +} + +template < class Map, unsigned int i> + bool is_whole_cell_marked(const Map & amap, + typename Map::Dart_const_handle adart, + unsigned int amark) +{ + return is_whole_cell_marked(amap,adart,amark); +} + +/** Test if all the darts of a given cell are unmarked. + * @param amap a combinatorial map. + * @param adart a dart of the cell. + * @param amark the mark. + * @return true iff all the darts are marked. + */ +template < class Map, unsigned int i, unsigned int d > +bool is_whole_cell_unmarked(const Map & amap, + typename Map::Dart_const_handle adart, + unsigned int amark) +{ + return is_whole_orbit_unmarked > + (amap, adart, amark); +} + +template < class Map, unsigned int i> +bool is_whole_cell_unmarked(const Map & amap, + typename Map::Dart_const_handle adart, + unsigned int amark) +{ + return is_whole_cell_unmarked(amap,adart,amark); +} + +/** Mark a given cell with a given mark. + * @param amap a combinatorial map. + * @param adart a dart of the cell. + * @param amark the mark. + * @return the number of darts of the marked cell. + * @pre The whole cell must be unmarked. + */ +template < class Map, unsigned int i, unsigned int d > +typename Map::size_type mark_cell(const Map & amap, + typename Map::Dart_const_handle adart, + int amark) +{ return mark_orbit > + (amap, adart, amark); } + +template < class Map, unsigned int i> +typename Map::size_type mark_cell(const Map & amap, + typename Map::Dart_const_handle adart, + int amark) +{ return mark_cell(amap, adart, amark);} + +/** Unmark a given orbit with a given mark. + * @param amap a combinatorial map. + * @param adart a dart of the cell. + * @param amark the mark. + * @return the number of darts of the unmarked cell. + * @pre The whole cell must be marked. + */ +template < class Map, unsigned int i, unsigned int d > +typename Map::size_type unmark_cell(const Map & amap, + typename Map::Dart_handle adart, + int amark) +{ return unmark_orbit > + (amap, adart, amark);} + +template < class Map, unsigned int i > +typename Map::size_type unmark_cell(const Map & amap, + typename Map::Dart_handle adart, + int amark) +{ return unmark_cell(amap, adart, amark);} + +/** Compute the degree of a given i-cell c. + * The degree is the number of distinct i+1 cells incident to c. + * @param amap a combinatorial map. + * @param adart a dart of the cell. + * @return the degree of the cell. + */ +template < class Map, unsigned int i > +typename Map::size_type degree( const Map & amap, + typename Map::Dart_handle adart ) +{ + CGAL_assertion(adart != NULL); + + typename Map::size_type nbIncident = 0; + int mark = amap.get_new_mark(); + int treated = amap.get_new_mark(); + + CMap_dart_const_iterator_basic_of_cell it(amap, adart, mark); + for ( ;it.cont(); ++it ) + { + if (!amap.is_marked(*it, treated)) + { + ++nbIncident; + mark_cell(amap, *it, treated); + } + amap.mark(*it,mark); + } + + amap.negate_mark(mark); + for (it.rewind(); it.cont(); ++it) + { + if (amap.is_marked(*it, treated)) + unmark_cell(amap, *it, treated); + amap.mark(*it,mark); + } + + amap.negate_mark(mark); + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + CGAL_assertion( amap.is_whole_map_unmarked(treated) ); + + amap.free_mark(mark); + amap.free_mark(treated); + + CGAL_assertion(nbIncident != 0); + return nbIncident; +} + +/** Compute the co-degree of a given i-cell c. + * The co-degree is the number of distinct i-1 cells incident to c. + * @param amap a combinatorial map. + * @param adart a dart of the cell. + * @return the co-degree of the cell. + */ +template < class Map, unsigned int i > +typename Map::size_type codegree(const Map & amap, + typename Map::Dart_handle adart) +{ + CGAL_assertion(adart != NULL); + + typename Map::size_type nbIncident = 0; + int mark = amap.get_new_mark(); + int treated = amap.get_new_mark(); + + CMap_dart_const_iterator_basic_of_cell it(amap, adart, mark); + for ( ; it.cont(); ++it) + { + if (!amap.is_marked(*it, treated)) + { + ++nbIncident; + mark_cell(amap, *it, treated); + } + amap.mark(*it,mark); + } + + amap.negate_mark(mark); + for (it.rewind(); it.cont(); ++it) + { + if (amap.is_marked(*it, treated)) + unmark_cell(amap, *it, treated); + amap.mark(*it,mark); + } + + amap.negate_mark(mark); + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + CGAL_assertion( amap.is_whole_map_unmarked(treated) ); + + amap.free_mark(mark); + amap.free_mark(treated); + + CGAL_assertion(nbIncident != 0); + return nbIncident; +} + +} // namespace CGAL + +#endif // CGAL_COMBINATORIAL_MAP_BASIC_OPERATIONS_H // +// EOF // diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_constructors.h b/Combinatorial_map/include/CGAL/Combinatorial_map_constructors.h new file mode 100644 index 00000000000..c21ff9229fe --- /dev/null +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_constructors.h @@ -0,0 +1,167 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (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; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// 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) : Guillaume Damiand +// +#ifndef CGAL_COMBINATORIAL_MAP_CONSTRUCTORS_H +#define CGAL_COMBINATORIAL_MAP_CONSTRUCTORS_H 1 + +namespace CGAL { + +/** @file Combinatorial_map_constructors.h + * Basic creation operations for a combinatorial map. + * Create edge, triangle, quadrilateral, tetrahedron, hexahedron. + */ + +/** Create an edge. + * @param amap the used combinatorial map. + * @return a dart of the new edge. + */ +template < class Map > +typename Map::Dart_handle make_edge(Map& amap) +{ + typename Map::Dart_handle d1 = amap.create_dart(); + typename Map::Dart_handle d2 = amap.create_dart(); + amap.template basic_link_beta<2>(d1, d2); + return d1; +} + +/** Create a combinatorial polygon of length alg + * (a cycle of alg darts beta1 links together). + * @param amap the used combinatorial map. + * @return a new dart. + */ +template < class Map > +typename Map::Dart_handle make_combinatorial_polygon(Map& amap, + unsigned int alg) +{ + CGAL_assertion(alg>0); + + typename Map::Dart_handle start = amap.create_dart(); + typename Map::Dart_handle prev = start; + for ( unsigned int nb=1; nb(prev, cur); + prev=cur; + } + + amap.template basic_link_beta<1>(prev, start); + return start; +} + +/** Create a combinatorial tetrahedron from 4 triangles. + * @param amap the used combinatorial map. + * @param d1 a dart onto a first triangle. + * @param d2 a dart onto a second triangle. + * @param d3 a dart onto a third triangle. + * @param d4 a dart onto a fourth triangle. + * @return a new dart. + */ +template < class Map > +typename Map::Dart_handle +make_combinatorial_tetrahedron(Map& amap, + typename Map::Dart_handle d1, + typename Map::Dart_handle d2, + typename Map::Dart_handle d3, + typename Map::Dart_handle d4) +{ + amap.basic_link_beta(d1, d2, 2); + amap.basic_link_beta(d3, d2->beta(0), 2); + amap.basic_link_beta(d1->beta(1), d3->beta(0), 2); + amap.basic_link_beta(d4, d2->beta(1), 2); + amap.basic_link_beta(d4->beta(0), d3->beta(1), 2); + amap.basic_link_beta(d4->beta(1), d1->beta(0), 2); + + return d1; +} + +/** Create a new combinatorial tetrahedron. + * @param amap the used combinatorial map. + * @return a new dart. + */ +template < class Map > +typename Map::Dart_handle make_combinatorial_tetrahedron(Map& amap) +{ + typename Map::Dart_handle d1 = make_combinatorial_polygon(amap,3); + typename Map::Dart_handle d2 = make_combinatorial_polygon(amap,3); + typename Map::Dart_handle d3 = make_combinatorial_polygon(amap,3); + typename Map::Dart_handle d4 = make_combinatorial_polygon(amap,3); + + return make_combinatorial_tetrahedron(amap, d1, d2, d3, d4); +} + +/** Create a combinatorial hexahedron from 6 quadrilaterals. + * @param amap the used combinatorial map. + * @param d1 a dart onto a first quadrilateral. + * @param d2 a dart onto a second quadrilateral. + * @param d3 a dart onto a third quadrilateral. + * @param d4 a dart onto a fourth quadrilateral. + * @param d5 a dart onto a fifth quadrilateral. + * @param d6 a dart onto a sixth quadrilateral. + * @return a dart of the new cuboidal_cell. + */ +template < class Map > +typename Map::Dart_handle +make_combinatorial_hexahedron(Map& amap, + typename Map::Dart_handle d1, + typename Map::Dart_handle d2, + typename Map::Dart_handle d3, + typename Map::Dart_handle d4, + typename Map::Dart_handle d5, + typename Map::Dart_handle d6) +{ + amap.basic_link_beta(d1, d4->beta(1)->beta(1), 2); + amap.basic_link_beta(d1->beta(1), d6->beta(0) , 2); + amap.basic_link_beta(d1->beta(1)->beta(1), d2 , 2); + amap.basic_link_beta(d1->beta(0), d5 , 2); + + amap.basic_link_beta(d3, d2->beta(1)->beta(1), 2); + amap.basic_link_beta(d3->beta(1), d6->beta(1) , 2); + amap.basic_link_beta(d3->beta(1)->beta(1), d4 , 2); + amap.basic_link_beta(d3->beta(0), d5->beta(1)->beta(1), 2); + + amap.basic_link_beta(d6, d4->beta(1) , 2); + amap.basic_link_beta(d6->beta(1)->beta(1), d2->beta(1) , 2); + + amap.basic_link_beta(d5->beta(0), d4->beta(0) , 2); + amap.basic_link_beta(d5->beta(1), d2->beta(0) , 2); + + return d1; +} + +/** Create a new combinatorial hexahedron. + * @param amap the used combinatorial map. + * @return a new dart. + */ +template < class Map > +typename Map::Dart_handle make_combinatorial_hexahedron(Map& amap) +{ + typename Map::Dart_handle d1 = make_combinatorial_polygon(amap,4); + typename Map::Dart_handle d2 = make_combinatorial_polygon(amap,4); + typename Map::Dart_handle d3 = make_combinatorial_polygon(amap,4); + typename Map::Dart_handle d4 = make_combinatorial_polygon(amap,4); + typename Map::Dart_handle d5 = make_combinatorial_polygon(amap,4); + typename Map::Dart_handle d6 = make_combinatorial_polygon(amap,4); + + return make_combinatorial_hexahedron(amap, d1, d2, d3, d4, d5, d6); +} + +} // namespace CGAL + +#endif // CGAL_COMBINATORIAL_MAP_CONSTRUCTORS_H // +// EOF // diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_min_items.h b/Combinatorial_map/include/CGAL/Combinatorial_map_min_items.h new file mode 100644 index 00000000000..11a305a8f56 --- /dev/null +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_min_items.h @@ -0,0 +1,50 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (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; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// 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) : Guillaume Damiand +// +#ifndef CGAL_COMBINATORIAL_MAP_MIN_ITEMS_H +#define CGAL_COMBINATORIAL_MAP_MIN_ITEMS_H 1 + +#include + +namespace CGAL { + +/** @file Combinatorial_map_min_items.h + * Definition of min item class for dD combinatorial map. + */ + +/** Minimal items for dD combinatorial map. + * Combinatorial_map_min_items defines what is the minimal item + * class for a d-map It provides definitions for darts without attribute. + */ +template +struct Combinatorial_map_min_items +{ + /// Dart_wrapper defines the type of darts used, and enabled attributes. + template < class Refs > + struct Dart_wrapper + { + typedef CGAL::Dart< d, Refs > Dart; + typedef CGAL::cpp0x::tuple<> Attributes; + }; +}; + +} // namespace CGAL + +#endif // CGAL_COMBINATORIAL_MAP_MIN_ITEMS_H // +// EOF // diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_operations.h b/Combinatorial_map/include/CGAL/Combinatorial_map_operations.h new file mode 100644 index 00000000000..75185a1ae7f --- /dev/null +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_operations.h @@ -0,0 +1,927 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (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; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// 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) : Guillaume Damiand +// +#ifndef CGAL_COMBINATORIAL_MAP_OPERATIONS_H +#define CGAL_COMBINATORIAL_MAP_OPERATIONS_H 1 + +#include +#include +#include + +namespace CGAL { + + /** @file Combinatorial_map_operations.h + * Some operations to modify a combinatorial map. + */ + + /** Insert a vertex in the given 2-cell which is splitted in triangles, + * once for each inital edge of the facet. + * @param amap the used combinatorial map. + * @param adart a dart of the facet to triangulate. + * @return A dart incident to the new vertex. + */ + template < class Map > + typename Map::Dart_handle + insert_cell_0_in_cell_2(Map& amap, typename Map::Dart_handle adart) + { + CGAL_assertion(adart != NULL && adart!=Map::null_dart_handle); + + typename Map::Dart_handle first = adart, prev = NULL, cur = NULL; + typename Map::Dart_handle n1 = NULL, n2 = NULL; + + typename Map::Dart_handle nn1 = NULL, nn2 = NULL; + + // If the facet is open, we search the dart 0-free + while (!first->is_free(0) && first->beta(0) != adart) + first = first->beta(0); + + // Stack of couple of dart and dimension for which + // we must call on_split functor + std::stack > + tosplit; + + // Now we run through the facet + for (CGAL::CMap_dart_iterator_basic_of_orbit it(amap,first); + it.cont();) + { + cur = it; + ++it; + + if ( cur!=first ) + { + if ( amap.template degroup_attribute_of_dart<2, + typename Map::template Dart_of_involution_range<1> > + (first, cur) ) + tosplit.push(internal::Couple_dart_and_dim + + (first,cur,2)); + } + + if (!cur->is_free(0)) + { + n1 = amap.create_dart(); + amap.template link_beta<0>(cur, n1); + } + else n1 = NULL; + + if (!cur->is_free(1)) + { + n2 = amap.create_dart(); + amap.template link_beta<1>(cur, n2); + } + else n2 = NULL; + + if (n1 != NULL && n2 != NULL) + amap.template link_beta<0>(n1, n2); + + if (n1 != NULL && prev != NULL) + amap.link_beta(prev, n1, 2); + + for (unsigned int dim=3; dim<=Map::dimension; ++dim) + { + if ( !adart->is_free(dim) ) + { + if (n1!=NULL) + { + nn1=amap.create_dart(); + amap.template link_beta<1>(cur->beta(dim), nn1); + amap.link_beta(n1, nn1, dim); + } + else nn1=NULL; + + if (n2!=NULL) + { + nn2=amap.create_dart(); + amap.template link_beta<0>(cur->beta(dim), nn2); + amap.link_beta(n2, nn2, dim); + } + else nn2=NULL; + + if (nn1 != NULL && nn2 != NULL) + amap.template basic_link_beta<1>(nn1, nn2); + + if (nn1 != NULL && prev != NULL) + amap.link_beta(nn1, prev->beta(dim), 2); + } + } + + prev = n2; + } + + if (n2 != NULL) + { + amap.link_beta(first->beta(0), n2, 2); + for (unsigned int dim=3; dim<=Map::dimension; ++dim) + { + if ( !adart->is_free(dim) ) + { + amap.link_beta(first->beta(0)->beta(dim), nn2, 2); + } + } + } + + while ( !tosplit.empty() ) + { + internal::Couple_dart_and_dim c=tosplit.top(); + tosplit.pop(); + internal::Call_split_functor::run(c.d1, c.d2); + } + + return n1; + } + + /** Test if a i-cell can be removed. + * An i-cell can be removed if i==Map::dimension, + * or if there are at most two (i+1)-cell incident to it. + * @param adart a dart of the i-cell. + * @return true iff the i-cell can be removed. + */ + template < class Map, unsigned int i > + bool is_removable(const Map& amap, typename Map::Dart_const_handle adart) + { + CGAL_assertion(adart != NULL); + CGAL_assertion(0<=i && i<=Map::dimension); + + if ( i==Map::dimension ) return true; + if ( i==Map::dimension-1 ) return true; + + // TODO ? Optimisation for dim-2, and to not test all the darts of the cell ? + bool res = true; + for (CMap_dart_const_iterator_of_cell it(amap, adart); + res && it.cont(); ++it) + { + if (it->beta(i+2)->beta(i+1) != it->beta_inv(i+1)->beta(i+2) ) + res = false; + } + return res; + } + + /** Remove a i-cell, 0 + struct Remove_cell_functor + { + static size_t run(Map& amap, typename Map::Dart_handle adart) + { + CGAL_assertion ( 1<=i && i(amap, adart)) ); + + size_t res = 0; + + // 1) We group the two (i+1)-cells if they exist. + if (!adart->is_free(i+1)) + amap.template group_attribute(adart, adart->beta(i+1)); + + typename Map::Dart_handle d1, d2, other; + int mark = amap.get_new_mark(); + std::vector to_erase; + + // 2) We mark all the darts of the i-cell. + { + for ( CMap_dart_iterator_basic_of_cell it(amap,adart,mark); + it.cont(); ++it ) + { + to_erase.push_back(it); + amap.mark(it,mark); + ++res; + } + } + + // Stack of couple of dart for which we must call degroup_all_attributes + typedef std::pair + Dart_pair; + std::stack todegroup; + + // 3) We modify the darts of the cells incident to the removed i-cell + // when they are marked to remove. + typename std::vector::iterator it = + to_erase.begin(); + for (; it != to_erase.end(); ++it) + { amap.update_dart_of_all_attributes(*it, mark); } + + // 4) For each dart of the cell, we modify i-link of neighbors. + for ( it=to_erase.begin(); it != to_erase.end(); ++it) + { + d1 = (*it)->beta_inv(i); + while ( d1!=Map::null_dart_handle && amap.is_marked(d1, mark) ) + { + d1 = d1->beta(i+1)->beta_inv(i); + if (d1 == (*it)->beta_inv(i)) d1 = Map::null_dart_handle; + } + + d2 = (*it)->beta(i+1)->beta(i); + while ( d2!=Map::null_dart_handle && amap.is_marked(d2, mark) ) + { + d2 = d2->beta(i+1)->beta(i); + if ( d2==(*it)->beta(i+1)->beta(i) ) d2=Map::null_dart_handle; + } + + // TODO ? We can optimize by using map.basic_link_beta but we need to mark + // the second dart to not process another time... + if (d1 != Map::null_dart_handle) + { + if (d2 != Map::null_dart_handle) + { + d1->basic_link_beta(d2, i); + // Here special case for edge, TODO special method ? + if ( i==1 ) d2->basic_link_beta(d1, 0); + } + else + { + if ( !d1->is_free(i) ) + { + todegroup.push(Dart_pair(d1, d1->beta(i))); + d1->unlink_beta(i); + } + } + } + else if (d2 != Map::null_dart_handle) + { + if ( !d2->is_free(CGAL_BETAINV(i)) ) + { + todegroup.push(Dart_pair(d2, d2->beta_inv(i))); + d2->unlink_beta(CGAL_BETAINV(i)); + } + } + + if ((*it)->is_free(i+1) && !(*it)->is_free(i)) + { + d1 = (*it)->beta(i); + if ( !d1->is_free(CGAL_BETAINV(i)) ) + { + todegroup.push(Dart_pair(d1, d1->beta_inv(i))); + d1->unlink_beta(CGAL_BETAINV(i)); + } + } + } + + // 5) We degroup all the pair + while ( !todegroup.empty() ) + { + Dart_pair p=todegroup.top(); + todegroup.pop(); + amap.degroup_all_attributes(p.first,p.second); + } + + // 6) We remove all the darts of the cell. + for ( it=to_erase.begin(); it!=to_erase.end(); ++it ) + { amap.erase_dart(*it); } + + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + amap.free_mark(mark); + + // CGAL_postcondition(amap.is_valid()); + + return res; + } + }; + + /** Remove a d-cell, in a d-map (special case). + * @param amap the used combinatorial map. + * @param adart a dart of the volume to remove. + * @return the number of deleted darts. + */ + template + struct Remove_cell_functor + { + static size_t run(Map& amap, typename Map::Dart_handle adart) + { + CGAL_assertion( adart!=NULL ); + + std::vector to_erase; + int mark = amap.get_new_mark(); + size_t res = 0; + typename Map::Dart_handle other = NULL; + + // Stack of couple of dart for which we must call degroup_all_attributes + typedef std::pair + Dart_pair; + std::stack todegroup; + + // 1) We mark all the darts of the d-cell. + { + for (CMap_dart_iterator_basic_of_cell + it(amap,adart,mark); it.cont(); ++it) + { + to_erase.push_back(it); + amap.mark(it,mark); + ++res; + } + } + + // 2) We update the cells incident to the remove volume. + typename std::vector::iterator + it = to_erase.begin(); + for (; it != to_erase.end(); ++it) + { amap.update_dart_of_all_attributes(*it, mark); } + + // 3) We unlink all the darts of the volume for beta-d. + for ( it = to_erase.begin(); it != to_erase.end(); ++it ) + { + if ( !(*it)->is_free(Map::dimension) ) + { + todegroup.push(Dart_pair(*it, (*it)->beta(Map::dimension))); + amap.unlink_beta(*it,Map::dimension); + } + } + + // 4) We degroup all the pairs + while ( !todegroup.empty() ) + { + Dart_pair p=todegroup.top(); + todegroup.pop(); + amap.degroup_all_attributes(p.first,p.second); + } + + // 5) last, we remove all the darts of the d-cell. + for ( it = to_erase.begin(); it != to_erase.end(); ++it ) + { amap.erase_dart(*it); } + + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + amap.free_mark(mark); + + //CGAL_postcondition(amap.is_valid()); + + return res; + } + }; + + /** Remove a vertex, and merge eventually both incident edges. + * @param amap the used combinatorial map. + * @param adart a dart of the vertex to remove. + * @return the number of deleted darts. + */ + template + struct Remove_cell_functor + { + static size_t run(Map& amap, typename Map::Dart_handle adart) + { + CGAL_assertion( (is_removable(amap,adart)) ); + + size_t res = 0; + + // Stack of couple of dart for which we must call degroup_all_attributes + typedef std::pair + Dart_pair; + std::stack todegroup; + + // 1) We group the two edges if they exist. + if (!adart->is_free(0)) + amap.template group_attribute<1>(adart, adart->beta(0)); + + typename Map::Dart_handle d1, d2; + int mark = amap.get_new_mark(); + std::vector to_erase; + + // 2) We mark all the darts of the vertex. + { + for ( CMap_dart_iterator_basic_of_cell it(amap,adart,mark); + it.cont(); ++it ) + { + to_erase.push_back(it); + amap.mark(it,mark); + ++res; + } + } + + // 3) We modify the darts of the cells incident to the vertex + // when they are marked to remove. + typename std::vector::iterator + it = to_erase.begin(); + for (; it != to_erase.end(); ++it) + { amap.update_dart_of_all_attributes(*it, mark); } + + // 4) For each dart of the cell, we modify link of neighbors. + for ( it=to_erase.begin(); it!=to_erase.end(); ++it ) + { + if ( !(*it)->is_free(0) && (*it)->beta(0)!=(*it) ) + { + amap.template basic_link_beta<1>((*it)->beta(0), (*it)->beta(1)); + + for ( unsigned int j=2; j<=Map::dimension; ++j ) + { + if ( !(*it)->is_free(j) ) + ((*it)->beta(0))->basic_link_beta((*it)->beta(j),j); + } + } + else + { + for ( unsigned int j=1; j<=Map::dimension; ++j ) + { + if (!(*it)->is_free(j)) + { + d1 = (*it)->beta(j); + if ( !d1->is_free(CGAL_BETAINV(j)) ) + { + todegroup.push(Dart_pair(d1, d1->beta_inv(j))); + d1->unlink_beta(CGAL_BETAINV(j)); + } + } + } + } + } + + // 5) We degroup all the pairs + while ( !todegroup.empty() ) + { + Dart_pair p=todegroup.top(); + todegroup.pop(); + amap.degroup_all_attributes(p.first,p.second); + } + + // 6) We remove all the darts of the cell. + for (it = to_erase.begin(); it != to_erase.end(); ++it) + { amap.erase_dart(*it); } + + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + amap.free_mark(mark); + + // CGAL_postcondition( amap.is_valid() ); + + return res; + } + }; + + /** Remove a i-cell, 0<=i<=dimension. + * @param amap the used combinatorial map. + * @param adart a dart of the i-cell to remove. + * @return the number of deleted darts. + */ + template < class Map, unsigned int i > + size_t remove_cell(Map& amap, typename Map::Dart_handle adart) + { return Remove_cell_functor::run(amap,adart); } + + /** Test if an edge can be inserted onto a 2-cell between two given darts. + * @param amap the used combinatorial map. + * @param adart1 a first dart. + * @param adart2 a second dart. + * @return true iff an edge can be inserted between adart1 and adart2. + */ + template < class Map > + bool is_insertable_cell_1_in_cell_2(const Map& amap, + typename Map::Dart_const_handle adart1, + typename Map::Dart_const_handle adart2) + { + CGAL_assertion(adart1 != NULL && adart2 != NULL); + if ( adart1==adart2 ) return false; + for ( CMap_dart_const_iterator_of_orbit it(amap,adart1); + it.cont(); ++it ) + { + if ( it==adart2 ) return true; + } + return false; + } + + /** Test if a 2-cell can be inserted onto a given 3-cell along + * a path of edges. + * @param amap the used combinatorial map. + * @param afirst iterator on the begining of the path. + * @param alast iterator on the end of the path. + * @return true iff a 2-cell can be inserted along the path. + */ + template + bool is_insertable_cell_2_in_cell_3(const Map& amap, + InputIterator afirst, + InputIterator alast) + { + CGAL_assertion( Map::dimension>= 3 ); + + // The path must have at least one dart. + if (afirst==alast) return false; + typename Map::Dart_const_handle prec = NULL; + typename Map::Dart_const_handle od = NULL; + + for (InputIterator it(afirst); it!=alast; ++it) + { + // The path must contain only non empty darts. + if (*it == NULL || *it==Map::null_dart_handle) return false; + + // Two consecutive darts of the path must belong to two edges + // incident to the same vertex of the same volume. + if (prec != NULL) + { + od = prec->other_extremity(); + if ( od==Map::null_dart_handle ) return false; + + // of and *it must belong to the same vertex of the same volume + if ( !belong_to_same_cell(amap, od, *it) ) + return false; + } + prec = *it; + } + + // The path must be closed. + od = prec->other_extremity(); + if ( od==Map::null_dart_handle ) return false; + + if (!belong_to_same_cell(amap, od, *afirst)) + return false; + + return true; + } + + /** Insert a vertex in a given edge. + * @param amap the used combinatorial map. + * @param adart a dart of the edge (!=NULL && !=null_dart_handle). + * @return a dart of the new vertex. + */ + template + typename Map::Dart_handle + insert_cell_0_in_cell_1(Map& amap, typename Map::Dart_handle adart) + { + CGAL_assertion(adart != NULL && adart!=Map::null_dart_handle); + + typename Map::Dart_handle d1, d2; + int mark = amap.get_new_mark(); + + std::vector vect; + { + for (typename Map::template Dart_of_cell_range<1>::iterator it= + amap.template darts_of_cell<1>(adart).begin(); + it != amap.template darts_of_cell<1>(adart).end(); ++it) + vect.push_back(it); + } + + // 3) For each dart of the cell, we modify link of neighbors. + typename std::vector::iterator it = vect.begin(); + for (; it != vect.end(); ++it) + { + d1 = amap.create_dart(); + + if (!(*it)->is_free(1)) + { amap.template basic_link_beta<1>(d1, (*it)->beta(1)); } + + amap.template link_beta<1>(*it, d1); + + for ( unsigned int dim = 2; dim<=Map::dimension; ++dim ) + { + if (!(*it)->is_free(dim) && amap.is_marked((*it)->beta(dim), mark)) + { + amap.basic_link_beta((*it)->beta(dim), d1, dim); + amap.basic_link_beta(*it, (*it)->beta(dim)->beta(1), dim); + } + } + + amap.mark(*it, mark); + } + + for (it = vect.begin(); it != vect.end(); ++it) + { amap.unmark(*it, mark); } + + amap.free_mark(mark); + + amap.template degroup_attribute<1>(adart, adart->beta(1)); + + // CGAL_postcondition(amap.is_valid()); + + return adart->beta(1); + } + + /** Insert a dangling edge in a 2-cell between given by a dart. + * @param amap the used combinatorial map. + * @param adart1 a first dart of the facet (!=NULL && !=null_dart_handle). + * @return a dart of the new edge, not incident to the vertex of adart1. + */ + template + typename Map::Dart_handle + insert_dangling_cell_1_in_cell_2(Map& amap, typename Map::Dart_handle adart1) + { + CGAL_assertion(adart1!=NULL && adart1!=Map::null_dart_handle); + + int mark1 = amap.get_new_mark(); + std::vector to_unmark; + { + for ( CMap_dart_iterator_basic_of_cell it(amap,adart1,mark1); + it.cont(); ++it ) + { + to_unmark.push_back(it); + amap.mark(it,mark1); + } + } + + typename Map::Dart_handle d1 = NULL; + typename Map::Dart_handle d2 = NULL; + unsigned int s1 = 0; + + int treated = amap.get_new_mark(); + + CGAL::CMap_dart_iterator_of_involution it1(amap,adart1); + + for ( ; it1.cont(); ++it1) + { + d1 = amap.create_dart(); + d2 = amap.create_dart(); + + if ( amap.is_marked(it1, mark1) ) s1 = 0; + else s1 = 1; + + if ( !it1->is_free(s1) ) + { + if ( s1==0 ) amap.template link_beta<1>(it1->beta(0), d2); + else amap.template link_beta<0>(it1->beta(1), d2); + } + + if (s1==0) + { + amap.template link_beta<0>(it1, d1); + amap.template basic_link_beta<0>(d1,d2); + } + else + { + amap.template link_beta<1>(it1, d1); + amap.template basic_link_beta<1>(d1,d2); + } + + amap.link_beta(d1, d2, 2); + + for ( unsigned int dim=3; dim<=Map::dimension; ++dim) + { + if ( !it1->is_free(dim) && + amap.is_marked(it1->beta(dim), treated) ) + { + amap.basic_link_beta(it1->beta(dim)->beta_inv(s1), d1, dim); + amap.basic_link_beta(it1->beta(dim)->beta_inv(s1)->beta(2), + d2, dim); + } + } + + amap.mark(it1,treated); + } + + // amap.template degroup_attribute<1>(adart1, adart1->beta(0)); + // amap.template degroup_attribute<2>(d1, d2); + + for ( it1.rewind(); it1.cont(); ++it1 ) + { + amap.unmark(it1,treated); + } + CGAL_assertion( amap.is_whole_map_unmarked(treated) ); + amap.free_mark(treated); + + typename std::vector::iterator it = + to_unmark.begin(); + for (; it != to_unmark.end(); ++it) + { amap.unmark(*it, mark1); } + CGAL_assertion( amap.is_whole_map_unmarked(mark1) ); + amap.free_mark(mark1); + + // CGAL_postcondition(amap.is_valid()); + return adart1->beta(0); + } + + /** Insert an edge in a 2-cell between two given darts. + * @param amap the used combinatorial map. + * @param adart1 a first dart of the facet (!=NULL && !=null_dart_handle). + * @param adart2 a second dart of the facet. If NULL insert a dangling edge. + * @return a dart of the new edge, and not incident to the + * same vertex than adart1. + */ + template + typename CMap::Dart_handle + insert_cell_1_in_cell_2(CMap& amap, + typename CMap::Dart_handle adart1, + typename CMap::Dart_handle adart2) + { + if ( adart2==NULL ) return insert_dangling_cell_1_in_cell_2(amap,adart1); + + CGAL_assertion(is_insertable_cell_1_in_cell_2(amap, adart1, adart2)); + + int m1 = amap.get_new_mark(); + CMap_dart_iterator_basic_of_involution + it1 = CMap_dart_iterator_basic_of_involution(amap, adart1, m1); + int m2 = amap.get_new_mark(); + CMap_dart_iterator_basic_of_involution + it2 = CMap_dart_iterator_basic_of_involution(amap, adart2, m2); + + int mark1 = amap.get_new_mark(); + std::vector to_unmark; + { + for ( CMap_dart_iterator_basic_of_cell it(amap,adart1,mark1); + it.cont(); ++it ) + { + to_unmark.push_back(it); + amap.mark(it,mark1); + } + } + + typename CMap::Dart_handle d1 = NULL; + typename CMap::Dart_handle d2 = NULL; + unsigned int s1 = 0; + + int treated = amap.get_new_mark(); + + for ( ; it1.cont(); ++it1, ++it2) + { + CGAL_assertion (it2.cont() ); + d1 = amap.create_dart(); + d2 = amap.create_dart(); + + if ( amap.is_marked(it1, mark1) ) s1 = 0; + else s1 = 1; + + if ( !it1->is_free(s1) ) + { + if ( s1==0 ) amap.template basic_link_beta<1>(it1->beta(0), d2); + else amap.template link_beta<0>(it1->beta(1), d2); + } + + if ( !it2->is_free(s1) ) + { + if ( s1==0 ) amap.template basic_link_beta<1>(it2->beta(0), d1); + else amap.template link_beta<0>(it2->beta(1), d1); + } + + if ( s1==0 ) + { + amap.template link_beta<0>(it1, d1); + amap.template link_beta<0>(it2, d2); + } + else + { + amap.template basic_link_beta<1>(it1, d1); + amap.template basic_link_beta<1>(it2, d2); + } + amap.link_beta(d2, d1, 2); + + for ( unsigned int dim=3; dim<=CMap::dimension; ++dim) + { + if ( !it1->is_free(dim) && + amap.is_marked(it1->beta(dim), treated) ) + { + amap.basic_link_beta(it1->beta(dim)->beta_inv(s1), d1, dim); + amap.basic_link_beta(it1->beta(dim)->beta_inv(s1)->beta(2), + d2, dim); + } + } + + amap.mark(it1,treated); + } + + // amap.template degroup_attribute<1>(adart1, adart1->beta(0)); + amap.template degroup_attribute<2>(d1, d2); + + amap.negate_mark(m1); + amap.negate_mark(m2); + it1.rewind(); it2.rewind(); + for ( ; it1.cont(); ++it1, ++it2) + { + amap.mark(it1,m1); + amap.unmark(it1,treated); + amap.mark(it2,m2); + } + amap.negate_mark(m1); + amap.negate_mark(m2); + CGAL_assertion( amap.is_whole_map_unmarked(m1) ); + CGAL_assertion( amap.is_whole_map_unmarked(m2) ); + CGAL_assertion( amap.is_whole_map_unmarked(treated) ); + amap.free_mark(m1); + amap.free_mark(m2); + amap.free_mark(treated); + + typename std::vector::iterator it = + to_unmark.begin(); + for (; it != to_unmark.end(); ++it) + { amap.unmark(*it, mark1); } + CGAL_assertion( amap.is_whole_map_unmarked(mark1) ); + amap.free_mark(mark1); + + // CGAL_postcondition(amap.is_valid()); + return adart1->beta(0); + } + + /** Insert a 2-cell in a given 3-cell along a path of darts. + * @param amap the used combinatorial map. + * @param afirst iterator on the begining of the path. + * @param alast iterator on the end of the path. + * @return a dart of the new 2-cell. + */ + template + typename Map::Dart_handle + insert_cell_2_in_cell_3(Map& amap, InputIterator afirst, InputIterator alast) + { + CGAL_assertion(is_insertable_cell_2_in_cell_3(amap,afirst,alast)); + + typename Map::Dart_handle prec = NULL, d = NULL, dd = NULL, first = NULL; + bool withBeta3 = false; + + { + for (InputIterator it(afirst); it!=alast; ++it) + { + if (!(*it)->is_free(2)) withBeta3 = true; + } + } + + { + for (InputIterator it(afirst); it!=alast; ++it) + { + d = amap.create_dart(); + if (withBeta3) + { + dd = amap.create_dart(); + amap.basic_link_beta(d, dd, 3); + } + + if (prec != NULL) + { + amap.template link_beta<0>(prec, d); + if (withBeta3) amap.template link_beta<1>(prec->beta(3), dd); + } + else first = d; + + if (!(*it)->is_free(2)) + amap.link_beta((*it)->beta(2), dd, 2); + + amap.link_beta(*it, d, 2); + + prec = d; + } + } + + amap.template link_beta<0>(prec, first); + if (withBeta3) + { + amap.template link_beta<1>(prec->beta(3), first->beta(3)); + } + + // Make copies of the new facet for dimension >=4 + for ( unsigned int dim=4; dim<=Map::dimension; ++dim ) + { + if ( !first->is_free(dim) ) + { + typename Map::Dart_handle first2 = NULL; + prec = NULL; + for ( CMap_dart_iterator_of_orbit it(amap, first); + it.cont(); ++it ) + { + d = amap.create_dart(); + amap.link_beta(it->beta(2),d,dim); + if ( withBeta3 ) + { + dd = amap.create_dart(); + amap.link_beta(it->beta(2)->beta(3),dd,dim); + amap.basic_link_beta(d, dd, 3); + } + if ( prec!=NULL ) + { + amap.template link_beta<0>(prec,d); + if ( withBeta3 ) + { + amap.template link_beta<1>(prec->beta(3),dd); + } + } + else first2 = prec; + + for ( unsigned dim2=2; dim2<=Map::dimension; ++dim2 ) + { + if ( dim2+1!=dim && dim2!=dim && dim2!=dim+1 ) + { + if ( !it->is_free(dim2) && + it->beta(dim2)->is_free(dim) ) + amap.basic_link_beta(it->beta(dim2)->beta(dim), d, dim2); + if ( withBeta3 && !it->beta(3)->is_free(dim2) && + it->beta(3)->beta(dim2)->is_free(dim) ) + amap.basic_link_beta(it->beta(3)->beta(dim2)->beta(dim), + dd, dim2); + } + } + prec = d; + } + amap.template link_beta<0>( prec, first2 ); + if ( withBeta3 ) + { + amap.template link_beta<1>( prec->beta(3), first2->beta(3) ); + } + } + } + + // Degroup the attributes + if ( withBeta3 ) + amap.template degroup_attribute<3>( first, first->beta(3) ); + + // CGAL_postcondition(amap.is_valid()); + return first; + } +} // namespace CGAL + +#endif // CGAL_COMBINATORIAL_MAP_OPERATIONS_H // +// EOF // diff --git a/Combinatorial_map/include/CGAL/Dart.h b/Combinatorial_map/include/CGAL/Dart.h new file mode 100644 index 00000000000..19fdcfd4006 --- /dev/null +++ b/Combinatorial_map/include/CGAL/Dart.h @@ -0,0 +1,314 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (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; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// 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) : Guillaume Damiand +// +#ifndef CGAL_DART_H +#define CGAL_DART_H 1 + +#include +#include +#include + +// Temporary patch since CGAL_static_assertion_msg is not yet available. +#ifndef CGAL_static_assertion + +# define CGAL_static_assertion(EX) \ + BOOST_STATIC_ASSERT(EX) +# define CGAL_static_assertion_msg(EX,MSG) \ + BOOST_STATIC_ASSERT(EX) + +#endif +// end of temporary patch: to remove asap. + + +namespace CGAL { + +/** @file Dart.h + * Definition of nD dart. + */ + + template < unsigned int d_, class Refs, + class Items_, class Alloc_ > + class Combinatorial_map_base; + + template + struct Remove_cell_functor; + + namespace internal { + template + struct basic_link_beta_functor; + + template + struct link_beta_functor; + } + +#define CGAL_BETAINV(i) (i>1?i:(i==1?0:1)) + +/** Definition of nD dart. + * The Dart class describes an nD dart (basic element of a + * combinatorial map). A dart is composed with handle towards its neighbors, + * a bitset containing Boolean marks, and handle towards enabled attributes. + * n is the dimension of the space (2 for 2D, 3 for 3D...) + * Refs the ref class + */ +template +struct Dart +{ + template < unsigned int d_, class Refs_, + class Items_, class Alloc_ > + friend class Combinatorial_map_base; + + template + friend class Compact_container; + + template + friend struct Remove_cell_functor; + + template + friend struct internal::basic_link_beta_functor; + + template + friend struct internal::link_beta_functor; + +public: + typedef Dart Self; + typedef typename Refs::Dart_handle Dart_handle; + typedef typename Refs::size_type size_type; + typedef typename Refs::Dart_const_handle Dart_const_handle; + typedef typename Refs::Helper Helper; + /// Typedef for attributes + template + struct Attribute_handle: public Refs::template Attribute_handle + {}; + template + struct Attribute_const_handle: public Refs::template Attribute_const_handle + {}; + + /// The number of used marks. + static const size_type NB_MARKS = Refs::NB_MARKS; + + /// The dimension of the combinatorial map. + static const unsigned int dimension = d; + + /** Return if this dart is free for adimension. + * @param i the dimension. + * @return true iff the dart is linked with NULL for \em adimension. + */ + bool is_free(unsigned int i) const + { + CGAL_assertion(i <= dimension); + return mbeta[i] == Refs::null_dart_handle; + } + + /** Return the highest dimension for which the dart is not free. + * @return the dimension d such that the dart is not d-free but k-free for + * all k>d. -1 if the dart is free for all d in {0..n} + */ + int highest_nonfree_dimension() const + { + for (int i=(int)dimension; i>=0; --i) + { if ( !is_free(i) ) return i; } + return -1; + } + + /** Return the beta of this dart for a given dimension. + * @param i the dimension. + * @return beta(\em i). + */ + Dart_handle beta(unsigned int i) + { + CGAL_assertion(i <= dimension); + return mbeta[i]; + } + Dart_const_handle beta(unsigned int i) const + { + CGAL_assertion(i <= dimension); + return mbeta[i]; + } + + /** Return the beta inverse of this dart for a given dimension. + * @param i the dimension. + * @return beta^{-1}(\em i). + */ + Dart_handle beta_inv(unsigned int i) + { return beta(CGAL_BETAINV(i)); } + Dart_const_handle beta_inv(unsigned int i) const + { return beta(CGAL_BETAINV(i)); } + + /** Return a dart belonging to the same edge and to the second vertex + * of the current edge (NULL if such a dart does not exist). + * @return An handle to the opposite dart. + */ + Dart_handle opposite() + { + for (unsigned int i = 2; i <= dimension; ++i) + if (!is_free(i)) return beta(i); + return NULL; + } + Dart_const_handle opposite() const + { + for (unsigned int i = 2; i <= dimension; ++i) + if (!is_free(i)) return beta(i); + return NULL; + } + + /** Return a dart incident to the other extremity of the current edge, + * but contrary to opposite, non necessary to the same edge + * (NULL if such a dart does not exist). + * @return An handle to the opposite dart. + */ + Dart_handle other_extremity() + { + for (unsigned int i = 1; i <= dimension; ++i) + if (!is_free(i)) return beta(i); + return NULL; + } + Dart_const_handle other_extremity() const + { + for (unsigned int i = 1; i <= dimension; ++i) + if (!is_free(i)) return beta(i); + return NULL; + } + + /// @return a handle on the i-attribute + template + typename Attribute_handle::type attribute() + { + CGAL_static_assertion_msg(Helper::template Dimension_index::value>=0, + "attribute called but i-attributes are disabled."); + return CGAL::cpp0x::get::value> + (mattribute_handles); + } + template + typename Attribute_const_handle::type attribute() const + { + CGAL_static_assertion_msg(Helper::template Dimension_index::value>=0, + "attribute called but i-attributes are disabled."); + return CGAL::cpp0x::get::value> + (mattribute_handles); + } + +protected: + /** Default constructor: initialise marks and beta of this dart. + * @param amarks the marks. + */ + Dart(const std::bitset& amarks) : mmarks(amarks) + { + for (unsigned int i = 0; i <= dimension; ++i) + mbeta[i] = Refs::null_dart_handle; + + Helper::template Foreach_enabled_attributes:: + run(this); + } + + /** Return the mark value of a given mark number. + * @param amark the mark number. + * @return the value for this number. + */ + bool get_mark(int amark) const + { + CGAL_assertion(amark>=0 && (size_type)amark=0 && (size_type)amark get_marks() const + { return mmarks; } + + /** Set simultaneously all the marks of this dart to a given value. + * @param amarks the value of the marks. + */ + void set_marks(const std::bitset& amarks) const + { mmarks = amarks; } + + /** Link this dart with a given dart for a given dimension. + * @param adart the dart to link with. + * @param i the dimension. + */ + void basic_link_beta(Dart_handle adart, unsigned int i) + { + CGAL_assertion(i <= dimension); + CGAL_assertion(this!=&*Refs::null_dart_handle); + mbeta[i] = adart; + } + + /** Unlink this dart for a given dimension. + * @param i the dimension. + */ + void unlink_beta(unsigned int i) + { + CGAL_assertion(i <= dimension); + mbeta[i] = Refs::null_dart_handle; + } + + /// @return a handle on the i th attribute + template + void set_attribute( typename Attribute_handle::type & ahandle ) + { + CGAL_static_assertion_msg(Helper::template Dimension_index::value>=0, + "set_attribute called but i-attributes are disabled."); + CGAL::cpp0x::get::value> + (mattribute_handles) = ahandle; + if (ahandle!=NULL) ahandle->inc_nb_refs(); + } + +protected: + /// Functor used to initialize all attributes to NULL. + struct Init_attribute_functor + { + template + static void run(Self* adart) + { + // TODO BUG EN 1 SEULE LIGNE ? + typename Attribute_handle::type h = NULL; + adart->template set_attribute (h); } + }; + +public: + void * for_compact_container() const + { return mbeta[0].for_compact_container(); } + void * & for_compact_container() + { return mbeta[0].for_compact_container(); } + +protected: + /// Beta for each dimension +1 (from 0 to dimension). + Dart_handle mbeta[dimension+1]; + + /// Attributes enabled + typename Helper::Attribute_handles mattribute_handles; + + /// Values of Boolean marks. + mutable std::bitset mmarks; +}; + +} // namespace CGAL + +#endif // CGAL_DART_H // +// EOF // diff --git a/Combinatorial_map/include/CGAL/Dart_const_iterators.h b/Combinatorial_map/include/CGAL/Dart_const_iterators.h new file mode 100644 index 00000000000..37e5d4f66a7 --- /dev/null +++ b/Combinatorial_map/include/CGAL/Dart_const_iterators.h @@ -0,0 +1,273 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (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; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// 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) : Guillaume Damiand +// +#ifndef CGAL_DART_CONST_ITERATORS_HH +#define CGAL_DART_CONST_ITERATORS_HH 1 + +#include + +namespace CGAL { + + /** @file Dart_const_iterators.h + * Definition of dart const iterators. There are 8 iterators: + * - CMap_dart_const_iterator_basic_of_orbit + * - CMap_dart_const_iterator_basic_of_cell + * - CMap_dart_const_iterator_of_orbit + * - CMap_dart_const_iterator_of_cell + * - CMap_dart_const_iterator_basic_of_involution + * - CMap_dart_const_iterator_of_involution + * - CMap_dart_const_iterator_basic_of_involution_inv + * - CMap_dart_const_iterator_of_involution_inv + */ + //**************************************************************************** + #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template + class CMap_dart_const_iterator_basic_of_orbit: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_const_iterator_basic_of_orbit Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Map_::Dart_const_handle Dart_const_handle; + + /// Main constructor. + CMap_dart_const_iterator_basic_of_orbit(const Map_& amap, + Dart_const_handle adart): + Base(amap,adart) + {} + /// Main constructor. + CMap_dart_const_iterator_basic_of_orbit(const Map_& amap, + Dart_const_handle adart, + int amark): + Base(amap,adart,amark) + {} + }; + //**************************************************************************** + template + class CMap_dart_const_iterator_of_orbit: + public CMap_dart_iterator_of_orbit_generic + { + public: + typedef CMap_dart_const_iterator_of_orbit Self; + typedef CMap_dart_iterator_of_orbit_generic Base; + + typedef typename Map_::Dart_const_handle Dart_const_handle; + + /// Main constructor. + CMap_dart_const_iterator_of_orbit(const Map_& amap, + Dart_const_handle adart): + Base(amap,adart) + {} + /// Constructor from non const version. + CMap_dart_const_iterator_of_orbit + (const CMap_dart_iterator_of_orbit& it): + Base(*const_cast(it.get_combinatorial_map()), + it.get_first_dart()) + {} + }; + #else + //**************************************************************************** + template + class CMap_dart_const_iterator_basic_of_orbit: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_const_iterator_basic_of_orbit Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Map_::Dart_const_handle Dart_const_handle; + + /// Main constructor. + CMap_dart_const_iterator_basic_of_orbit(const Map_& amap, + Dart_const_handle adart): + Base(amap,adart) + {} + /// Main constructor. + CMap_dart_const_iterator_basic_of_orbit(const Map_& amap, + Dart_const_handle adart, + int amark): + Base(amap,adart,amark) + {} + }; + //**************************************************************************** + template + class CMap_dart_const_iterator_of_orbit: + public CMap_dart_iterator_of_orbit_generic + { + public: + typedef CMap_dart_const_iterator_of_orbit Self; + typedef CMap_dart_iterator_of_orbit_generic Base; + + typedef typename Map_::Dart_const_handle Dart_const_handle; + + /// Main constructor. + CMap_dart_const_iterator_of_orbit(const Map_& amap, + Dart_const_handle adart): + Base(amap,adart) + {} + /// Constructor from non const version. + CMap_dart_const_iterator_of_orbit + (const CMap_dart_iterator_of_orbit& it): + Base(*const_cast(it.get_combinatorial_map()), + it.get_first_dart()) + {} + }; + #endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + //**************************************************************************** + template + class CMap_dart_const_iterator_basic_of_cell: + public CMap_dart_iterator_basic_of_cell + { + public: + typedef CMap_dart_iterator_basic_of_cell Base; + typedef typename Map_::Dart_const_handle Dart_const_handle; + + /* Main constructor. */ + CMap_dart_const_iterator_basic_of_cell(const Map_& amap, + Dart_const_handle adart, int amark): + Base(amap,adart,amark) + {} + /// Constructor from non const version. + CMap_dart_const_iterator_basic_of_cell + (const CMap_dart_iterator_basic_of_cell& it): + Base(*const_cast(it.get_combinatorial_map()), + it.get_first_dart()) + {} + }; + //**************************************************************************** + template + class CMap_dart_const_iterator_of_cell: + public CMap_dart_iterator_of_cell + { + public: + typedef CMap_dart_iterator_of_cell Base; + typedef typename Map_::Dart_const_handle Dart_const_handle; + + /* Main constructor. */ + CMap_dart_const_iterator_of_cell(const Map_& amap, + Dart_const_handle adart): + Base(amap,adart) + {} + /// Constructor from non const version. + CMap_dart_const_iterator_of_cell + (const CMap_dart_iterator_of_cell& it): + Base(*const_cast(it.get_combinatorial_map()), + it.get_first_dart()) + {} + }; + //**************************************************************************** + template + class CMap_dart_const_iterator_basic_of_involution: + public CMap_dart_iterator_basic_of_involution + { + public: + typedef CMap_dart_iterator_basic_of_involution Base; + typedef typename Map_::Dart_const_handle Dart_const_handle; + + /* Main constructor. */ + CMap_dart_const_iterator_basic_of_involution(const Map_& amap, + Dart_const_handle adart, + int amark): + Base(amap,adart,amark) + {} + /// Constructor from non const version. + CMap_dart_const_iterator_basic_of_involution + (const CMap_dart_iterator_basic_of_involution& it): + Base(*const_cast(it.get_combinatorial_map()), + it.get_first_dart(), it.mmark_number) + {} + }; + //**************************************************************************** + template + class CMap_dart_const_iterator_of_involution: + public CMap_dart_iterator_of_involution + { + public: + typedef CMap_dart_iterator_of_involution Base; + typedef typename Map_::Dart_const_handle Dart_const_handle; + + /* Main constructor. */ + CMap_dart_const_iterator_of_involution(const Map_& amap, + Dart_const_handle adart): + Base(amap,adart) + {} + /// Constructor from non const version. + CMap_dart_const_iterator_of_involution + (const CMap_dart_iterator_of_involution& it): + Base(*const_cast(it.get_combinatorial_map()), + it.get_first_dart()) + {} + }; + //**************************************************************************** + template + class CMap_dart_const_iterator_basic_of_involution_inv: + public CMap_dart_iterator_basic_of_involution_inv + { + public: + typedef CMap_dart_iterator_basic_of_involution_inv Base; + typedef typename Map_::Dart_const_handle Dart_const_handle; + + /* Main constructor. */ + CMap_dart_const_iterator_basic_of_involution_inv(const Map_& amap, + Dart_const_handle adart, + int amark): + Base(amap,adart,amark) + {} + /// Constructor from non const version. + CMap_dart_const_iterator_basic_of_involution_inv + (const CMap_dart_iterator_basic_of_involution_inv& it): + Base(*const_cast(it.get_combinatorial_map()), + it.get_first_dart(), it.mmark_number) + {} + }; + //**************************************************************************** + template + class CMap_dart_const_iterator_of_involution_inv: + public CMap_dart_iterator_of_involution_inv + { + public: + typedef CMap_dart_iterator_of_involution_inv Base; + typedef typename Map_::Dart_const_handle Dart_const_handle; + + /* Main constructor. */ + CMap_dart_const_iterator_of_involution_inv(const Map_& amap, + Dart_const_handle adart): + Base(amap,adart) + {} + /// Constructor from non const version. + CMap_dart_const_iterator_of_involution_inv + (const CMap_dart_iterator_of_involution_inv& it): + Base(*const_cast(it.get_combinatorial_map()), + it.get_first_dart()) + {} + }; + //**************************************************************************** +} // namespace CGAL +//****************************************************************************** +#endif // CGAL_DART_CONST_ITERATORS_HH +//****************************************************************************** diff --git a/Combinatorial_map/include/CGAL/Dart_iterators.h b/Combinatorial_map/include/CGAL/Dart_iterators.h new file mode 100644 index 00000000000..e0200fb45c6 --- /dev/null +++ b/Combinatorial_map/include/CGAL/Dart_iterators.h @@ -0,0 +1,2920 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (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; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// 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) : Guillaume Damiand +// +#ifndef CGAL_DART_ITERATORS_HH +#define CGAL_DART_ITERATORS_HH 1 + +#include + +namespace CGAL { + + /** @file Dart_iterators.h + * Definition of dart iterators. There are 9 iterators: + * - CMap_dart_iterator_basic_of_orbit + * - CMap_dart_iterator_basic_of_cell + * - CMap_dart_iterator_basic_of_all + * - CMap_dart_iterator_of_orbit + * - CMap_dart_iterator_of_cell + * - CMap_dart_iterator_basic_of_involution + * - CMap_dart_iterator_of_involution + * - CMap_dart_iterator_basic_of_involution_inv + * - CMap_dart_iterator_of_involution_inv + * but many specializations to optimize specific cases. + * + */ + //**************************************************************************** + /// OperationState: type to keep the last operation used by the previous ++. + typedef char OperationState; + + /// Enum of all the possible operations used by the ++ operator. + enum + { + OP_NONE = -1, ///< Beginning of the iterator (there is not yet operator++). + OP_BETAI, ///< Previous op was the first beta. + OP_BETAI_INV, ///< Previous op was the inverse of the first beta. + OP_BETAJ, ///< Previous op was the second beta. + OP_BETAK, ///< Previous op was the third beta. + OP_BETA0I, ///< Previous op was beta0 o the first beta. + OP_BETAI1, ///< Previous op was the first beta o beta1. + OP_BETAIJ, ///< Previous op was the composition of two beta. + OP_BETAJI, ///< Previous op was the composition of two beta. + OP_BETA21, ///< Previous op was beta21. + OP_JUMP, ///< Previous op was a jump . + OP_POP, ///< Previous op pop a dart from a stack or a queue. + OP_END ///< Previous op go out of the iterator. + }; + //**************************************************************************** + //**************************************************************************** + /** Generic class of iterator onto darts. + * Class CMap_dart_iterator is a pure virtual generic iterator. This + * class defines what is an iterator. All the iterator classes inherit + * from this class. + */ + template < typename Map_,bool Const=false > + class CMap_dart_iterator: + public internal::CC_iterator + { + public: + typedef CMap_dart_iterator Self; + typedef internal::CC_iterator Base; + + typedef Base Dart_handle; + typedef typename boost::mpl::if_c< Const, const Map_, + Map_>::type Map; + + typedef std::input_iterator_tag iterator_category; + typedef typename Base::value_type value_type; + typedef typename Base::difference_type difference_type; + typedef typename Base::pointer pointer; + typedef typename Base::reference reference; + + public: + /// Main constructor. + CMap_dart_iterator(Map& amap, Dart_handle adart): + Base(adart), + mmap(&amap), + mfirst_dart(adart), + mprev_op(OP_NONE) + {} + + /// == operator. + bool operator==(const Self& aiterator) const + { + return ( ((*this==NULL) && (aiterator==NULL)) || + (mfirst_dart == aiterator.mfirst_dart && + ((const Base&)*this==(const Base&)aiterator)) ); + } + + /// != operator. + bool operator!=(const Self& aiterator) const + { return !operator==(aiterator); } + + /// Accessor to the initial dart of the iterator. + Dart_handle get_first_dart() const { return mfirst_dart; } + + /// Accessor to the combinatorial map. + Map* get_combinatorial_map() const { return mmap; } + + /// Rewind of the iterator to its beginning. + void rewind() + { set_current_dart(mfirst_dart); mprev_op = OP_NONE; } + + /// Test if the iterator is at its end. + bool cont() const { return *this != NULL; } + + /// Get the previous operation used for the last ++. + OperationState prev_operation() const { return mprev_op; } + + /// Return true iff this iterator is basic + static bool is_basic_iterator() + { return true; } + + protected: + /// Set the current dart to a given dart + void set_current_dart(Dart_handle adart) + { Base::operator=(adart); } + + private: + /// operator -- in private to invalidate the base operator. + Self& operator--() + { return *this; } + /// operator -- in private to invalidate the base operator. + void operator--(int) + {} + + protected: + /// test if adart->beta(ai) exists and is not marked for amark + bool is_unmarked(Dart_handle adart, unsigned int ai, unsigned amark) const + { return !adart->is_free(ai) && + !mmap->is_marked(adart->beta(ai), amark); } + + /// test if adart->beta(ai)->beta(aj) exists + bool exist_betaij(Dart_handle adart, unsigned int ai, unsigned int aj) const + { return !adart->is_free(ai) && !adart->beta(ai)->is_free(aj); } + + /// test if adart->beta(ai)->beta(aj) exists and is not marked for amark + bool is_unmarked2(Dart_handle adart, unsigned int ai, unsigned int aj, + unsigned amark) const + { return exist_betaij(adart,ai,aj) && + !mmap->is_marked(adart->beta(ai)->beta(aj), amark); } + + protected: + /// The map containing the darts to iterate on. + Map* mmap; + + /// The initial dart of the iterator. + Dart_handle mfirst_dart; + + /// The last operation used for the ++ operator. + OperationState mprev_op; + }; + //**************************************************************************** + //**********************BASIC ITERATORS*************************************** + //**************************************************************************** + /* Class CMap_dart_iterator_basic_of_orbit: to iterate + * on the darts of the orbit + */ + #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template + class CMap_dart_iterator_basic_of_orbit_generic; + #else + template + class CMap_dart_iterator_basic_of_orbit_generic; + + template + struct Get_CMap_dart_iterator_basic_of_orbit; + + template + struct Get_CMap_dart_iterator_basic_of_orbit + { + typedef CMap_dart_iterator_basic_of_orbit_generic type; + }; + + template + struct Get_CMap_dart_iterator_basic_of_orbit + { + typedef CMap_dart_iterator_basic_of_orbit_generic type; + }; + + template + struct Get_CMap_dart_iterator_basic_of_orbit + { + typedef CMap_dart_iterator_basic_of_orbit_generic type; + }; + + template + struct Get_CMap_dart_iterator_basic_of_orbit + { + typedef CMap_dart_iterator_basic_of_orbit_generic type; + }; + + template + struct Get_CMap_dart_iterator_basic_of_orbit + { + typedef CMap_dart_iterator_basic_of_orbit_generic type; + }; + + template + struct Get_CMap_dart_iterator_basic_of_orbit + { + typedef CMap_dart_iterator_basic_of_orbit_generic type; + }; + + template + struct Get_CMap_dart_iterator_basic_of_orbit + { + typedef CMap_dart_iterator_basic_of_orbit_generic type; + }; + + template + struct Get_CMap_dart_iterator_basic_of_orbit + { + typedef CMap_dart_iterator_basic_of_orbit_generic type; + }; + + template + struct Get_CMap_dart_iterator_basic_of_orbit + { + typedef CMap_dart_iterator_basic_of_orbit_generic type; + }; + + template + struct Get_CMap_dart_iterator_basic_of_orbit + { + typedef CMap_dart_iterator_basic_of_orbit_generic type; + }; + + template + class CMap_dart_iterator_basic_of_orbit_generic: + public Get_CMap_dart_iterator_basic_of_orbit::type + { + public: + typedef typename Get_CMap_dart_iterator_basic_of_orbit::type Self; + typedef typename Get_CMap_dart_iterator_basic_of_orbit::type Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int amark): + Base(amap, adart, amark) + { + CGAL_assertion( B1>=0 && B1<=Map::dimension ); + + if (adart!=NULL) + { + if (!adart->is_free(B1) && + !this->mmap->is_marked(adart->beta(B1), this->mmark_number)) + this->mto_treat.push(adart->beta(B1)); + } + } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(this->mmark_number != -1); + Base::rewind(); + if (!(*this)->is_free(B1) && + !this->mmap->is_marked((*this)->beta(B1), this->mmark_number)) + this->mto_treat.push((*this)->beta(B1)); + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + + Base::operator++(); + + if (this->cont()) + { + if (!(*this)->is_free(B1) && + !this->mmap->is_marked((*this)->beta(B1), + this->mmark_number)) + this->mto_treat.push((*this)->beta(B1)); + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + }; + #endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + //**************************************************************************** + // Case when Beta... is empty: iterator of self + template + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart): + Base(amap, adart) + {} + + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + this->set_current_dart(NULL); + this->mprev_op = OP_END; + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + }; + //**************************************************************************** + /* Class CMap_dart_iterator_basic_of_orbit: iterate onto orbit . + * Begin by turning around the facet with beta0, then turn if + * necessary in the second direction by using beta1. + */ + template + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart): + Base(amap, adart), + mfirst_dir(true) + {} + + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int /*amark*/): + Base(amap, adart), + mfirst_dir(true) + {} + + /// Assignment operator. + Self& operator= (const Self & aiterator) + { + if (this != &aiterator) + { + Base::operator=(aiterator); + mfirst_dir = aiterator.mfirst_dir; + } + return *this; + } + + /// Rewind of the iterator to its beginning. + void rewind() + { + Base::rewind(); + mfirst_dir = true; + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + + if (mfirst_dir && (*this)->is_free(0)) + { + this->set_current_dart(this->mfirst_dart); + mfirst_dir = false; + this->mprev_op = OP_JUMP; + } + else + { + this->mprev_op = OP_BETAI; + } + + if (mfirst_dir) + { + CGAL_assertion(!(*this)->is_free(0)); + this->set_current_dart((*this)->beta(0)); + + if ((*this)==this->mfirst_dart) + { + this->set_current_dart(NULL); + this->mprev_op = OP_END; + } + } + else + { + if ((*this)->is_free(1)) + { + this->set_current_dart(NULL); + this->mprev_op = OP_END; + } + else + { + this->set_current_dart((*this)->beta(1)); + this->mprev_op = OP_BETAI_INV; + } + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Boolean: true iff we turn in the first direction (i.e. using beta0). + bool mfirst_dir; + }; + //**************************************************************************** + /* Class CMap_dart_iterator_basic_of_orbit: iterate onto orbit . + * Begin by turning around the facet with beta1, then turn if + * necessary in the second direction by using beta0. + */ + template + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart): + Base(amap, adart), + mfirst_dir(true) + {} + + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int /*amark*/): + Base(amap, adart), + mfirst_dir(true) + {} + + /// Rewind of the iterator to its beginning. + void rewind() + { + Base::rewind(); + mfirst_dir = true; + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + + if (mfirst_dir && (*this)->is_free(1)) + { + this->set_current_dart(this->mfirst_dart); + mfirst_dir = false; + this->mprev_op = OP_JUMP; + } + else + { + this->mprev_op = OP_BETAI; + } + + if (mfirst_dir) + { + CGAL_assertion(!(*this)->is_free(1)); + this->set_current_dart((*this)->beta(1)); + + if ((*this)==this->mfirst_dart) + { + this->set_current_dart(NULL); + this->mprev_op = OP_END; + } + } + else + { + if ((*this)->is_free(0)) + { + this->set_current_dart(NULL); + this->mprev_op = OP_END; + } + else + { + this->set_current_dart((*this)->beta(0)); + this->mprev_op = OP_BETAI_INV; + } + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Boolean: true iff we turn in the first direction (i.e. using beta0). + bool mfirst_dir; + }; + //**************************************************************************** + /* Class CMap_dart_iterator_basic_of_orbit: to iterate + * on the darts of the orbit (2<=Bi<=dimension) + * (not for beta0 and beta1 which are special cases). + */ + template + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart): + Base(amap, adart) + { CGAL_assertion( Bi>=2 && Bi<=Map::dimension ); } + + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int /*amark*/): + Base(amap, adart) + { CGAL_assertion( Bi>=2 && Bi<=Map::dimension ); } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + if ((*this)!=this->mfirst_dart || (*this)->is_free(Bi)) + { + this->set_current_dart(NULL); + this->mprev_op = OP_END; + } + else + { + this->set_current_dart((*this)->beta(Bi)); + this->mprev_op = OP_BETAI; + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + }; + //**************************************************************************** + /* Class CMap_extend_iterator which extend a given iterator by + * adding Bi and by using a stack and a mark. + */ + template + class CMap_extend_iterator: public Ite + { + public: + typedef CMap_extend_iterator Self; + typedef Ite Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_extend_iterator(Map& amap, Dart_handle adart, int amark): + Base(amap, adart), + mmark_number(amark), + minitial_dart(adart) + { + if ( adart!=NULL ) + { + this->mmap->mark(adart, mmark_number); + if (!(*this)->is_free(Bi)) + mto_treat.push((*this)->beta(Bi)); + } + } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(mmark_number != -1); + Base::operator= ( Base(*this->mmap,minitial_dart) ); + mto_treat = std::queue(); + this->mmap->mark((*this), mmark_number); + if (!(*this)->is_free(Bi)) + mto_treat.push((*this)->beta(Bi)); + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(mmark_number != -1); + CGAL_assertion(this->cont()); + + Base::operator++(); + + if ( !this->cont() ) + { + if ( !mto_treat.empty() ) + { + Dart_handle res=NULL; + do + { + res = mto_treat.front(); + mto_treat.pop(); + } + while (!mto_treat.empty() && + this->mmap->is_marked(res, mmark_number)); + + if (!this->mmap->is_marked(res, mmark_number)) + { + Base::operator= ( Base(*this->mmap,res) ); + this->mprev_op = OP_POP; + } + } + } + + if ( this->cont() ) + { + CGAL_assertion( !this->mmap->is_marked((*this), + mmark_number) ); + this->mmap->mark((*this), mmark_number); + + if (!(*this)->is_free(Bi) && + !this->mmap->is_marked((*this)->beta(Bi), + mmark_number)) + mto_treat.push((*this)->beta(Bi)); + } + + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Queue of darts to process. + std::queue mto_treat; + + /// Index of the used mark. + int mmark_number; + + /// Initial dart + Dart_handle minitial_dart; + }; + //**************************************************************************** + /* Class CMap_dart_iterator_basic_of_orbit: to iterate + * on the darts of the orbit : Bi + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_extend_iterator, Bj> + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_extend_iterator, Bj> Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int amark): + Base(amap, adart, amark) + { CGAL_assertion( Bi: to iterate onto the + * darts of the orbit (i.e. orbit facet in 3D). + * Specialized here since we do not need queue nor mark. + */ + template + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart): + Base(amap, adart), + mit(amap, adart), + mexist_beta3(false), + mprev_beta3(false), + mfirst_border(true) + { if (adart!=NULL) mexist_beta3=!adart->is_free(3); } + + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int /*amark*/): + Base(amap, adart), + mit(amap, adart), + mexist_beta3(false), + mprev_beta3(false), + mfirst_border(true) + { if (adart!=NULL) mexist_beta3=!adart->is_free(3); } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + if (mexist_beta3 && !mprev_beta3) + { + mprev_beta3 = true; + mfirst_border = ! mfirst_border; + this->set_current_dart((*this)->beta(3)); + this->mprev_op = OP_BETAJ; + } + else + { + mprev_beta3 = false; + ++mit; + this->mprev_op = mit.prev_operation(); + if ( !mit.cont() ) + this->set_current_dart(NULL); + else + { + if ( !mfirst_border ) + this->set_current_dart(mit->beta(3)); + else + this->set_current_dart(*mit); + } + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + /// Rewind of the iterator to its beginning. + void rewind() + { + Base::rewind(); + mit.rewind(); + mprev_beta3 = false; + mfirst_border = true; + } + + private: + /// Iterator on beta0 + CMap_dart_iterator_basic_of_orbit_generic mit; + + /// Boolean: true iff there are two half facets. + bool mexist_beta3; + + /// Boolean: true iff the last ++ used beta3. + bool mprev_beta3; + + /// Boolean: true iff the current dart is on the first border. + bool mfirst_border; + }; + //**************************************************************************** + /* Class CMap_dart_iterator_basic_of_orbit: to iterate onto the + * darts of the orbit (i.e. orbit facet in 3D). + * Specialized here since we do not need queue nor mark. + */ + template + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart): + Base(amap, adart), + mit(amap, adart), + mexist_beta3(false), + mprev_beta3(false), + mfirst_border(true) + { if (adart!=NULL) mexist_beta3=!adart->is_free(3); } + + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int /*amark*/): + Base(amap, adart), + mit(amap, adart), + mexist_beta3(false), + mprev_beta3(false), + mfirst_border(true) + { if (adart!=NULL) mexist_beta3=!adart->is_free(3); } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + if (mexist_beta3 && !mprev_beta3) + { + mprev_beta3 = true; + mfirst_border = ! mfirst_border; + this->set_current_dart((*this)->beta(3)); + this->mprev_op = OP_BETAJ; + } + else + { + mprev_beta3 = false; + ++mit; + this->mprev_op = mit.prev_operation(); + if ( !mit.cont() ) + this->set_current_dart(NULL); + else + { + if ( !mfirst_border ) + this->set_current_dart(mit->beta(3)); + else + this->set_current_dart(mit); + } + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + /// Rewind of the iterator to its beginning. + void rewind() + { + Base::rewind(); + mit.rewind(); + mprev_beta3 = false; + mfirst_border = true; + } + + private: + /// Iterator on beta1 + CMap_dart_iterator_basic_of_orbit_generic mit; + + /// Boolean: true iff there are two half facets. + bool mexist_beta3; + + /// Boolean: true iff the last ++ used beta3. + bool mprev_beta3; + + /// Boolean: true iff the current dart is on the first border. + bool mfirst_border; + }; + //**************************************************************************** + /* Class CMap_dart_iterator_basic_of_orbit: to iterate onto the + * darts of the orbit (i.e. orbit edge in 3D). + */ + template + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart): + Base(amap, adart), + mfirst_dir(true), + mnext_try_beta2(true) + {} + + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int /*amark*/): + Base(amap, adart), + mfirst_dir(true), + mnext_try_beta2(true) + {} + + /// Rewind of the iterator to its beginning. + void rewind() + { + Base::rewind(); + mfirst_dir = true; + mnext_try_beta2 = true; + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + + if (mfirst_dir) + { + if (mnext_try_beta2) + { + if ((*this)->is_free(2)) + { + mfirst_dir = false; + if (this->mfirst_dart->is_free(3)) + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + else + { + this->set_current_dart(this->mfirst_dart->beta(3)); + this->mprev_op = OP_JUMP; + } + } + else + { + this->set_current_dart((*this)->beta(2)); + mnext_try_beta2 = false; + this->mprev_op = OP_BETAI; + } + } + else + { + if ((*this)->is_free(3)) + { + mfirst_dir = false; + if (this->mfirst_dart->is_free(3)) + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + else + { + this->set_current_dart(this->mfirst_dart->beta(3)); + mnext_try_beta2 = true; + this->mprev_op = OP_JUMP; + } + } + else + { + this->set_current_dart((*this)->beta(3)); + if ((*this)==this->mfirst_dart) + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + else + { + mnext_try_beta2 = true; + this->mprev_op = OP_BETAJ; + } + } + } + } + else + { + if (mnext_try_beta2) + { + if ((*this)->is_free(2)) + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + else + { + this->set_current_dart((*this)->beta(2)); + mnext_try_beta2 = false; + this->mprev_op = OP_BETAI; + } + } + else + { + if ((*this)->is_free(3)) + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + else + { + this->set_current_dart((*this)->beta(3)); + mnext_try_beta2 = true; + this->mprev_op = OP_BETAJ; + } + } + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + private: + /// Boolean: true iff we turn in the first direction (i.e. using beta2). + bool mfirst_dir; + + /// Boolean: true iff the next ++ must use beta2. + bool mnext_try_beta2; + }; + //**************************************************************************** + /* Class CMap_dart_iterator_basic_of_orbit: to iterate onto + * the darts of the orbit , Bi, , which are specific cases. + */ + template + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int amark): + Base(amap, adart, amark) + { + CGAL_assertion( Biis_free(Bk) && + !this->mmap->is_marked(adart->beta(Bk), this->mmark_number)) + this->mto_treat.push(adart->beta(Bk)); + } + } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(this->mmark_number != -1); + Base::rewind(); + if (!(*this)->is_free(Bk) && + !this->mmap->is_marked((*this)->beta(Bk), + this->mmark_number)) + this->mto_treat.push((*this)->beta(Bk)); + } + + /// Prefix ++ operator. + Self& operator++() + { + Base::operator++(); + + if ( this->cont() ) + { + if (!(*this)->is_free(Bk) && + !this->mmap->is_marked((*this)->beta(Bk), + this->mmark_number)) + this->mto_treat.push((*this)->beta(Bk)); + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + }; + //**************************************************************************** + template + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_extend_iterator, Bk> + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_extend_iterator, Bk> Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart, + int amark): + Base(amap, adart, amark) + { CGAL_assertion( Bi<3 && 3 + class CMap_dart_iterator_basic_of_orbit: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_orbit Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Map::Dart_handle Dart_handle; + + /// Main constructor. + CMap_dart_iterator_basic_of_orbit(Map& amap,Dart_handle adart): + Base(amap,adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_orbit(Map& amap,Dart_handle adart,int amark): + Base(amap,adart,amark) + {} + }; + #else + //**************************************************************************** + template + class CMap_dart_iterator_basic_of_orbit: + public Get_CMap_dart_iterator_basic_of_orbit::type + { + public: + typedef CMap_dart_iterator_basic_of_orbit + Self; + typedef typename Get_CMap_dart_iterator_basic_of_orbit::type + Base; + + typedef typename Map::Dart_handle Dart_handle; + + /// Main constructor. + CMap_dart_iterator_basic_of_orbit(Map& amap,Dart_handle adart): + Base(amap,adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_orbit(Map& amap,Dart_handle adart,int amark): + Base(amap,adart,amark) + {} + }; + #endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + //**************************************************************************** + // i-Cell iterator in combinatorial map of dimension d, i>1 + // i<=Map::dimension+1 (for i==Map::dimension+1, iterate on the connected + // component) + template + class CMap_dart_iterator_basic_of_cell: public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart), + mmark_number(amark) + { + CGAL_assertion( i>=2 && i<=Map::dimension+1 ); + if (adart!=NULL) + this->mmap->mark(adart, mmark_number); + } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(mmark_number != -1); + Base::rewind(); + mto_treat = std::queue(); + this->mmap->mark(*this, mmark_number); + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(mmark_number != -1); + CGAL_assertion(this->cont()); + Dart_handle nd = NULL; + + for ( unsigned int k=0; k<=d; ++k ) + { + if ( k!=i && this->is_unmarked((*this), k, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(k); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAI; + } + else + { + mto_treat.push((*this)->beta(k)); + this->mmap->mark((*this)->beta(k), mmark_number); + } + } + } + + if (nd == NULL) + { + if (!mto_treat.empty()) + { + nd = mto_treat.front(); + mto_treat.pop(); + this->mprev_op = OP_POP; + } + else + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + } + + this->set_current_dart(nd); + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Queue of darts to process. + std::queue mto_treat; + + /// Index of the used mark. + int mmark_number; + }; + //**************************************************************************** + // 0-Cell iterator in combinatorial map of dimension d + template + class CMap_dart_iterator_basic_of_cell: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart), + mmark_number(amark) + { + if (adart!=NULL) this->mmap->mark(adart, mmark_number); + } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(mmark_number != -1); + Base::rewind(); + mto_treat = std::queue(); + this->mmap->mark((*this), mmark_number); + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(mmark_number != -1); + CGAL_assertion(this->cont()); + + Dart_handle nd = NULL; + + for ( unsigned int k=2; k<=d; ++k ) + { + if ( this->is_unmarked2((*this), 0, k, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(0)->beta(k); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETA0I; + } + else + { + mto_treat.push((*this)->beta(0)->beta(k)); + this->mmap->mark((*this)->beta(0)->beta(k), mmark_number); + } + + } + if ( this->is_unmarked2((*this), k, 1, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(k)->beta(1); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAI1; + } + else + { + mto_treat.push((*this)->beta(k)->beta(1)); + this->mmap->mark((*this)->beta(k)->beta(1), mmark_number); + } + } + for ( unsigned int l=k+1; l<=d; ++l ) + { + if ( this->is_unmarked2((*this), k, l, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(k)->beta(l); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAIJ; + } + else + { + mto_treat.push((*this)->beta(k)->beta(l)); + this->mmap->mark((*this)->beta(k)->beta(l), mmark_number); + } + } + if ( this->is_unmarked2((*this), l, k, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(l)->beta(k); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAJI; + } + else + { + mto_treat.push((*this)->beta(l)->beta(k)); + this->mmap->mark((*this)->beta(l)->beta(k), mmark_number); + } + } + } + } + + if (nd == NULL) + { + if (!mto_treat.empty()) + { + nd = mto_treat.front(); + CGAL_assertion(nd!=Map::null_dart_handle); + mto_treat.pop(); + this->mprev_op = OP_POP; + } + else + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + } + + this->set_current_dart(nd); + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Queue of darts to process. + std::queue mto_treat; + + /// Index of the used mark. + int mmark_number; + }; + //**************************************************************************** + // 1-Cell iterator in combinatorial map of dimension d + template + class CMap_dart_iterator_basic_of_cell: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart), + mmark_number(amark) + { if (adart!=NULL) this->mmap->mark(adart, mmark_number); } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(mmark_number != -1); + Base::rewind(); + mto_treat = std::queue(); + this->mmap->mark((*this), mmark_number); + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(mmark_number != -1); + CGAL_assertion(this->cont()); + + Dart_handle nd = NULL; + + for ( unsigned int k=2; k<=d; ++k ) + { + if ( this->is_unmarked((*this), k, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(k); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAI; + } + else + { + mto_treat.push((*this)->beta(k)); + this->mmap->mark((*this)->beta(k), mmark_number); + } + } + } + + if (nd == NULL) + { + if (!mto_treat.empty()) + { + nd = mto_treat.front(); + mto_treat.pop(); + this->mprev_op = OP_POP; + } + else + { + this->mprev_op = OP_END; + } + } + + this->set_current_dart(nd); + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Queue of darts to process. + std::queue mto_treat; + + /// Index of the used mark. + int mmark_number; + }; + //**************************************************************************** + // Specialization for edge in 2D + template + class CMap_dart_iterator_basic_of_cell: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + }; + //**************************************************************************** + // Specialization for facet in 2D + template + class CMap_dart_iterator_basic_of_cell: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + }; + //**************************************************************************** + // Specialization for cc in 2D + template + class CMap_dart_iterator_basic_of_cell: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart, amark) + {} + }; + //**************************************************************************** + // Specialization for edge in 3D + template + class CMap_dart_iterator_basic_of_cell: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int /*amark*/): Base(amap, adart) + {} + }; + //**************************************************************************** + // Specialization for facet in 3D + template + class CMap_dart_iterator_basic_of_cell: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int /*amark*/): Base(amap, adart) + {} + }; + //**************************************************************************** + // Specialization for volume in 3D + template + class CMap_dart_iterator_basic_of_cell: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart, amark) + {} + }; + //**************************************************************************** + // Specialization for cc in 3D + template + class CMap_dart_iterator_basic_of_cell: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart, amark) + {} + }; + //**************************************************************************** + /* Class CMap_dart_iterator_basic_of_cell: to iterate onto the + * darts of the orbit vertex in 2D. + */ + template + class CMap_dart_iterator_basic_of_cell: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart): + Base(amap, adart), + mfirst_dir(true) + {} + + /// Main constructor. + CMap_dart_iterator_basic_of_cell(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart), + mfirst_dir(true) + {} + + /// Rewind of the iterator to its beginning. + void rewind() + { + Base::rewind(); + mfirst_dir = true; + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + + if (mfirst_dir) + { + this->set_current_dart((*this)->beta(0)->beta(2)); + if ((*this)==Map::null_dart_handle) + { + mfirst_dir = false; + this->set_current_dart(this->mfirst_dart->beta(2)->beta(1)); + if ((*this)==Map::null_dart_handle) + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + else + { + this->mprev_op = OP_BETAI1; + } + } + else + { + if ((*this)==this->mfirst_dart) + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + else + this->mprev_op = OP_BETA0I; + } + } + else + { + this->set_current_dart((*this)->beta(2)->beta(1)); + if ((*this) == Map::null_dart_handle) + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + else + this->mprev_op = OP_BETA21; + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Boolean: true iff we turn in the first direction (i.e. using beta02). + bool mfirst_dir; + }; + //**************************************************************************** + /* Class CMap_dart_iterator_basic_of_all: to iterate onto all the + * darts of the map. + */ + template + class CMap_dart_iterator_basic_of_all: public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_all Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_all(Map& amap): + Base(amap, amap.darts().begin()) + {} + + /// Main constructor. + CMap_dart_iterator_basic_of_all(Map& amap, int /*amark*/): + Base(amap, amap.darts().begin()) + {} + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + + Base::operator++(); + if ( (*this) != this->mmap->darts().end()) + { this->mprev_op = OP_POP; } + else + { + this->set_current_dart(NULL); + this->mprev_op = OP_END; + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + }; + //************************************************************************** + /* Generic nD version. Here we are sure that all the bases classes use mark + * and queue. + */ + #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template + class CMap_dart_iterator_basic_of_orbit_generic: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_orbit_generic Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_orbit_generic(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart, amark) + { + CGAL_assertion( Bi>=0 && Bi<=Map::dimension ); + + if (adart!=NULL) + { + if (!adart->is_free(Bi) && + !this->mmap->is_marked(adart->beta(Bi), this->mmark_number)) + this->mto_treat.push(adart->beta(Bi)); + } + } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(this->mmark_number != -1); + Base::rewind(); + if (!(*this)->is_free(Bi) && + !this->mmap->is_marked((*this)->beta(Bi), + this->mmark_number)) + this->mto_treat.push((*this)->beta(Bi)); + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(this->cont()); + + Base::operator++(); + + if (this->cont()) + { + if (!(*this)->is_free(Bi) && + !this->mmap->is_marked((*this)->beta(Bi), + this->mmark_number)) + this->mto_treat.push((*this)->beta(Bi)); + } + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + }; +#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + //**************************************************************************** + //*************************ITERATORS*NON*BASIC********************************* + //**************************************************************************** + //* Class CMap_non_basic_iterator allows to transform a basic_iterator onto + //* a non basic one, depending if the basic iterator uses mark or not. + template + class CMap_non_basic_iterator; + //**************************************************************************** + template + class CMap_non_basic_iterator: + public Basic_iterator + { + public: + typedef CMap_non_basic_iterator Self; + + typedef typename Basic_iterator::Map Map; + typedef typename Basic_iterator::Dart_handle Dart_handle; + + /// Main constructor. + CMap_non_basic_iterator(Map& amap, Dart_handle adart1): + Basic_iterator(amap, adart1, amap.get_new_mark()) + { CGAL_assertion( Basic_iterator::is_basic_iterator() ); } + + /// Destructor. + ~CMap_non_basic_iterator() + { + if (this->mmark_number != -1) + { + unmark_treated_darts(); + CGAL_assertion( this->mmap->is_whole_map_unmarked + (this->mmark_number) ); + this->mmap->free_mark(this->mmark_number); + } + } + + /// Copy constructor. + CMap_non_basic_iterator(const Self& aiterator): + Basic_iterator(aiterator) + { this->mmark_number = -1; } + + /// Assignment operator. + Self& operator=(const Self& aiterator) + { + if (this != &aiterator) + { + Basic_iterator::operator=(aiterator); + this->mmark_number = -1; + } + return *this; + } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(this->mmark_number != -1); + unmark_treated_darts(); + Basic_iterator::rewind(); + } + + using Basic_iterator::operator++; + + /// Postfix ++ operator. + void operator++(int) + { operator ++(); } + + /// Return true iff this iterator is basic + static bool is_basic_iterator() + { return false; } + + protected: + /// Unmark all the marked darts during the iterator. + void unmark_treated_darts() + { + CGAL_assertion(this->mmark_number != -1); + if (this->mmap->is_whole_map_unmarked(this->mmark_number)) return; + + this->mmap->negate_mark(this->mmark_number); + + if (this->mmap->is_whole_map_unmarked(this->mmark_number)) return; + + Basic_iterator::rewind(); + while (this->mmap->number_of_unmarked_darts(this->mmark_number) > 0) + this->operator++(); + this->mmap->negate_mark(this->mmark_number); + CGAL_assertion(this->mmap->is_whole_map_unmarked(this->mmark_number)); + } + }; + //**************************************************************************** + template + class CMap_non_basic_iterator: + public Basic_iterator + { + public: + typedef CMap_non_basic_iterator Self; + typedef typename Basic_iterator::Map Map; + typedef typename Basic_iterator::Dart_handle Dart_handle; + + /// Main constructor. + CMap_non_basic_iterator(Map& amap, Dart_handle adart): + Basic_iterator(amap, adart,-1) + {} + /// Return true iff this iterator is basic + static bool is_basic_iterator() + { return false; } + }; + //**************************************************************************** + #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template + class CMap_dart_iterator_of_orbit_generic: + public CMap_non_basic_iterator > + { + public: + typedef CMap_dart_iterator_of_orbit_generic Self; + typedef CMap_non_basic_iterator > Base; + + typedef typename Base::Map Map; + typedef typename Base::Dart_handle Dart_handle; + + /// Main constructor. + CMap_dart_iterator_of_orbit_generic(Map& amap, Dart_handle adart1): + Base(amap, adart1) + {} + }; + //**************************************************************************** + template + class CMap_dart_iterator_of_orbit: + public CMap_dart_iterator_of_orbit_generic + { + public: + typedef CMap_dart_iterator_of_orbit Self; + typedef CMap_dart_iterator_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + + /// Main constructor. + CMap_dart_iterator_of_orbit(Map_& amap, Dart_handle adart): + Base(amap, adart) + {} + }; + #else + //**************************************************************************** + template + class CMap_dart_iterator_of_orbit_generic: + public CMap_non_basic_iterator::type> + { + public: + typedef CMap_dart_iterator_of_orbit_generic Self; + typedef CMap_non_basic_iterator::type> Base; + + typedef typename Base::Map Map; + typedef typename Base::Dart_handle Dart_handle; + + /// Main constructor. + CMap_dart_iterator_of_orbit_generic(Map& amap, Dart_handle adart1): + Base(amap, adart1) + {} + }; + //**************************************************************************** + template + class CMap_dart_iterator_of_orbit: + public CMap_dart_iterator_of_orbit_generic + { + public: + typedef CMap_dart_iterator_of_orbit Self; + typedef CMap_dart_iterator_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + + /// Main constructor. + CMap_dart_iterator_of_orbit(Map& amap, Dart_handle adart): + Base(amap, adart) + {} + }; + #endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + //**************************************************************************** + template + class CMap_dart_iterator_of_cell: + public CMap_non_basic_iterator > + { + public: + typedef CMap_dart_iterator_basic_of_cell Self; + typedef CMap_non_basic_iterator > Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + /// Main constructor. + CMap_dart_iterator_of_cell(Map& amap, Dart_handle adart1): + Base(amap, adart1) + {} + }; + //**************************************************************************** + //********************ITERATOR*INVOLUTION************************************* + //**************************************************************************** + // i-involution iterator in combinatorial map of dimension d, + // 2 + class CMap_dart_iterator_basic_of_involution; + + template + class CMap_dart_iterator_basic_of_involution: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_involution Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart), + mmark_number(amark) + { + CGAL_assertion( d>=3 && d<=Map::dimension ); + CGAL_assertion( i>=3 && i<=Map::dimension ); + if (adart!=NULL) this->mmap->mark(adart, mmark_number); + } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(mmark_number != -1); + Base::rewind(); + mto_treat = std::queue(); + this->mmap->mark((*this), mmark_number); + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(mmark_number != -1); + CGAL_assertion(this->cont()); + + Dart_handle nd = NULL; + + for ( unsigned int k=0; k<2; ++k ) + { + if ( this->is_unmarked((*this), k, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(k); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAI; + } + else + { + mto_treat.push((*this)->beta(k)); + this->mmap->mark((*this)->beta(k), mmark_number); + } + } + } + + for ( unsigned int k=2; k<=d; ++k ) + { + if ( k!=i-1 && k!=i && k!=i+1 && + this->is_unmarked((*this), k, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(k); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAI; + } + else + { + mto_treat.push((*this)->beta(k)); + this->mmap->mark((*this)->beta(k), mmark_number); + } + } + } + + if (nd == NULL) + { + if (!mto_treat.empty()) + { + nd = mto_treat.front(); + mto_treat.pop(); + this->mprev_op = OP_POP; + } + else + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + } + + this->set_current_dart(nd); + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Queue of darts to process. + std::queue mto_treat; + + /// Index of the used mark. + int mmark_number; + }; + //**************************************************************************** + // i-involution iterator in combinatorial map of dimension d, + // 2 + class CMap_dart_iterator_basic_of_involution_inv: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_involution_inv Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart), + mmark_number(amark) + { + CGAL_assertion( i>=3 && i<=Map::dimension ); + if (adart!=NULL) this->mmap->mark(adart, mmark_number); + } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(mmark_number != -1); + Base::rewind(); + mto_treat = std::queue(); + this->mmap->mark((*this), mmark_number); + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(mmark_number != -1); + CGAL_assertion(this->cont()); + + Dart_handle nd = NULL; + + for ( int k=1; k>=0; --k ) + { + if ( this->is_unmarked((*this), k, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(k); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAI; + } + else + { + mto_treat.push((*this)->beta(k)); + this->mmap->mark((*this)->beta(k), mmark_number); + } + } + } + for ( unsigned int k=2; k<=d; ++k ) + { + if ( k!=i-1 && k!=i && k!=i+1 && + this->is_unmarked((*this), k, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(k); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAI; + } + else + { + mto_treat.push((*this)->beta(k)); + this->mmap->mark((*this)->beta(k), mmark_number); + } + } + } + + if (nd == NULL) + { + if (!mto_treat.empty()) + { + nd = mto_treat.front(); + mto_treat.pop(); + this->mprev_op = OP_POP; + } + else + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + } + + this->set_current_dart(nd); + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Queue of darts to process. + std::queue mto_treat; + + /// Index of the used mark. + int mmark_number; + }; + //**************************************************************************** + // 1-involution iterator in combinatorial map of dimension d. + // Iterate by using all beta between 3 and d. + template + class CMap_dart_iterator_basic_of_involution: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_involution Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart), + mmark_number(amark) + { if (adart!=NULL) this->mmap->mark(adart, mmark_number); } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(mmark_number != -1); + Base::rewind(); + mto_treat = std::queue(); + this->mmap->mark((*this), mmark_number); + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(mmark_number != -1); + CGAL_assertion(this->cont()); + + Dart_handle nd = NULL; + + for ( unsigned int k=3; k<=d; ++k ) + { + if ( this->is_unmarked((*this), k, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(k); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAI; + } + else + { + mto_treat.push((*this)->beta(k)); + this->mmap->mark((*this)->beta(k), mmark_number); + } + } + } + + if (nd == NULL) + { + if (!mto_treat.empty()) + { + nd = mto_treat.front(); + mto_treat.pop(); + this->mprev_op = OP_POP; + } + else + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + } + + this->set_current_dart(nd); + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Queue of darts to process. + std::queue mto_treat; + + /// Index of the used mark. + int mmark_number; + }; + //**************************************************************************** + // 1-involution iterator in combinatorial map of dimension d. + // Iterate by using all beta between 3 and d. + template + class CMap_dart_iterator_basic_of_involution_inv: + public CMap_dart_iterator_basic_of_involution + { + public: + typedef CMap_dart_iterator_basic_of_involution_inv Self; + typedef CMap_dart_iterator_basic_of_involution Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart,amark) + {} + }; + //**************************************************************************** + // 2-involution iterator in combinatorial map of dimension d. + // Iterate by using all beta between 4 and d. + template + class CMap_dart_iterator_basic_of_involution: + public CMap_dart_iterator + { + public: + typedef CMap_dart_iterator_basic_of_involution Self; + typedef CMap_dart_iterator Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart), + mmark_number(amark) + { this->mmap->mark(adart, mmark_number); } + + /// Rewind of the iterator to its beginning. + void rewind() + { + CGAL_assertion(mmark_number != -1); + Base::rewind(); + mto_treat = std::queue(); + this->mmap->mark((*this), mmark_number); + } + + /// Prefix ++ operator. + Self& operator++() + { + CGAL_assertion(mmark_number != -1); + CGAL_assertion(this->cont()); + + Dart_handle nd = NULL; + + for ( unsigned int k=4; k<=d; ++k ) + { + if ( this->is_unmarked((*this), k, mmark_number) ) + { + if (nd == NULL) + { + nd = (*this)->beta(k); + CGAL_assertion(nd!=Map::null_dart_handle); + this->mmap->mark(nd, mmark_number); + this->mprev_op = OP_BETAI; + } + else + { + mto_treat.push((*this)->beta(k)); + this->mmap->mark((*this)->beta(k), mmark_number); + } + } + } + + if (nd == NULL) + { + if (!mto_treat.empty()) + { + nd = mto_treat.front(); + mto_treat.pop(); + this->mprev_op = OP_POP; + } + else + { + this->mprev_op = OP_END; + this->set_current_dart(NULL); + } + } + + this->set_current_dart(nd); + return *this; + } + + /// Postfix ++ operator. + Self operator++(int) + { Self res=*this; operator ++(); return res; } + + protected: + /// Queue of darts to process. + std::queue mto_treat; + + /// Index of the used mark. + int mmark_number; + }; + //**************************************************************************** + // 2-involution iterator in combinatorial map of dimension d. + // Iterate by using all beta between 4 and d. + template + class CMap_dart_iterator_basic_of_involution_inv: + public CMap_dart_iterator_basic_of_involution + { + public: + typedef CMap_dart_iterator_basic_of_involution_inv Self; + typedef CMap_dart_iterator_basic_of_involution Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_true Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart, + int amark): + Base(amap, adart,amark) + {} + }; + //**************************************************************************** + // 1-involution iterator in combinatorial map of dimension 2. + // Empty iterator. + template + class CMap_dart_iterator_basic_of_involution: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_involution Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + }; + //**************************************************************************** + // 1-involution iterator in combinatorial map of dimension 2. + // self iterator. + template + class CMap_dart_iterator_basic_of_involution_inv: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_involution_inv Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + }; + //**************************************************************************** + // 2-involution iterator in combinatorial map of dimension 2. + // self iterator. + template + class CMap_dart_iterator_basic_of_involution: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_involution Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + }; + //**************************************************************************** + // 2-involution iterator in combinatorial map of dimension 2. + // self iterator. + template + class CMap_dart_iterator_basic_of_involution_inv: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_involution_inv Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + }; + //**************************************************************************** + // 1-involution iterator in combinatorial map of dimension 3. + // Beta3 iterator. + template + class CMap_dart_iterator_basic_of_involution: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_involution Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + }; + //**************************************************************************** + // 1-involution iterator in combinatorial map of dimension 3. + // Beta3 iterator. + template + class CMap_dart_iterator_basic_of_involution_inv: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_involution_inv Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + }; + //**************************************************************************** + // 2-involution iterator in combinatorial map of dimension 3. + // Self iterator. + template + class CMap_dart_iterator_basic_of_involution: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_involution Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart, + int /* amark*/): + Base(amap, adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + }; + //**************************************************************************** + // 2-involution iterator in combinatorial map of dimension 3. + // Self iterator. + template + class CMap_dart_iterator_basic_of_involution_inv: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_involution_inv Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + }; + //**************************************************************************** + // 1-involution iterator in combinatorial map of dimension 3. + // Beta1 iterator. + template + class CMap_dart_iterator_basic_of_involution: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_involution Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_involution(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + }; + //**************************************************************************** + // 1-involution iterator in combinatorial map of dimension 3. + // Beta0 iterator. + template + class CMap_dart_iterator_basic_of_involution_inv: + public CMap_dart_iterator_basic_of_orbit_generic + { + public: + typedef CMap_dart_iterator_basic_of_involution_inv Self; + typedef CMap_dart_iterator_basic_of_orbit_generic Base; + + typedef typename Base::Dart_handle Dart_handle; + typedef typename Base::Map Map; + + typedef Tag_false Use_mark; + + public: + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart, + int /*amark*/): + Base(amap, adart) + {} + /// Main constructor. + CMap_dart_iterator_basic_of_involution_inv(Map& amap, + Dart_handle adart): + Base(amap, adart) + {} + }; + //**************************************************************************** + template + class CMap_dart_iterator_of_involution: + public CMap_non_basic_iterator > + { + public: + typedef CMap_dart_iterator_of_involution Self; + typedef CMap_non_basic_iterator > Base; + + /// Main constructor. + CMap_dart_iterator_of_involution(typename Base::Map& amap, + typename Base::Dart_handle adart1): + Base(amap, adart1) + {} + }; + //**************************************************************************** + template + class CMap_dart_iterator_of_involution_inv: + public CMap_non_basic_iterator > + { + public: + typedef CMap_dart_iterator_of_involution_inv Self; + typedef CMap_non_basic_iterator > Base; + + /// Main constructor. + CMap_dart_iterator_of_involution_inv(typename Base::Map& amap, + typename Base::Dart_handle adart1): + Base(amap, adart1) + {} + }; + //**************************************************************************** +} // namespace CGAL +//****************************************************************************** +#endif // CGAL_DART_ITERATORS_HH +//****************************************************************************** diff --git a/Combinatorial_map/include/CGAL/internal/Combinatorial_map_functors.h b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_functors.h new file mode 100644 index 00000000000..f7fed3e586d --- /dev/null +++ b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_functors.h @@ -0,0 +1,992 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (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; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// 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) : Guillaume Damiand +// +#ifndef CGAL_COMBINATORIAL_MAP_FUNCTORS_H +#define CGAL_COMBINATORIAL_MAP_FUNCTORS_H + +#include +#include +#include +#include + +namespace CGAL { + namespace internal { + + /** @file Combinatorial_map_functors.h + * Definition of functors used for dD Combinatorial map. + */ + + template + struct Couple_dart_and_dim + { + Couple_dart_and_dim(Dart_handle ad1,Dart_handle ad2,int adim) : + d1(ad1), d2(ad2), dim(adim) + {} + Dart_handle d1,d2; + int dim; + }; + + + /// Functor used to test if it is possible to i-sew two darts, + /// 2<=i<=dimension + template + struct is_sewable_functor{ + static bool run(const Map& amap, + typename Map::Dart_const_handle adart1, + typename Map::Dart_const_handle adart2) + { + CGAL_assertion(2<=i && i<=Map::dimension); + CGAL_assertion(adart1!=NULL && adart2!=NULL); + + if ( !adart1->is_free(i) || !adart2->is_free(i) || adart1==adart2 ) + return false; + + CMap_dart_const_iterator_of_involution I1(amap, adart1); + CMap_dart_const_iterator_of_involution_inv I2(amap, adart2); + bool res = true; + while (res && I1.cont() && I2.cont()) + { + // We can remove this constraint which is not required for + // combinatorial map definition, but which is quite "normal" + if ( I1==adart2 || I2==adart1 ) res=false; + + // Special case to consider beta0 and beta1 + if ( i>2 ) + { + if ( I1->is_free(0)!=I2->is_free(1) ) res = false; + else if ( I1->is_free(1)!=I2->is_free(0) ) res = false; + } + + // General case + for (unsigned int j=2;res && j<=Map::dimension; ++j) + { + if ( j+1!=i && j!=i && j!=i+1 && + I1->is_free(j)!=I2->is_free(j) ) + { res = false; } + } + ++I1; ++I2; + } + if (I1.cont() != I2.cont()) + res = false; + + return res; + } + }; + + /// Functor used to test if it is possible to 1-sew two darts. + template + struct is_sewable_functor{ + static bool run(const Map& amap, + typename Map::Dart_const_handle adart1, + typename Map::Dart_const_handle adart2) + { + CGAL_assertion(adart1!=NULL && adart2!=NULL); + + if ( !adart1->is_free(1) || !adart2->is_free(0) ) + return false; + + if ( adart1 == adart2 ) return true; + + CMap_dart_const_iterator_of_involution I1(amap, adart1); + CMap_dart_const_iterator_of_involution_inv I2(amap, adart2); + bool res = true; + while (res && I1.cont() && I2.cont()) + { + // We can remove this constraint which is not required for + // combinatorial map definition, but which imposes quite "normal" + // configurations + if ( I1==adart2 || I2==adart1 ) res=false; + + for (unsigned int j=3;res && j<=Map::dimension; ++j) + { + if ( I1->is_free(j)!=I2->is_free(j) ) + { + res = false; + } + } + ++I1; ++I2; + } + if (I1.cont() != I2.cont()) + res = false; + + return res; + } + }; + + /// Functor used to test if it is possible to 0-sew two darts. + template + struct is_sewable_functor{ + static bool run(const Map& amap, + typename Map::Dart_const_handle adart1, + typename Map::Dart_const_handle adart2) + { return is_sewable_functor::run(amap,adart1,adart2); } + }; + + /// Functor used to i-topo_sew two darts, 2<=i<=dimension. + template + struct topo_sew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + CGAL_assertion(2<=i && i<=Map::dimension); + CGAL_assertion( (is_sewable_functor::run(amap,adart1,adart2)) ); + + CMap_dart_iterator_of_involution I1(amap, adart1); + CMap_dart_iterator_of_involution_inv I2(amap, adart2); + while ( I1.cont() ) + { + amap.basic_link_beta(I1, I2, i); + ++I1; ++I2; + } + } + }; + + /// Functor used to 1-topo_sew two darts. + template + struct topo_sew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + CGAL_assertion( (is_sewable_functor::run(amap,adart1,adart2)) ); + + int mark = amap.get_new_mark(); + std::vector dartv; + for (CMap_dart_iterator_basic_of_cell it(amap,adart1,mark); + it.cont(); ++it) + { + amap.mark(*it,mark); + dartv.push_back(*it); + } + + CMap_dart_iterator_of_involution I1(amap, adart1); + CMap_dart_iterator_of_involution_inv I2(amap, adart2); + while ( I1.cont() ) + { + if ( amap.is_marked(*I1,mark) ) amap.template basic_link_beta<1>(*I1, *I2); + else amap.template basic_link_beta<0>(*I1, *I2); + ++I1; ++I2; + } + + for (typename std::vector::iterator + it=dartv.begin(); it!=dartv.end(); ++it) + { amap.unmark(*it,mark); } + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + amap.free_mark(mark); + } + }; + + /// Functor used to 0-topo_sew two darts. + template + struct topo_sew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { topo_sew_functor::run(amap,adart1,adart2); } + }; + + /// Functor used to i-sew two darts, 2<=i<=dimension. + template + struct sew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + CGAL_assertion(2<=i && i<=Map::dimension); + CGAL_assertion( (is_sewable_functor::run(amap,adart1,adart2)) ); + + CMap_dart_iterator_of_involution I1(amap, adart1); + CMap_dart_iterator_of_involution_inv I2(amap, adart2); + while ( I1.cont() ) + { + amap.group_all_attributes_except(I1,I2,i); + ++I1; ++I2; + } + + I1.rewind(); I2.rewind(); + while ( I1.cont() ) + { + amap.basic_link_beta(I1, I2, i); + ++I1; ++I2; + } + } + }; + + /// Functor used to 0-sew two darts. + template + struct sew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + CGAL_assertion( (is_sewable_functor::run(amap,adart1,adart2)) ); + + int mark = amap.get_new_mark(); + std::vector dartv; + for (CMap_dart_iterator_basic_of_cell it(amap,adart1,mark); + it.cont(); ++it) + { + amap.mark(*it,mark); + dartv.push_back(*it); + } + + CMap_dart_iterator_of_involution I1(amap, adart1); + CMap_dart_iterator_of_involution_inv I2(amap, adart2); + while ( I1.cont() ) + { + group_all_attributes_except(*I1,*I2,1); + ++I1; ++I2; + } + + I1.rewind(); I2.rewind(); + while ( I1.cont() ) + { + if ( amap.is_marked(*I1,mark) ) amap.template basic_link_beta<0>(*I1, *I2); + else amap.template basic_link_beta<1>(*I1, *I2); + ++I1; ++I2; + } + + for (typename std::vector::iterator + it=dartv.begin(); it!=dartv.end(); ++it) + { amap.unmark(*it,mark); } + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + amap.free_mark(mark); + } + }; + + /// Functor used to 1-sew two darts. + template + struct sew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + CGAL_assertion( (is_sewable_functor::run(amap,adart1,adart2)) ); + int mark = amap.get_new_mark(); + std::vector dartv; + for (CMap_dart_iterator_basic_of_cell it(amap,adart1,mark); + it.cont(); ++it) + { + amap.mark(it,mark); + dartv.push_back(it); + } + + CMap_dart_iterator_of_involution I1(amap, adart1); + CMap_dart_iterator_of_involution_inv I2(amap, adart2); + while ( I1.cont() ) + { + amap.group_all_attributes_except(I1,I2,1); + ++I1; ++I2; + } + + I1.rewind(); I2.rewind(); + while ( I1.cont() ) + { + if ( amap.is_marked(I1,mark) ) amap.template basic_link_beta<1>(I1, I2); + else amap.template basic_link_beta<0>(I1, I2); + ++I1; ++I2; + } + + for (typename std::vector::iterator + it=dartv.begin(); it!=dartv.end(); ++it) + { amap.unmark(*it,mark); } + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + amap.free_mark(mark); + } + }; + + /// Functor used to i-topo_unsew one dart, 2<=i<=dimension. + template + struct topo_unsew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart) + { + CGAL_assertion( adart!=NULL && !adart->is_free(i) ); + CGAL_assertion(2<=i && i<=Map::dimension); + + CMap_dart_iterator_of_involution it(amap, adart); + while ( it.cont() ) + { + amap.unlink_beta(*it, i); + ++it; + } + } + }; + + /// Functor used to 1-topo_unsew one dart. + template + struct topo_unsew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart) + { + CGAL_assertion( adart!=NULL && !adart->is_free(1) ); + + int mark = amap.get_new_mark(); + std::vector dartv; + for (CMap_dart_iterator_basic_of_cell it(amap,adart,mark); + it.cont(); ++it) + { + amap.mark(*it,mark); + dartv.push_back(*it); + } + + { + CMap_dart_iterator_of_involution it(amap, adart); + while ( it.cont() ) + { + if ( amap.is_marked(*it,mark) ) amap.unlink_beta<1>(*it); + else amap.unlink_beta<0>(*it); + ++it; + } + } + + for (typename std::vector::iterator + it=dartv.begin(); it!=dartv.end(); ++it) + { amap.unmark(*it,mark); } + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + amap.free_mark(mark); + } + }; + + /// Functor used to 1-topo_unsew one dart. + template + struct topo_unsew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart) + { + CGAL_assertion( adart!=NULL && !adart->is_free(0) ); + topo_unsew_functor::run(adart->beta(0)); + } + }; + + /// Functor used to i-unsew one dart, 2<=i<=dimension. + template + struct unsew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart) + { + CGAL_assertion(2<=i && i<=Map::dimension); + CGAL_assertion( adart!=NULL && !adart->is_free(i) ); + + std::stack > todegroup; + + CMap_dart_iterator_of_involution it(amap, adart); + while ( it.cont() ) + { + todegroup.push(Couple_dart_and_dim + (it,it->beta(i),i)); + amap.unlink_beta(it, i); + ++it; + } + + while (!todegroup.empty() ) + { + Couple_dart_and_dim c=todegroup.top(); + todegroup.pop(); + amap.degroup_all_attributes_except(c.d1,c.d2,c.dim); + } + } + }; + + /// Functor used to 1-unsew one dart. + template + struct unsew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart) + { + CGAL_assertion( adart!=NULL && !adart->is_free(1) ); + typename Map::Dart_handle d2 = NULL; + + int mark = amap.get_new_mark(); + std::vector dartv; + for (CMap_dart_iterator_basic_of_cell it(amap,adart,mark); + it.cont(); ++it) + { + amap.mark(*it,mark); + dartv.push_back(*it); + } + + { + CMap_dart_iterator_of_involution it(amap, adart); + while ( it.cont() ) + { + if ( amap.is_marked(*it,mark) ) + { d2 = it->beta(1); amap.template unlink_beta<1>(*it); } + else + { d2 = it->beta(0); amap.template unlink_beta<0>(*it); } + amap.degroup_all_attributes_except(*it,d2,1); + ++it; + } + } + + for (typename std::vector::iterator + it=dartv.begin(); it!=dartv.end(); ++it) + { amap.unmark(*it,mark); } + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + amap.free_mark(mark); + } + }; + + /// Functor used to 1-unsew one dart. + template + struct unsew_functor{ + static void run(Map& amap,typename Map::Dart_handle adart) + { + CGAL_assertion( adart!=NULL && !adart->is_free(0) ); + typename Map::Dart_handle d2 = NULL; + + int mark = amap.get_new_mark(); + std::vector dartv; + for (CMap_dart_iterator_basic_of_cell it(amap,adart,mark); + it.cont(); ++it) + { + amap.mark(*it,mark); + dartv.push_back(*it); + } + + { + CMap_dart_iterator_of_involution it(amap, adart); + while ( it.cont() ) + { + if ( amap.is_marked(*it,mark) ) + { d2 = it->beta(0); amap.template unlink_beta<0>(*it); } + else + { d2 = it->beta(1); amap.template unlink_beta<1>(*it); } + amap.degroup_all_attributes_except(*it,d2,1); + ++it; + } + } + + for (typename std::vector::iterator + it=dartv.begin(); it!=dartv.end(); ++it) + { amap.unmark(*it,mark); } + CGAL_assertion( amap.is_whole_map_unmarked(mark) ); + amap.free_mark(mark); + } + }; + + /// Functor used to i-link two darts, 2<=i<=dimension. + template + struct basic_link_beta_functor{ + static void run(Map&,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + CGAL_assertion(adart1 != NULL && adart2 != NULL && adart1!=adart2); + CGAL_assertion( i>=2 && i<=Map::dimension ); + adart1->basic_link_beta(adart2, i); + adart2->basic_link_beta(adart1, i); + } + }; + + /// Functor used to 0-link two darts. + template + struct basic_link_beta_functor{ + static void run(Map&,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + CGAL_assertion(adart1 != NULL && adart2 != NULL ); + adart1->basic_link_beta(adart2, 0); + adart2->basic_link_beta(adart1, 1); + } + }; + + /// Functor used to 1-link two darts. + template + struct basic_link_beta_functor{ + static void run(Map& ,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + CGAL_assertion(adart1 != NULL && adart2 != NULL); + adart1->basic_link_beta(adart2, 1); + adart2->basic_link_beta(adart1, 0); + } + }; + + /// Functor used to i-unlink one dart. + template + struct unlink_beta_functor{ + static void run(Map&,typename Map::Dart_handle adart) + { + CGAL_assertion(adart != NULL && !adart->is_free(i)); + CGAL_assertion(2<=i && i<=Map::dimension); + adart->beta(i)->unlink_beta(i); + adart->unlink_beta(i); + } + }; + + /// Functor used to 0-unlink one dart. + template + struct unlink_beta_functor{ + static void run(Map&,typename Map::Dart_handle adart) + { + CGAL_assertion(adart != NULL && !adart->is_free(0)); + adart->beta(0)->unlink_beta(1); + adart->unlink_beta(0); + } + }; + + /// Functor used to 1-unlink one dart. + template + struct unlink_beta_functor{ + static void run(Map&,typename Map::Dart_handle adart) + { + CGAL_assertion(adart != NULL && !adart->is_free(1)); + adart->beta(1)->unlink_beta(0); + adart->unlink_beta(1); + } + }; + + // Functor used to group one attribute of two given darts + template + struct Group_one_attribute_functor + { + static void run(CMap* amap, + typename CMap::Dart_handle adart1, + typename CMap::Dart_handle adart2) + { + CGAL_assertion(amap!=NULL); + amap->template group_enabled_attribute(adart1,adart2); + } + }; + + // Specialization for i-attributes disabled. + template + struct Group_one_attribute_functor + { + static void run(CMap*, + typename CMap::Dart_handle, + typename CMap::Dart_handle) + {} + }; + + // Functor used to degroup one attribute of two given darts + template + struct Degroup_one_attribute_functor + { + static bool run(CMap* amap, + typename CMap::Dart_handle adart1, + typename CMap::Dart_handle adart2) + { + CGAL_assertion(amap!=NULL); + return amap->template degroup_enabled_attribute + (adart1,adart2); + } + }; + + // Specialization for i-attributes disabled. + template + struct Degroup_one_attribute_functor + { + static bool run(CMap*, + typename CMap::Dart_handle, + typename CMap::Dart_handle) + { return false; } + }; + + // Functor used to degroup one attribute of one dart + template + struct Degroup_one_attribute_of_dart_functor + { + static bool run(CMap* amap, + typename CMap::Dart_handle adart1, + typename CMap::Dart_handle adart2) + { + CGAL_assertion(amap!=NULL); + return amap->template degroup_enabled_attribute_of_dart + (adart1,adart2); + } + }; + + // Specialization for i-attributes disabled. + template + struct Degroup_one_attribute_of_dart_functor + { + static bool run(CMap*, + typename CMap::Dart_handle, + typename CMap::Dart_handle) + { return false; } + }; + + /// Functor used to call decrease_attribute_ref_counting + /// on each i-cell attribute enabled + template + struct Decrease_attribute_functor + { + template + static void run(Map* amap, typename Map::Dart_handle adart) + { amap->template + decrease_attribute_ref_counting(adart/*,Tag_true()*/); } + }; + + /// Functor used to call update_dart_of_attribute + /// on each i-cell attribute enabled + template + struct Update_dart_of_attribute_functor + { + template + static void run(Map* amap, typename Map::Dart_handle ah, int amark) + { amap->template update_dart_of_attribute(ah,amark); } + }; + + /// Functor used to reserve one mark for each enabled attribute. + template + struct Reserve_mark_functor + { + template + static void run(const Map* amap, std::vector* marks) + { (*marks)[i] = amap->get_new_mark(); } + }; + + /// Functor used to test if a cell is valid + template + struct Test_is_valid_attribute_functor + { + template + static void run(const Map* amap, + typename Map::Dart_const_handle adart, + std::vector* marks, bool *ares) + { + if (!amap->template is_valid_attribute(adart,(*marks)[i]) ) + { + (*ares)=false; + std::cerr << "Map not valid: a "< + struct Count_cell_functor + { + template + static void run( const Map* amap, + typename Map::Dart_const_handle adart, + std::vector* amarks, + std::vector* ares ) + { + if ( (*amarks)[i]!=-1 && !amap->is_marked(adart, (*amarks)[i]) ) + { + ++ (*ares)[i]; + mark_cell(*amap, adart, (*amarks)[i]); + } + } + }; + + // Functor used to group the two n-attributes of the two darts, except the + // attribute of adim (adim==-1 || 1<=adim<=dimension) + template + struct Group_attribute_functor_run + { + static void run(Map* amap, + typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2, int adim) + { + if ( i!=adim ) + { + amap->template group_enabled_attribute + ::type> + (adart1, adart2); + } + } + }; + + template + struct Group_attribute_functor_run + { + static void run(CMap* amap, + typename CMap::Dart_handle adart1, + typename CMap::Dart_handle adart2, int adim) + { + typename CMap::Dart_handle od = adart1->other_extremity(); + if ( od!=NULL ) + { + amap->template group_enabled_attribute + <0, typename CMap::Helper::template Attribute_type<0>::type> + (od, adart2); + } + + if ( adim!=1 ) + { + od = adart2->other_extremity(); + if ( od!=NULL ) + amap->template group_enabled_attribute + <0, typename CMap::Helper::template Attribute_type<0>::type> + (adart1, od); + } + } + }; + + template + struct Group_attribute_functor + { + template + static void run(Map* amap, + typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2, int adim) + { + CGAL_assertion( adim==-1 || + (1<=adim && (unsigned int)adim<=Map::dimension) ); + Group_attribute_functor_run::run(amap,adart1,adart2,adim); + } + }; + + // Functor used to degroup the two n-attributes of the two darts, except the + // attribute of adim + template + struct Degroup_attribute_functor_run + { + static void run(CMap* amap, + typename CMap::Dart_handle adart1, + typename CMap::Dart_handle adart2, int adim) + { + CGAL_assertion( adim==-1 || + (1<=adim && (unsigned int)adim<=CMap::dimension) ); + if (i!=adim ) + { + amap->template degroup_enabled_attribute + ::type> + (adart1, adart2); + } + } + }; + template + struct Degroup_attribute_functor_run + { + static void run(CMap* amap, + typename CMap::Dart_handle adart1, + typename CMap::Dart_handle adart2, int adim) + { + CGAL_assertion( adim==-1 || + (1<=adim && (unsigned int)adim<=CMap::dimension) ); + typename CMap::Dart_handle od = adart1->other_extremity(); + if ( od!=NULL ) + amap->template degroup_enabled_attribute + <0, typename CMap::Helper::template Attribute_type<0>::type > + (od, adart2); + + if ( adim!=1 ) + { + od = adart2->other_extremity(); + if ( od!=NULL ) + { + amap->template degroup_enabled_attribute + <0, typename CMap::Helper::template Attribute_type<0>::type> + (adart1, od); + } + } + } + }; + template + struct Degroup_attribute_functor + { + template + static void run(Map* amap,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2, int adim) + { + Degroup_attribute_functor_run::run(amap,adart1,adart2,adim); + } + }; + + // Functor which call operator() on the cell_attribute... + template + struct Apply_cell_functor + { + static void run(Cell_attribute& acell1, Cell_attribute& acell2) + { + Functor() (acell1,acell2); + } + }; + //...except for Null_functor. + template + struct Apply_cell_functor + { + static void run(Cell_attribute&, Cell_attribute&) + {} + }; + + /// Functor used for link_beta to update the attributes of + /// adart2 on the attributes of this dart, except for adimension-attributes. + template + struct Group_attribute_functor_of_dart_run + { + static void run(CMap* amap, + typename CMap::Dart_handle dh1, + typename CMap::Dart_handle dh2, + int adim) + { + CGAL_assertion( adim==-1 || + (0<=adim && (unsigned int)adim<=CMap::dimension) ); + if ( adim!=i ) + { + amap->template group_enabled_attribute_of_dart + ::type> + (dh1, dh2); + } + } + }; + template + struct Group_attribute_functor_of_dart_run + { + static void run(CMap* amap, + typename CMap::Dart_handle dh1, + typename CMap::Dart_handle dh2, + int adim) + { + CGAL_assertion( adim==-1 || + (0<=adim && (unsigned int)adim<=CMap::dimension) ); + + if ( adim!=0 ) + { + typename CMap::Dart_handle od = dh1->other_extremity(); + if ( od!=NULL ) + { + typename CMap::Helper::template Attribute_handle<0>::type + a1=od->template attribute<0>(); + if ( a1!=NULL && a1!=dh2->template attribute<0>() ) + amap->template set_attribute_of_dart<0>(dh2, a1); + } + } + + if ( adim!=1 ) + { + typename CMap::Dart_handle od = dh2->other_extremity(); + if ( od!=NULL && dh1->template attribute<0>()==NULL ) + { + typename CMap::Helper::template Attribute_handle<0>::type + a2=od->template attribute<0>(); + if ( a2!=NULL ) + amap->template set_attribute_of_dart<0>(dh1, a2); + } + } + } + }; + + template + struct Group_attribute_functor_of_dart + { + template + static void run(CMap* amap, + typename CMap::Dart_handle adart1, + typename CMap::Dart_handle adart2, int adim) + { + CGAL_assertion( adim==-1 || + (0<=adim && (unsigned int)adim<=CMap::dimension) ); + Group_attribute_functor_of_dart_run::run(amap,adart1,adart2,adim); + } + }; + + /// Functor used to i-link two darts, 2<=i<=dimension. + template + struct link_beta_functor{ + static void run(CMap& amap,typename CMap::Dart_handle adart1, + typename CMap::Dart_handle adart2) + { + CGAL_assertion(adart1 != NULL && adart2 != NULL && adart1!=adart2 ); + CGAL_assertion( 2<=i && i<=CMap::dimension ); + adart1->basic_link_beta(adart2, i); + adart2->basic_link_beta(adart1, i); + CMap::Helper::template Foreach_enabled_attributes + >::run(&amap,adart1,adart2,i); + } + }; + + /// Functor used to 0-link two darts. + template + struct link_beta_functor{ + static void run(Map& amap,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + CGAL_assertion(adart1 != NULL && adart2 != NULL); + adart1->basic_link_beta(adart2,0); + adart2->basic_link_beta(adart1, 1); + Map::Helper::template Foreach_enabled_attributes + >::run(&amap,adart1,adart2,0); + } + }; + + /// Functor used to 1-link two darts. + template + struct link_beta_functor{ + static void run(Map& amap,typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + CGAL_assertion(adart1 != NULL && adart2 != NULL); + adart1->basic_link_beta(adart2,1); + adart2->basic_link_beta(adart1,0); + Map::Helper::template Foreach_enabled_attributes + >::run(&amap,adart1,adart2,1); + } + }; + + // Functor used to call the On_split functor between the two given darts. + template::type> + struct Call_split_functor + { + static void run(typename Map::Dart_handle adart1, + typename Map::Dart_handle adart2) + { + Apply_cell_functor::type, + typename Map::Helper::template Attribute_type::type::On_split>::run + (*(adart1->template attribute()), + *(adart2->template attribute())); + } + }; + + // Specialization for disabled attributes. + template + struct Call_split_functor + { + static void run(typename Map::Dart_handle, + typename Map::Dart_handle) + {} + }; + + /// Functor for counting the memory occupation of attributes + /// Be careful not reentrant !!! TODO a Foreach_enabled_attributes + /// taking an instance of a functor as argument allowing to compute and return + /// values. + template + struct Count_bytes_one_attribute_functor + { + template + static void run( const Map* amap ) + { + res += amap->template attributes().capacity()* + sizeof(typename Map::template Attribute_type::type); + } + + static typename Map::size_type res; + }; + template + typename Map::size_type Count_bytes_one_attribute_functor::res = 0; + + template + struct Count_bytes_all_attributes_functor + { + static typename Map::size_type run( const Map& amap ) + { + Count_bytes_one_attribute_functor::res = 0; + Map::Helper::template Foreach_enabled_attributes + >::run(&amap); + return Count_bytes_one_attribute_functor::res; + } + }; + + } // namespace internal +} // namespace CGAL + +#endif // CGAL_COMBINATORIAL_MAP_FUNCTORS_H // +// EOF // diff --git a/Combinatorial_map/include/CGAL/internal/Combinatorial_map_utility.h b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_utility.h new file mode 100644 index 00000000000..1e871349ca2 --- /dev/null +++ b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_utility.h @@ -0,0 +1,1667 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (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; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// 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) : Guillaume Damiand +// +#ifndef CGAL_INTERNAL_COMBINATORIAL_MAP_UTILITY_H +#define CGAL_INTERNAL_COMBINATORIAL_MAP_UTILITY_H 1 + +#include +#include +#include +#include + +#ifdef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES +#include +#include +#endif + + +namespace CGAL +{ + // struct Disabled {}; // If we want to use CGAL::Disabled for disabled attributes + // typedef CGAL::Void Disabled; + // typedef void Disabled; // If we wand to use void, does not compile on windows + + namespace internal + { + // There is a problem on windows to handle tuple containing void. To solve this, we + // transform such a tuple in tuple containing Disabled. + template + struct Convert_void + { typedef T type; }; + + template<> + struct Convert_void + { typedef CGAL::Void type; }; + + #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template + struct Convert_tuple_with_void; + + template + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple::type... > type; + }; + + template + struct My_length; + template + struct My_length > + { + static const int value = My_length >::value + 1; + }; + + template<> + struct My_length > + { + static const int value = 0; + }; + + +#else //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template + struct Convert_tuple_with_void; + + template <> + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple<> type; + }; + template + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple::type > type; + }; + template + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple::type, + typename Convert_void::type> type; + }; + template + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple::type, + typename Convert_void::type, + typename Convert_void::type> type; + }; + template + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type> type; + }; + template + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type> type; + }; + template + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type> type; + }; + template + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type> type; + }; + template + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type> type; + }; + template + struct Convert_tuple_with_void > + { + typedef CGAL::cpp0x::tuple::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type, + typename Convert_void::type> type; + }; + template + struct My_length; + + template <> + struct My_length > + { + static const int value = 0; + }; + template + struct My_length > + { + static const int value = 1; + }; + template + struct My_length > + { + static const int value = 2; + }; + template + struct My_length > + { + static const int value = 3; + }; + template + struct My_length > + { + static const int value = 4; + }; + template + struct My_length > + { + static const int value = 5; + }; + template + struct My_length > + { + static const int value = 6; + }; + template + struct My_length > + { + static const int value = 7; + }; + template + struct My_length > + { + static const int value = 8; + }; + template + struct My_length > + { + static const int value = 9; + }; +#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES +//count the number of time a given type is present in a tuple +template +struct Number_of_type_in_tuple; + +template +struct Number_of_type_in_tuple >{ + static const int value=Number_of_type_in_tuple >::value+1; +}; + +template +struct Number_of_type_in_tuple >{ + static const int value=Number_of_type_in_tuple >::value; +}; + +template +struct Number_of_type_in_tuple >{ + static const int value=0; +}; +#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + +//count the number of different types from Type is present in a tuple +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES +template +struct Number_of_different_type_in_tuple; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value=Number_of_different_type_in_tuple >::value+1; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value=Number_of_different_type_in_tuple >::value; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value=0; +}; +#else +template +struct Number_of_different_type_in_tuple; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value=0; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value=boost::is_same::value?0:1; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value= (boost::is_same::value?0:1) + Number_of_different_type_in_tuple >::value; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value= (boost::is_same::value?0:1) + Number_of_different_type_in_tuple >::value; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value= (boost::is_same::value?0:1) + Number_of_different_type_in_tuple >::value; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value= (boost::is_same::value?0:1) + Number_of_different_type_in_tuple >::value; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value= (boost::is_same::value?0:1) + Number_of_different_type_in_tuple >::value; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value= (boost::is_same::value?0:1) + Number_of_different_type_in_tuple >::value; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value= (boost::is_same::value?0:1) + Number_of_different_type_in_tuple >::value; +}; + +template +struct Number_of_different_type_in_tuple > +{ + static const int value= (boost::is_same::value?0:1) + Number_of_different_type_in_tuple >::value; +}; +#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + + +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES +//count the number of time a given type have been found +//within a tuple, until reaching position the k'th type of the tuple. +//dim is the total size of the tuple +template ::value-1> +struct Nb_type_in_tuple_up_to_k; + +template +struct Nb_type_in_tuple_up_to_k,dim>{ + static const int pos= Nb_type_in_tuple_up_to_k,dim>::pos - 1; + + static const int value = + ( pos==k ) ? ( boost::is_same::value ? 0:-dim-1 ) + : ( ( pos::value ? 1:0 ) + + Nb_type_in_tuple_up_to_k,dim >::value) + :0 + ); +}; + +template +struct Nb_type_in_tuple_up_to_k,dim >{ + static const int pos=dim; + static const int value= pos==k? boost::is_same::value?0:-dim-1 : 0; +}; +#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + +//count the number of time a type different from Type have been found +//within a tuple, until reaching position the k'th type of the tuple. +//dim is the total size of the tuple +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES +template ::value-1> +struct Nb_type_different_in_tuple_up_to_k; + +template +struct Nb_type_different_in_tuple_up_to_k,dim>{ + static const int pos= + Nb_type_different_in_tuple_up_to_k,dim >::pos - 1; + + static const int value = + ( pos==k ) ? ( boost::is_same::value ? -dim-1 : 0 ) + : ( ( pos::value ? 0:1 ) + + Nb_type_different_in_tuple_up_to_k,dim >::value) + :0 + ); +}; + +template +struct Nb_type_different_in_tuple_up_to_k,dim >{ + static const int pos=dim; + static const int value= pos==k? boost::is_same::value?-dim-1:0 : 0; +}; +#else +template ::value-1> +struct Nb_type_different_in_tuple_up_to_k; + +template +struct Nb_type_different_in_tuple_up_to_k,dim >{ + static const int pos=dim; + static const int value= pos==k? boost::is_same::value?-dim-1:0 : 0; +}; + +template +struct Nb_type_different_in_tuple_up_to_k,dim >{ + static const int pos= + Nb_type_different_in_tuple_up_to_k,dim >::pos - 1; + + static const int value = + ( pos==k ) ? ( boost::is_same::value ? -dim-1 : 0 ) + : ( ( pos::value ? 0:1 ) + + Nb_type_different_in_tuple_up_to_k,dim >::value) + :0 + ); +}; + +template +struct Nb_type_different_in_tuple_up_to_k,dim >{ + static const int pos= + Nb_type_different_in_tuple_up_to_k,dim >::pos - 1; + + static const int value = + ( pos==k ) ? ( boost::is_same::value ? -dim-1 : 0 ) + : ( ( pos::value ? 0:1 ) + + Nb_type_different_in_tuple_up_to_k,dim >::value) + :0 + ); +}; + + +template +struct Nb_type_different_in_tuple_up_to_k,dim >{ + static const int pos= + Nb_type_different_in_tuple_up_to_k,dim >::pos - 1; + + static const int value = + ( pos==k ) ? ( boost::is_same::value ? -dim-1 : 0 ) + : ( ( pos::value ? 0:1 ) + + Nb_type_different_in_tuple_up_to_k,dim >::value) + :0 + ); +}; + +template +struct Nb_type_different_in_tuple_up_to_k,dim >{ + static const int pos= + Nb_type_different_in_tuple_up_to_k,dim >::pos - 1; + + static const int value = + ( pos==k ) ? ( boost::is_same::value ? -dim-1 : 0 ) + : ( ( pos::value ? 0:1 ) + + Nb_type_different_in_tuple_up_to_k,dim >::value) + :0 + ); +}; + +template +struct Nb_type_different_in_tuple_up_to_k,dim >{ + static const int pos= + Nb_type_different_in_tuple_up_to_k,dim >::pos - 1; + + static const int value = + ( pos==k ) ? ( boost::is_same::value ? -dim-1 : 0 ) + : ( ( pos::value ? 0:1 ) + + Nb_type_different_in_tuple_up_to_k,dim >::value) + :0 + ); +}; + +template +struct Nb_type_different_in_tuple_up_to_k,dim >{ + static const int pos= + Nb_type_different_in_tuple_up_to_k,dim >::pos - 1; + + static const int value = + ( pos==k ) ? ( boost::is_same::value ? -dim-1 : 0 ) + : ( ( pos::value ? 0:1 ) + + Nb_type_different_in_tuple_up_to_k,dim >::value) + :0 + ); +}; + +template +struct Nb_type_different_in_tuple_up_to_k,dim >{ + static const int pos= + Nb_type_different_in_tuple_up_to_k,dim >::pos - 1; + + static const int value = + ( pos==k ) ? ( boost::is_same::value ? -dim-1 : 0 ) + : ( ( pos::value ? 0:1 ) + + Nb_type_different_in_tuple_up_to_k,dim >::value) + :0 + ); +}; + +template +struct Nb_type_different_in_tuple_up_to_k,dim >{ + static const int pos= + Nb_type_different_in_tuple_up_to_k,dim >::pos - 1; + + static const int value = + ( pos==k ) ? ( boost::is_same::value ? -dim-1 : 0 ) + : ( ( pos::value ? 0:1 ) + + Nb_type_different_in_tuple_up_to_k,dim >::value) + :0 + ); +}; +#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + +//Convert a tuple of T... to a tuple of Functor::type... +template