diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index 286b53f6c33..9f991d5ab2c 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -51,12 +51,6 @@ namespace CGAL { 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; @@ -907,95 +901,6 @@ namespace CGAL { else basic_link_beta_for_involution(adart1, adart2, i); } - /** 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) - { - if ( i==0 ) unlink_beta_0(adart); - else if ( i==1 ) unlink_beta_1(adart); - else unlink_beta_for_involution(adart, i); - } - void unlink_beta(Dart_handle adart, unsigned int i) - { - if ( i==0 ) unlink_beta_0(adart); - else if ( i==1 ) unlink_beta_1(adart); - else unlink_beta_for_involution(adart, i); - } - - /** Double unlink a dart with beta 0. - * 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. - */ - void unlink_beta_0(Dart_handle adart) - { - CGAL_assertion(adart != NULL && !adart->is_free(0)); - adart->beta(0)->unlink_beta(1); - adart->unlink_beta(0); - } - - /** Double unlink a dart with beta 1. - * beta1(\em adart) is 0-unlinked and \em adart is 1-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. - */ - void unlink_beta_1(Dart_handle adart) - { - CGAL_assertion(adart != NULL && !adart->is_free(1)); - adart->beta(1)->unlink_beta(0); - adart->unlink_beta(1); - } - - /** 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_for_involution(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) - { - if ( i==0 ) link_beta_0(adart1, adart2); - else if ( i==1 ) link_beta_1(adart1, adart2); - else link_beta_for_involution(adart1, adart2, i); - } - void link_beta(Dart_handle adart1, Dart_handle adart2, unsigned int i) - { - if ( i==0 ) link_beta_0(adart1, adart2); - else if ( i==1 ) link_beta_1(adart1, adart2); - else link_beta_for_involution(adart1, adart2, i); - } - /** Double link two darts, and update the NULL attributes. * \em adart1 is 0-linked to \em adart2 and \em adart2 is 1-linked * with \em adart1. The NULL attributes of \em adart1 are updated to @@ -1060,6 +965,29 @@ namespace CGAL { adart2->basic_link_beta(adart1, 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) + { + if ( i==0 ) link_beta_0(adart1, adart2); + else if ( i==1 ) link_beta_1(adart1, adart2); + else link_beta_for_involution(adart1, adart2, i); + } + void link_beta(Dart_handle adart1, Dart_handle adart2, unsigned int i) + { + if ( i==0 ) link_beta_0(adart1, adart2); + else if ( i==1 ) link_beta_1(adart1, adart2); + else link_beta_for_involution(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 @@ -1077,6 +1005,167 @@ namespace CGAL { else basic_link_beta(adart1, adart2); } + /** Double unlink a dart with beta 0. + * 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. + */ + void unlink_beta_0(Dart_handle adart) + { + CGAL_assertion(adart != NULL && !adart->is_free(0)); + adart->beta(0)->unlink_beta(1); + adart->unlink_beta(0); + } + + /** Double unlink a dart with beta 1. + * beta1(\em adart) is 0-unlinked and \em adart is 1-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. + */ + void unlink_beta_1(Dart_handle adart) + { + CGAL_assertion(adart != NULL && !adart->is_free(1)); + adart->beta(1)->unlink_beta(0); + adart->unlink_beta(1); + } + + /** 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_for_involution(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 unlink a dart with beta i. + * betai(\em adart) is i-1-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 + */ + template + void unlink_beta(Dart_handle adart) + { + if ( i==0 ) unlink_beta_0(adart); + else if ( i==1 ) unlink_beta_1(adart); + else unlink_beta_for_involution(adart, i); + } + void unlink_beta(Dart_handle adart, unsigned int i) + { + if ( i==0 ) unlink_beta_0(adart); + else if ( i==1 ) unlink_beta_1(adart); + else unlink_beta_for_involution(adart, i); + } + + /** Test if it is possible to sew by beta1 the two given darts + * @param adart1 the first dart. + * @param adart2 the second dart. + * @return true iff \em adart1 can be 1-sewn with \em adart2. + */ + bool is_sewable_1(Dart_const_handle adart1, Dart_const_handle adart2) const + { + 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(*this, adart1); + CMap_dart_const_iterator_of_involution_inv I2(*this, 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<=Self::dimension; ++j) + { + if ( I1->is_free(j)!=I2->is_free(j) ) + { + res = false; + } + } + ++I1; ++I2; + } + if (I1.cont() != I2.cont()) + res = false; + + return res; + } + + /** Test if it is possible to sew by beta0 the two given darts + * @param adart1 the first dart. + * @param adart2 the second dart. + * @return true iff \em adart1 can be 0-sewn with \em adart2. + */ + bool is_sewable_0(Dart_const_handle adart1, Dart_const_handle adart2) const + { return is_sewable_1(adart2, adart1); } + + /** Test if it is possible to sew by betai the two given darts + * for 2<=i<=dimension. + * @param adart1 the first dart. + * @param adart2 the second dart. + * @return true iff \em adart1 can be 1-sewn with \em adart2. + */ + template + bool is_sewable_for_involution(Dart_const_handle adart1, + Dart_const_handle adart2) const + { + CGAL_static_assertion(2<=i && i<=Self::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(*this, adart1); + CMap_dart_const_iterator_of_involution_inv I2(*this, 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<=Self::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; + } + /** Test if it is possible to sew by betai the two given darts * @param adart1 the first dart. * @param adart2 the second dart. @@ -1084,7 +1173,82 @@ namespace CGAL { */ template bool is_sewable(Dart_const_handle adart1, Dart_const_handle adart2) const - { return internal::is_sewable_functor::run(*this,adart1,adart2); } + { + if ( i==0 ) return is_sewable_0(adart1, adart2); + else if ( i==1 ) return is_sewable_1(adart1, adart2); + else return is_sewable_for_involution(adart1, adart2); + } + + /** Topological sew by beta1 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_1(adart1, adart2). + */ + void topo_sew_1(Dart_handle adart1, Dart_handle adart2) + { + CGAL_assertion( (is_sewable_1(adart1,adart2)) ); + + int mark = get_new_mark(); + std::vector dartv; + for (CMap_dart_iterator_basic_of_cell it(*this,adart1,mark); + it.cont(); ++it) + { + mark(*it,mark); + dartv.push_back(*it); + } + + CMap_dart_iterator_of_involution I1(*this, adart1); + CMap_dart_iterator_of_involution_inv I2(*this, adart2); + while ( I1.cont() ) + { + if ( is_marked(*I1,mark) ) + basic_link_beta_1(*I1, *I2); + else + basic_link_beta_0(*I1, *I2); + ++I1; ++I2; + } + + for (typename std::vector::iterator + it=dartv.begin(); it!=dartv.end(); ++it) + { unmark(*it,mark); } + CGAL_assertion( is_whole_map_unmarked(mark) ); + free_mark(mark); + } + + /** Topological sew by beta0 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_0(adart1, adart2). + */ + void topo_sew_0(Dart_handle adart1, Dart_handle adart2) + { topo_sew_1(adart2, adart1); } + + /** 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 2<=i<=dimension + * @pre is_sewable_for_involution(adart1, adart2). + */ + template + void topo_sew_for_involution(Dart_handle adart1, Dart_handle adart2) + { + CGAL_static_assertion(2<=i && i<=Self::dimension); + CGAL_assertion( (is_sewable_for_involution(adart1,adart2)) ); + + CMap_dart_iterator_of_involution I1(*this, adart1); + CMap_dart_iterator_of_involution_inv I2(*this, adart2); + while ( I1.cont() ) + { + basic_link_beta_for_involution(I1, I2, i); + ++I1; ++I2; + } + } /** Topological sew by betai the two given darts plus all the required darts * to satisfy the combinatorial map validity: but do not update attributes @@ -1095,7 +1259,136 @@ namespace CGAL { */ template void topo_sew(Dart_handle adart1, Dart_handle adart2) - { return internal::topo_sew_functor::run(*this,adart1,adart2); } + { + if ( i==0 ) topo_sew_0(adart1, adart2); + else if ( i==1 ) topo_sew1(adart1, adart2); + else topo_sew_for_involution(adart1, adart2); + } + + /** Sew by beta0 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_0(adart1, adart2). + * @post is_valid() + */ + void sew_0(Dart_handle adart1, Dart_handle adart2) + { + CGAL_assertion( (is_sewable_0(adart1,adart2)) ); + + int m = get_new_mark(); + std::vector dartv; + for (CMap_dart_iterator_basic_of_cell it(*this,adart1,m); + it.cont(); ++it) + { + mark(it,m); + dartv.push_back(it); + } + + CMap_dart_iterator_of_involution I1(*this, adart1); + CMap_dart_iterator_of_involution_inv I2(*this, adart2); + while ( I1.cont() ) + { + Dart_handle od1=I1->other_extremity(); + Dart_handle od2=I2->other_extremity(); + if (od1!=NULL && od2!=NULL) + group_all_attributes_except(od1, od2, 1); + ++I1; ++I2; + } + + I1.rewind(); I2.rewind(); + while ( I1.cont() ) + { + if ( is_marked(I1,m) ) + basic_link_beta_0(I1, I2); + else + basic_link_beta_1(I1, I2); + ++I1; ++I2; + } + + for (typename std::vector::iterator + it=dartv.begin(); it!=dartv.end(); ++it) + { unmark(*it,m); } + CGAL_assertion( is_whole_map_unmarked(m) ); + free_mark(m); + } + + /** Sew by beta1 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_1(adart1, adart2). + * @post is_valid() + */ + void sew_1(Dart_handle adart1, Dart_handle adart2) + { + CGAL_assertion( (is_sewable_1(adart1,adart2)) ); + int m = get_new_mark(); + std::vector dartv; + for (CMap_dart_iterator_basic_of_cell it(*this,adart1,m); + it.cont(); ++it) + { + mark(it,m); + dartv.push_back(it); + } + + CMap_dart_iterator_of_involution I1(*this, adart1); + CMap_dart_iterator_of_involution_inv I2(*this, adart2); + while ( I1.cont() ) + { + group_all_attributes_except(I1,I2,1); + ++I1; ++I2; + } + + I1.rewind(); I2.rewind(); + while ( I1.cont() ) + { + if ( is_marked(I1,m) ) + basic_link_beta_1(I1, I2); + else + basic_link_beta_0(I1, I2); + ++I1; ++I2; + } + + for (typename std::vector::iterator + it=dartv.begin(); it!=dartv.end(); ++it) + { unmark(*it,m); } + CGAL_assertion( is_whole_map_unmarked(m) ); + free_mark(m); + } + + /** 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). + * @pre 2<=i<=dimension. + * @post is_valid() + */ + template + void sew_for_involution(Dart_handle adart1, Dart_handle adart2) + { + CGAL_static_assertion(2<=i && i<=dimension); + CGAL_assertion( (is_sewable_for_involution(adart1,adart2)) ); + + CMap_dart_iterator_of_involution I1(*this, adart1); + CMap_dart_iterator_of_involution_inv I2(*this, adart2); + while ( I1.cont() ) + { + group_all_attributes_except(I1,I2,i); + ++I1; ++I2; + } + + I1.rewind(); I2.rewind(); + while ( I1.cont() ) + { + basic_link_beta_for_involution(I1, I2, i); + ++I1; ++I2; + } + } /** Sew by betai the two given darts plus all the required darts * to satisfy the combinatorial map validity, and updates enabled @@ -1107,7 +1400,11 @@ namespace CGAL { */ template void sew(Dart_handle adart1, Dart_handle adart2) - { return internal::sew_functor::run(*this,adart1,adart2); } + { + if ( i==0 ) sew_0(adart1, adart2); + else if ( i==1 ) sew_1(adart1, adart2); + else sew_for_involution(adart1, adart2); + } /** Sew by betai the two given darts plus all the required darts * to satisfy the combinatorial map validity. Enabled attributes @@ -1120,8 +1417,8 @@ namespace CGAL { template void sew(Dart_handle adart1, Dart_handle adart2, bool update_attributes) { - if ( update_attributes ) sew(adart1, adart2); - else topo_sew(adart1, adart2); + if ( update_attributes ) sew(adart1, adart2); + else topo_sew(adart1, adart2); } /** Topological unsew by betai the given dart plus all the required darts diff --git a/Combinatorial_map/include/CGAL/internal/Combinatorial_map_functors.h b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_functors.h index 0330bc1604e..b0ce7b5b2e3 100644 --- a/Combinatorial_map/include/CGAL/internal/Combinatorial_map_functors.h +++ b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_functors.h @@ -42,279 +42,6 @@ namespace CGAL { 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_static_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,adart2,adart1); } - }; - - /// 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_static_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,adart2,adart1); } - }; - - /// 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_static_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_for_involution(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() ) - { - typename Map::Dart_handle od1=I1->other_extremity(); - typename Map::Dart_handle od2=I2->other_extremity(); - if (od1!=NULL && od2!=NULL) - amap.group_all_attributes_except(od1, od2, 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{