diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index e3f74142174..09c6235a9ad 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -167,6 +167,8 @@ namespace CGAL { this->mnb_times_reserved_marks[i] = 0; } + this->automatic_attributes_management = true; + init_dart(null_dart_handle); CGAL_assertion(number_of_darts()==0); @@ -1159,8 +1161,8 @@ namespace CGAL { return valid; } - /// validate the map - void validate_attributes() + /// correct invalid attributes in the map + void correct_invalid_attributes() { std::vector marks(dimension+1); for ( int i=0; i<=dimension; ++i) @@ -1174,7 +1176,7 @@ namespace CGAL { itend(darts().end()); it!=itend; ++it) { Helper::template Foreach_enabled_attributes - >:: + >:: run(this,it,&marks); } @@ -3658,6 +3660,26 @@ namespace CGAL { return false; } + /** Test if the attributes of this map are automatically updated. + * @return true iff the boolean automatic_attributes_management is set to true. + */ + bool are_attributes_automatically_managed() const + { + return automatic_attributes_management; + } + + /** Sets the automatic_attributes_management boolean. + */ + void set_automatic_attributes_management(bool automatic_attributes_management) + { + if (this->automatic_attributes_management == false && automatic_attributes_management == true) + { + correct_invalid_attributes(); + } + + this->automatic_attributes_management = automatic_attributes_management; + } + protected: /// Number of times each mark is reserved. 0 if the mark is free. mutable size_type mnb_times_reserved_marks[NB_MARKS]; @@ -3680,6 +3702,9 @@ namespace CGAL { /// Number of marked darts for each used marks. mutable size_type mnb_marked_darts[NB_MARKS]; + /// Automatic management of the attributes: true means attributes are allways maintained updated + bool automatic_attributes_management; + /// Tuple of unary and binary functors (for all non void attributes). typename Helper::Split_functors m_onsplit_functors; typename Helper::Merge_functors m_onmerge_functors; diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_insertions.h b/Combinatorial_map/include/CGAL/Combinatorial_map_insertions.h index 895562b261d..42da65dcf32 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map_insertions.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_insertions.h @@ -72,7 +72,7 @@ insert_cell_0_in_cell_1( CMap& amap, typename CMap::Dart_handle adart, amap.basic_link_beta_1(*it, d1); - if (update_attributes) + if (amap.are_attributes_automatically_managed()) { // We copy all the attributes except for dim=0 CMap::Helper::template Foreach_enabled_attributes_except @@ -100,7 +100,7 @@ insert_cell_0_in_cell_1( CMap& amap, typename CMap::Dart_handle adart, amap.free_mark(m); amap.free_mark(mark); - if (update_attributes) + if (amap.are_attributes_automatically_managed()) { CGAL::internal::Degroup_attribute_functor_run:: run(&amap, adart, amap.template beta<1>(adart)); @@ -175,7 +175,7 @@ insert_cell_0_in_cell_2( CMap& amap, typename CMap::Dart_handle adart, if ( prev!=amap.null_handle ) amap.template basic_link_beta_for_involution<2>(prev, n1); - if (update_attributes) + if (amap.are_attributes_automatically_managed()) { CGAL::internal::Set_i_attribute_of_dart_functor:: run(&amap, n1, ah); @@ -201,7 +201,7 @@ insert_cell_0_in_cell_2( CMap& amap, typename CMap::Dart_handle adart, nn2=amap.create_dart(); amap.link_beta_0(amap.beta(cur, dim), nn2); amap.basic_link_beta_for_involution(n2, nn2, dim); - if (update_attributes) + if (amap.are_attributes_automatically_managed()) { CGAL::internal::Set_i_attribute_of_dart_functor:: run(&amap, nn2, ah); @@ -261,7 +261,7 @@ insert_cell_0_in_cell_2( CMap& amap, typename CMap::Dart_handle adart, amap.unmark(amap.beta(*itd, dim), treated); } if ( *itd!=adart ) - if (update_attributes) + if (amap.are_attributes_automatically_managed()) { CGAL::internal::Degroup_attribute_functor_run:: run(&amap, adart, *itd); @@ -351,7 +351,7 @@ insert_dangling_cell_1_in_cell_2( CMap& amap, (amap.beta(it1, dim, CGAL_BETAINV(s1), 2), d2, dim); } } - if (update_attributes) + if (amap.are_attributes_automatically_managed()) { CGAL::internal::Set_i_attribute_of_dart_functor:: run(&amap, d1, ah); @@ -490,7 +490,7 @@ insert_cell_1_in_cell_2(CMap& amap, amap.mark(it1,treated); } - if (update_attributes) + if (amap.are_attributes_automatically_managed()) { CGAL::internal::Degroup_attribute_functor_run::run(&amap, d1, d2); } @@ -702,7 +702,7 @@ insert_cell_2_in_cell_3(CMap& amap, InputIterator afirst, InputIterator alast, if ( withBeta3 ) { // Here we cannot use Degroup_attribute_functor_run as new darts do not // have their 3-attribute - if (update_attributes) + if (amap.are_attributes_automatically_managed()) { CGAL::internal::Degroup_attribute_functor_run:: run(&amap, first, amap.template beta<3>(first)); diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_operations.h b/Combinatorial_map/include/CGAL/Combinatorial_map_operations.h index 021692ef5ee..63f6e2200eb 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map_operations.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_operations.h @@ -361,7 +361,7 @@ namespace CGAL ++res; } - if (update_attributes) + if (amap.are_attributes_automatically_managed()) { // We group the two edges incident if they exist. if ( dg1!=amap.null_handle ) @@ -423,7 +423,7 @@ namespace CGAL } } - if (update_attributes) + if (amap.are_attributes_automatically_managed()) { // We test the split of all the incident cells for all the non // void attributes. diff --git a/Combinatorial_map/include/CGAL/internal/Combinatorial_map_internal_functors.h b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_internal_functors.h index bdf70875c5e..44787ba8f53 100644 --- a/Combinatorial_map/include/CGAL/internal/Combinatorial_map_internal_functors.h +++ b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_internal_functors.h @@ -262,80 +262,67 @@ struct Test_is_valid_attribute_functor } }; // **************************************************************************** -/// Functor used to validate an i-cell +/// Functor used to correct invalid attributes in an i-cell template -struct Validate_attribute_functor +struct Correct_invalid_attributes_functor { template static void run(CMap* amap, typename CMap::Dart_handle adart, std::vector* marks) { - // std::cout << "Validate_attribute_functor for " << i << "-cell" << std::endl; + // std::cout << "Correct_invalid_attributes_functor for " << i << "-cell" << std::endl; CGAL_static_assertion_msg(CMap::Helper::template Dimension_index::value>=0, - "Validate_attribute_functor but " + "Correct_invalid_attributes_functor but " " i-attributes are disabled"); int amark = (*marks)[i]; - if ( amap->is_marked(adart, amark) ) return; // dart already test. - typename CMap::template Attribute_handle::type a=amap->template attribute(adart); - bool found_attrib = false; + // dart already test, or without i-attribute + if ( amap->is_marked(adart, amark) ) return; + if ( a==amap->null_handle) { amap->mark(adart, amark); return; } - if (a == amap->null_handle) + // We search if all the darts of the i-cell has the same i-attrib, and we count + // the number of darts of the i-cell. + unsigned int nb=0; + bool found_dart = false; + + for ( CGAL::CMap_dart_iterator_of_cell + it(*amap, adart); it.cont(); ++it, ++nb ) { - // we search if the i-cell has a valid i-attrib - for ( CGAL::CMap_dart_iterator_of_cell - it(*amap, adart); !found_attrib && it.cont(); ++it ) + if ( a!=amap->template attribute(it) ) { - if (amap->template attribute(it) != amap->null_handle) - { - a = amap->template attribute(it); - found_attrib = true; - } + // If two different i-attributes, we could call on_split ? + amap->template set_dart_attribute(it, a); } - } - else - { - found_attrib = true; + if (it==amap->template dart_of_attribute(a)) + { + found_dart = true; + } + amap->mark(it, amark); } - if (found_attrib) + if (!found_dart) { - // std::cout << i << "-attribute found" << std::endl; - bool found_dart = false; - for ( CGAL::CMap_dart_iterator_of_cell - it(*amap, adart); it.cont(); ++it ) - { - if (a != amap->template attribute(it)) - { - // If two different i-attributes, we could call on_split ? - amap->template set_dart_attribute(it, a); - } - if (it==amap->template dart_of_attribute(a)) - { - found_dart = true; - } - - amap->mark(it, amark); - } - if (!found_dart) - { - // the current i-attrib does not belong to the i-cell - // so we affect it to the first dart of the i-cell - amap->template set_dart_of_attribute(a,adart); - } + // the current i-attrib does not belong to the i-cell + // so we affect it to the first dart of the i-cell + amap->template set_dart_of_attribute(a,adart); } - else + + // If the cells has less darts than the ref counter of the i-attribute, + // the i-attribute is shared by different cells => we duplicate it. + if ( nb!=amap->template get_attribute(a).get_nb_refs() ) { + typename CMap::template Attribute_handle::type + a2=amap->template create_attribute(amap->template get_attribute(a)); + for ( CGAL::CMap_dart_iterator_of_cell - it(*amap, adart); it.cont(); ++it ) + it(*amap, adart); it.cont(); ++it ) { - // we perform a traversal to mark all darts - amap->mark(it, amark); + amap->template set_dart_attribute(it, a2); } } } diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp index 9c498d16cff..6a40dfba6a0 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp @@ -1193,6 +1193,12 @@ void MainWindow::onMengerInc() this->mengerLevel++; + if (!mengerUpdateAttributes) + { + scene.lcc->set_update_attributes(false); + } + std::cout << "automatic_attributes_management=" << scene.lcc->are_attributes_automatically_managed() << std::endl; + std::vector edges; std::vector faces; unsigned int nbvolinit = (unsigned int)mengerVolumes.size(); @@ -1278,8 +1284,11 @@ void MainWindow::onMengerInc() update_volume_list_add(scene.lcc->attribute<3>(mengerVolumes[i])); } - std::cout << "validate scene..." << std::endl; - scene.lcc->validate_attributes(); + // validate_attributes is called in set_update_attributes + // std::cout << "validate scene..." << std::endl; + // scene.lcc->validate_attributes(); + + scene.lcc->set_update_attributes(true); } #ifdef CGAL_PROFILE_LCC_DEMO @@ -1306,16 +1315,16 @@ void MainWindow::split_edge_in_three(Dart_handle dh) LCC::Point p3 = LCC::Traits::Construct_translated_point() (p1,v2); LCC::Point p4 = LCC::Traits::Construct_translated_point() (p1,v3); - (scene.lcc)->insert_point_in_cell<1>(dh,p4,mengerUpdateAttributes); - (scene.lcc)->insert_point_in_cell<1>(dh,p3,mengerUpdateAttributes); + (scene.lcc)->insert_point_in_cell<1>(dh,p4); + (scene.lcc)->insert_point_in_cell<1>(dh,p3); } void MainWindow::split_face_in_three(Dart_handle dh) { CGAL::insert_cell_1_in_cell_2(*(scene.lcc),scene.lcc->beta(dh,1,1,1), - scene.lcc->beta(dh,0,0),mengerUpdateAttributes); + scene.lcc->beta(dh,0,0)); CGAL::insert_cell_1_in_cell_2(*(scene.lcc),scene.lcc->beta(dh,1,1), - scene.lcc->beta(dh,0),mengerUpdateAttributes); + scene.lcc->beta(dh,0)); } void MainWindow::split_face_in_nine(Dart_handle dh) @@ -1323,10 +1332,10 @@ void MainWindow::split_face_in_nine(Dart_handle dh) Dart_handle d2 = scene.lcc->beta(dh,1,1,1,1,1,1,1); Dart_handle e2= CGAL::insert_cell_1_in_cell_2(*(scene.lcc), - scene.lcc->beta(dh,1,1),d2,mengerUpdateAttributes); + scene.lcc->beta(dh,1,1),d2); Dart_handle e1= CGAL::insert_cell_1_in_cell_2(*(scene.lcc), scene.lcc->beta(dh,1), - scene.lcc->beta(d2,1),mengerUpdateAttributes); + scene.lcc->beta(d2,1)); split_edge_in_three(e1); split_edge_in_three(e2); @@ -1359,12 +1368,12 @@ void MainWindow::split_vol_in_three(Dart_handle dh, bool removecenter) scene.lcc->beta(dh,2,1,1,2,1,1,2) ); Dart_handle f1= - insert_cell_2_in_cell_3(*(scene.lcc),edges1.begin(),edges1.end(),mengerUpdateAttributes); + insert_cell_2_in_cell_3(*(scene.lcc),edges1.begin(),edges1.end()); Dart_handle f2= - insert_cell_2_in_cell_3(*(scene.lcc),edges2.begin(),edges2.end(),mengerUpdateAttributes); + insert_cell_2_in_cell_3(*(scene.lcc),edges2.begin(),edges2.end()); - if (mengerUpdateAttributes) + if (scene.lcc->are_attributes_automatically_managed()) { scene.lcc->info<3>(f1).color()= (CGAL::Color(myrandom.get_int(0,256), @@ -1379,12 +1388,12 @@ void MainWindow::split_vol_in_three(Dart_handle dh, bool removecenter) } if ( removecenter ) - CGAL::remove_cell(*scene.lcc,f1,mengerUpdateAttributes); + CGAL::remove_cell(*scene.lcc,f1); else { mengerVolumes.push_back(f1); - if (mengerUpdateAttributes) + if (scene.lcc->are_attributes_automatically_managed()) update_volume_list_add(scene.lcc->attribute<3>(f1)); } @@ -1413,12 +1422,12 @@ void MainWindow::split_vol_in_nine(Dart_handle dh, bool removecenter) CGAL_assertion( curd==scene.lcc->beta(dh,1,2,1,1,2) ); Dart_handle f1= - insert_cell_2_in_cell_3(*(scene.lcc),edges1.begin(),edges1.end(),mengerUpdateAttributes); + insert_cell_2_in_cell_3(*(scene.lcc),edges1.begin(),edges1.end()); Dart_handle f2= - insert_cell_2_in_cell_3(*(scene.lcc),edges2.begin(),edges2.end(),mengerUpdateAttributes); + insert_cell_2_in_cell_3(*(scene.lcc),edges2.begin(),edges2.end()); - if (mengerUpdateAttributes) + if (scene.lcc->are_attributes_automatically_managed()) { scene.lcc->info<3>(f1).color()= (CGAL::Color(myrandom.get_int(0,256), @@ -1443,7 +1452,7 @@ void MainWindow::split_vol_in_nine(Dart_handle dh, bool removecenter) split_vol_in_three(scene.lcc->beta(f2,2,1),removecenter); if ( removecenter ) - CGAL::remove_cell(*scene.lcc,f1,mengerUpdateAttributes); + CGAL::remove_cell(*scene.lcc,f1); else { mengerVolumes.push_back(scene.lcc->beta(f1,2,1)); @@ -1473,12 +1482,12 @@ void MainWindow::split_vol_in_twentyseven(Dart_handle dh) CGAL_assertion( curd==scene.lcc->beta(dh,1,1,2,1,1,2) ); Dart_handle f1= - insert_cell_2_in_cell_3(*(scene.lcc),edges1.begin(),edges1.end(),mengerUpdateAttributes); + insert_cell_2_in_cell_3(*(scene.lcc),edges1.begin(),edges1.end()); Dart_handle f2= - insert_cell_2_in_cell_3(*(scene.lcc),edges2.begin(),edges2.end(),mengerUpdateAttributes); + insert_cell_2_in_cell_3(*(scene.lcc),edges2.begin(),edges2.end()); - if (mengerUpdateAttributes) + if (scene.lcc->are_attributes_automatically_managed()) { scene.lcc->info<3>(f1).color()= (CGAL::Color(myrandom.get_int(0,256), @@ -1701,7 +1710,7 @@ void MainWindow::onMengerDec() if (!mengerUpdateAttributes) { - scene.lcc->validate_attributes(); + scene.lcc->correct_invalid_attributes(); } #ifdef CGAL_PROFILE_LCC_DEMO @@ -1976,7 +1985,7 @@ void MainWindow::onSierpinskiCarpetInc() std::cout << "BOOST_NO_VARIADIC_TEMPLATES" << " not defined" << std::endl; #endif - scene.lcc->validate_attributes(); + scene.lcc->correct_invalid_attributes(); // maintenant que la scène est valide, on offre la possibilité de calculer une géométrie qui correspond à un tapis de Sierpinski if (isComputableGeometry) @@ -2747,7 +2756,7 @@ void MainWindow::onSierpinskiCarpetDec() if (!duringConstructionUpdateAttributes) { - scene.lcc->validate_attributes(); + scene.lcc->correct_invalid_attributes(); } #ifdef CGAL_PROFILE_LCC_DEMO @@ -2931,7 +2940,7 @@ void MainWindow::onSierpinskiTriangleInc() update_volume_list_add(scene.lcc->attribute<3>(sierpinskiTriangleSurfaces[i])); } - scene.lcc->validate_attributes(); + scene.lcc->correct_invalid_attributes(); } // std::cout << removedTriangles.size() << std::endl; @@ -3153,7 +3162,7 @@ void MainWindow::onSierpinskiTriangleDec() if (!sierpinskiTriangleUpdateAttributes) { - scene.lcc->validate_attributes(); + scene.lcc->correct_invalid_attributes(); } #ifdef CGAL_PROFILE_LCC_DEMO diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex.h index bbb5f37bef1..c3290acc803 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex.h @@ -350,9 +350,9 @@ namespace CGAL { /** validate the lcc */ - void validate_attributes() + void correct_invalid_attributes() { - Base::validate_attributes(); + Base::correct_invalid_attributes(); // Each dart needs to have a 0-embedding for (typename Dart_range::iterator it(this->darts().begin()), @@ -801,6 +801,20 @@ namespace CGAL { return res; } + + /** Return the status of the managment of the attributes of the CMap + */ + bool are_attributes_automatically_managed() const + { + return Base::are_attributes_automatically_managed(); + } + + /** Set the status of the managment of the attributes of the CMap + */ + void set_update_attributes(bool automatic_attributes_management) + { + Base::set_automatic_attributes_management(automatic_attributes_management); + } }; // Linear_cell_complex using compact container with handle.