From c0392e1bbae884c47953e008170f442359f14024 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Thu, 14 Oct 2021 16:33:29 +0200 Subject: [PATCH 01/13] Improve LCC incremental builder. --- .../CGAL/Linear_cell_complex_constructors.h | 4 +- .../Linear_cell_complex_incremental_builder.h | 291 ++++++++++++++---- 2 files changed, 234 insertions(+), 61 deletions(-) diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h index 9ec501d454b..e0090132210 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h @@ -204,9 +204,7 @@ namespace CGAL { m_file_header = scanner; // Remember file header after return. Linear_cell_complex_incremental_builder_3 B(alcc); - B.begin_surface(scanner.size_of_vertices(), - scanner.size_of_facets(), - scanner.size_of_halfedges()); + B.begin_surface(); typedef typename LCC::Point Point; diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder.h index 8f4ed8b1846..e0763e50ebb 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder.h @@ -14,6 +14,8 @@ #include #include +#include +#include #include namespace CGAL { @@ -71,15 +73,147 @@ namespace CGAL { lcc.template link_alpha<0>(prev_dart, lcc.create_dart(vh)); } }; +/////////////////////////////////////////////////////////////////////////////// +template +struct Find_opposite_2_no_control // No difference for CMap and GMap +{ + typedef typename LCC::Dart_handle DH; + typedef typename LCC::Vertex_attribute_handle VAH; + static DH run(LCC&, + std::unordered_map>& + vertex_to_dart_map_in_surface, + VAH vah1, VAH vah2) + { + // We are searching edge vah2->vah1 (the opposite of edge vah1->vah2) + auto it2=vertex_to_dart_map_in_surface.find(vah2); + if (it2!=vertex_to_dart_map_in_surface.end()) + { + auto it1=it2->second.find(vah1); + if (it1!=it2->second.end()) + { return it1->second; } + } + return nullptr; + } +}; +/////////////////////////////////////////////////////////////////////////////// +template +struct Find_opposite_2_with_control +{ + typedef typename LCC::Dart_handle DH; + typedef typename LCC::Vertex_attribute_handle VAH; + static DH run(LCC&, + std::unordered_map>&, + VAH, VAH) + { return nullptr; } +}; +template +struct Find_opposite_2_with_control +{ + typedef typename LCC::Dart_handle DH; + typedef typename LCC::Vertex_attribute_handle VAH; + static DH run(LCC& lcc, + std::unordered_map>& + vertex_to_dart_map_in_surface, + VAH vah1, VAH vah2) + { + DH res=Find_opposite_2_no_control::run(lcc, + vertex_to_dart_map_in_surface, + vah1, vah2); + if (res!=nullptr) + { + if (!lcc.template is_free<2>(res)) + { // Here a dart vah1->vah2 already exists, and it was already 2-sewn. + std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: try to use a same oriented edge twice."<::run(lcc, + vertex_to_dart_map_in_surface, + vah2, vah1)!=nullptr) + { // Here a dart vah1->vah2 already exists (but it was not already 2-sewn). + std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: try to use a same oriented edge twice."< +struct Find_opposite_2_with_control +{ + typedef typename LCC::Dart_handle DH; + typedef typename LCC::Vertex_attribute_handle VAH; + static DH run(LCC& lcc, + std::unordered_map>& + vertex_to_dart_map_in_surface, + VAH vah1, VAH vah2) + { + DH res=Find_opposite_2_no_control::run(lcc, + vertex_to_dart_map_in_surface, + vah1, vah2); + if (res!=nullptr) + { + if (!lcc.template is_free<2>(res)) + { // Here a dart vah1->vah2 already exists, and it was already 2-sewn. + std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: try to use a same oriented edge twice."< +struct Add_edge_in_associative_array +{ + typedef typename LCC::Dart_handle DH; + typedef typename LCC::Vertex_attribute_handle VAH; + static void run(LCC&, DH, + std::unordered_map>&) + {} +}; +template +struct Add_edge_in_associative_array +{ + typedef typename LCC::Dart_handle DH; + typedef typename LCC::Vertex_attribute_handle VAH; + static void run(LCC& lcc, DH dh, + std::unordered_map>& + vertex_to_dart_map_in_surface) + { + vertex_to_dart_map_in_surface[lcc.vertex_attribute(dh)].insert + (std::make_pair(lcc.vertex_attribute(lcc.next(dh)), dh)); + } +}; +template +struct Add_edge_in_associative_array +{ + typedef typename LCC::Dart_handle DH; + typedef typename LCC::Vertex_attribute_handle VAH; + static void run(LCC& lcc, DH dh, + std::unordered_map>& + vertex_to_dart_map_in_surface) + { + vertex_to_dart_map_in_surface[lcc.vertex_attribute(dh)].insert + (std::make_pair(lcc.vertex_attribute(lcc.template alpha<0>(dh)), dh)); + + vertex_to_dart_map_in_surface + [lcc.vertex_attribute(lcc.template alpha<0>(dh))].insert + (std::make_pair(lcc.vertex_attribute(dh), lcc.template alpha<0>(dh))); + } +}; +/////////////////////////////////////////////////////////////////////////////// // Incremental builder template < class LCC_ > class Linear_cell_complex_incremental_builder_3 { public: typedef LCC_ LCC; - typedef typename LCC::Dart_handle Dart_handle; - typedef typename LCC::Vertex_attribute_handle Vertex_attribute_handle; + typedef typename LCC::Dart_handle DH; + typedef typename LCC::Vertex_attribute_handle VAH; typedef typename LCC::Point Point_3; typedef typename LCC::size_type size_type; @@ -87,122 +221,163 @@ namespace CGAL { lcc(alcc) {} - Vertex_attribute_handle add_vertex(const Point_3& p) + VAH add_vertex(const Point_3& p) { - Vertex_attribute_handle res = lcc.create_vertex_attribute(p); + VAH res=lcc.create_vertex_attribute(p); vertex_map.push_back(res); - vertex_to_dart_map.push_back(std::vector()); - ++new_vertices; return res; } void begin_facet() - { - first_dart = lcc.null_handle; - prev_dart = lcc.null_handle; - // std::cout<<"Begin facet: "<:: - run(lcc, vertex_map[i], prev_dart); - + DH cur_dart=Add_vertex_to_face::run(lcc, vertex_map[i], prev_dart); if ( prev_dart!=lcc.null_handle ) { - Dart_handle opposite= - find_dart_between(i,lcc.vertex_attribute(prev_dart)); + DH opposite=Find_opposite_2_with_control:: + run(lcc, + vertex_to_dart_map_in_surface, + lcc.vertex_attribute(prev_dart), + lcc.vertex_attribute(cur_dart)); if ( opposite!=lcc.null_handle ) { CGAL_assertion( lcc.template is_free<2>(opposite) ); lcc.template set_opposite<2>(prev_dart, opposite); } - add_dart_in_vertex_to_dart_map(prev_dart, prev_vertex); + Add_edge_in_associative_array::run(lcc, prev_dart, + vertex_to_dart_map_in_surface); + + if (imax_vertex) { max_vertex=i; } } else - { - first_dart = cur; - first_vertex = i; - } + { first_dart=cur_dart; min_vertex=max_vertex=i; min_dart=cur_dart; } - prev_dart = cur; - prev_vertex = i; + prev_dart=cur_dart; } // End of the facet. Return the first dart of this facet. - Dart_handle end_facet() + DH end_facet() { CGAL_assertion( first_dart!=lcc.null_handle && prev_dart!=lcc.null_handle ); - Add_vertex_to_face::run_for_last(lcc, vertex_map[first_vertex], + Add_vertex_to_face::run_for_last(lcc, + lcc.vertex_attribute(first_dart), prev_dart); lcc.set_next(prev_dart, first_dart); - Dart_handle opposite = - find_dart_between(first_vertex,lcc.vertex_attribute(prev_dart)); + DH opposite=Find_opposite_2_with_control:: + run(lcc, + vertex_to_dart_map_in_surface, + lcc.vertex_attribute(prev_dart), + lcc.vertex_attribute(first_dart)); if ( opposite!=lcc.null_handle ) { CGAL_assertion( lcc.template is_free<2>(opposite) ); lcc.template set_opposite<2>(prev_dart, opposite); } - add_dart_in_vertex_to_dart_map(prev_dart, prev_vertex); + Add_edge_in_associative_array::run(lcc, prev_dart, + vertex_to_dart_map_in_surface); + opposite=opposite_face(); + if(opposite!=nullptr) + { + if(!lcc.template is_free<3>(opposite)) + { + std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: it exists more than 2 faces with same indices."<(lcc.other_orientation(opposite), min_dart); } + } + add_face_in_array(); return first_dart; } - void begin_surface( std::size_t v, std::size_t /*f*/, std::size_t /*h*/) + DH add_facet(std::initializer_list l) { - new_vertices = 0; - first_dart = lcc.null_handle; - prev_dart = lcc.null_handle; - vertex_map.clear(); - vertex_to_dart_map.clear(); - vertex_map.reserve(v); - vertex_to_dart_map.reserve(v); - // lcc.reserve(v,h); + begin_facet(); + for (std::size_t i:l) + { add_vertex_to_facet(i); } + return end_facet(); + } + + void begin_surface() + { + vertex_to_dart_map_in_surface.clear(); } // End of the surface. Return one dart of the created surface. - Dart_handle end_surface() + DH end_surface() { return first_dart; } protected: - - Dart_handle find_dart_between(size_type i, Vertex_attribute_handle vh) + /** test if the two given facets have the same vertex handle but with + * opposite orientations. For closed facets. + * @return true iff the two facets have the same vertex handle with opposite + * orientation. + */ + bool are_facets_opposite_and_same_vertex_handles(DH d1, DH d2) const { - typename std::vector::reverse_iterator - it(vertex_to_dart_map[i].rbegin()); - typename std::vector::reverse_iterator - itend(vertex_to_dart_map[i].rend()); + DH s1=d1; + DH s2=d2; + do + { + assert(lcc.is_next_exist(d1) && lcc.is_previous_exist(d2)); + assert(lcc.other_extremity(d2)!=lcc.null_handle); - for ( ; it!=itend; ++it ) + if (lcc.vertex_attribute(d1)!=lcc.vertex_attribute(d2)) + { return false; } + d1=lcc.next(d1); + d2=lcc.previous(d2); + } + while(d1!=s1); + + if (d2!=s2) { return false; } + return true; + } + + DH opposite_face() { - if ( lcc.vertex_attribute(lcc.next(*it))==vh ) return (*it); + auto it1=faces.find(min_vertex); + if(it1==faces.end()) { return nullptr; } + auto it2=it1->second.find(max_vertex); + if(it2==it1->second.end()) { return nullptr; } + for(auto it3=it2->second.begin(), it3end=it2->second.end(); it3!=it3end; ++it3) + { + if (are_facets_opposite_and_same_vertex_handles(*it3, min_dart)) + { return lcc.previous(*it3); } } - return lcc.null_handle; + return nullptr; } - void add_dart_in_vertex_to_dart_map( Dart_handle adart, size_type i ) + void add_face_in_array() { - CGAL_assertion( adart!=lcc.null_handle ); - vertex_to_dart_map[i].push_back(adart); + faces[min_vertex][max_vertex].push_back(min_dart); } private: - std::vector vertex_map; - std::vector > vertex_to_dart_map; + LCC& lcc; + std::vector vertex_map; // Map each index to the corresponding vertex handle - LCC& lcc; - Dart_handle first_dart; - Dart_handle prev_dart; - size_type first_vertex; - size_type prev_vertex; - size_type new_vertices; + // A map to associate to each edge of a surface its dart. The edge is given + // by its two vertex handles (source-target). + std::unordered_map> vertex_to_dart_map_in_surface; + std::unordered_map>> faces; + + DH first_dart; /// First dart of the current face + DH prev_dart; /// Prev dart of the current face + DH min_dart; /// dart with the min vertex of the current facet. + std::size_t min_vertex, max_vertex; /// min and max indices of vertices of the current face }; } //namespace CGAL From 1e7a47c0eea9a48e065f98d48d1b66b4f420d1ca Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Thu, 14 Oct 2021 16:33:47 +0200 Subject: [PATCH 02/13] Add one test for LCC incremental builder --- .../LCC_3_incremental_builder_test.cpp | 179 ++++++++++++++++++ .../data/lcc3_ib_test.cmap | 2 + .../data/lcc3_ib_test.gmap | 2 + 3 files changed, 183 insertions(+) create mode 100644 Linear_cell_complex/test/Linear_cell_complex/LCC_3_incremental_builder_test.cpp create mode 100644 Linear_cell_complex/test/Linear_cell_complex/data/lcc3_ib_test.cmap create mode 100644 Linear_cell_complex/test/Linear_cell_complex/data/lcc3_ib_test.gmap diff --git a/Linear_cell_complex/test/Linear_cell_complex/LCC_3_incremental_builder_test.cpp b/Linear_cell_complex/test/Linear_cell_complex/LCC_3_incremental_builder_test.cpp new file mode 100644 index 00000000000..2569b0f929b --- /dev/null +++ b/Linear_cell_complex/test/Linear_cell_complex/LCC_3_incremental_builder_test.cpp @@ -0,0 +1,179 @@ +#include +#include +#include +#include + +#include "Linear_cell_complex_3_test.h" + +/////////////////////////////////////////////////////////////////////////////// +/* 3 + * /|\ + * 0-|-2 + * \|/ + * 1 + */ +template +void make_tetrahedron_with_builder(IncrementalBuilder& ib, + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t i3) +{ + ib.begin_surface(); + ib.add_facet({i0,i1,i2}); + ib.add_facet({i1,i0,i3}); + ib.add_facet({i2,i1,i3}); + ib.add_facet({i0,i2,i3}); + ib.end_surface(); +} +/////////////////////////////////////////////////////////////////////////////// +/* 4 + * /|\ + * 0-|-3 + * | | | + * 1---2 + */ +template +void make_pyramid_with_builder(IncrementalBuilder& ib, + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t i3, + std::size_t i4) +{ + ib.begin_surface(); + ib.add_facet({i0,i1,i2,i3}); + ib.add_facet({i1,i0,i4}); + ib.add_facet({i2,i1,i4}); + ib.add_facet({i3,i2,i4}); + ib.add_facet({i0,i3,i4}); + ib.end_surface(); +} +/////////////////////////////////////////////////////////////////////////////// +/* 3 + * /|\ + * 4---5 + * | | | + * | 0 | + * |/ \| + * 1---2 + */ +template +void make_prism_with_builder(IncrementalBuilder& ib, + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t i3, + std::size_t i4, + std::size_t i5) +{ + ib.begin_surface(); + ib.add_facet({i0,i1,i2}); + ib.add_facet({i1,i0,i3,i4}); + ib.add_facet({i2,i1,i4,i5}); + ib.add_facet({i0,i2,i5,i3}); + ib.add_facet({i5,i4,i3}); + ib.end_surface(); +} +/////////////////////////////////////////////////////////////////////////////// +/* 7----6 + * /| /| + * 4----5 | + * | 3--|-2 + * |/ |/ + * 0----1 + */ +template +void make_hexahedron_with_builder(IncrementalBuilder& ib, + std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t i3, + std::size_t i4, + std::size_t i5, + std::size_t i6, + std::size_t i7) +{ + ib.begin_surface(); + ib.add_facet({i0,i1,i2,i3}); + ib.add_facet({i1,i0,i4,i5}); + ib.add_facet({i2,i1,i5,i6}); + ib.add_facet({i3,i2,i6,i7}); + ib.add_facet({i0,i3,i7,i4}); + ib.add_facet({i7,i6,i5,i4}); + ib.end_surface(); +} +/////////////////////////////////////////////////////////////////////////////// +template +bool test_ib(const char* filename) +{ + typedef typename LCC::Point Point; + LCC lcc; + CGAL::Linear_cell_complex_incremental_builder_3 ib(lcc); + + ib.add_vertex(Point(0,0,0)); // 0 + ib.add_vertex(Point(1,0,0)); // 1 + ib.add_vertex(Point(1,2,0)); // 2 + ib.add_vertex(Point(0,2,0)); // 3 + + ib.add_vertex(Point(0,0,1.5)); // 4 + ib.add_vertex(Point(1,0,1.5)); // 5 + ib.add_vertex(Point(1,2,1.5)); // 6 + ib.add_vertex(Point(0,2,1.5)); // 7 + + ib.add_vertex(Point(0.5,1,2.5)); // 8 + + ib.add_vertex(Point(2,0,0)); // 9 + ib.add_vertex(Point(2,0,1)); // 10 + + trace_test_begin(); + make_hexahedron_with_builder(ib, 0,1,2,3,4,5,6,7); + make_pyramid_with_builder(ib, 4,5,6,7,8); + make_prism_with_builder(ib, 2,1,9,6,5,10); + make_tetrahedron_with_builder(ib, 6,5,10,8); + + if ( !check_number_of_cells_3(lcc, 11, 22, 16, 4, 1) ) + { return false; } + + LCC lcc2; + std::ifstream input(std::string("data/")+filename); + if (!input) + { + std::cout<<"Problem to load LCC data/"<>lcc2; + input.close(); + + if (!lcc.is_isomorphic_to(lcc2)) + { return false; } + trace_test_end(); + + return true; +} + +int main() +{ + std::cout<<"LCC_3_incremental_builder_test (v1)."<"); + typedef CGAL::Linear_cell_complex_for_combinatorial_map<3> LCC3; + if ( !test_ib("lcc3_ib_test.cmap") ) + { + std::cout<<" Error during Test_LCC_3."<"); + typedef CGAL::Linear_cell_complex_for_generalized_map<3> GLCC3; + if ( !test_ib("lcc3_ib_test.gmap") ) + { + std::cout<<" Error during Test_LCC_3."< +25394131176172082351010244118471222469144514315121621131818419162024176221527231126247252119282629232732222835212538243025314029333326623431643236633627373435393928403738304244434841524541946551247571144491049425047515648535343545155585245575060584659565461606257616556596858635932647034626633666067646569696170676863voidN4CGAL7Point_3INS_5EpickEEE17

000

49

100

52

120

18

020

38

001.5

66

101.5

68

121.5

39

021.5

70

0.512.5

53

200

69

201

\ No newline at end of file diff --git a/Linear_cell_complex/test/Linear_cell_complex/data/lcc3_ib_test.gmap b/Linear_cell_complex/test/Linear_cell_complex/data/lcc3_ib_test.gmap new file mode 100644 index 00000000000..6eca4776f71 --- /dev/null +++ b/Linear_cell_complex/test/Linear_cell_complex/data/lcc3_ib_test.gmap @@ -0,0 +1,2 @@ + +2810139421835176426572586347133101629111121040111339141246131545161420159191824488171938720181694192115932220449221234391242228902317278926326252752826242729233028422931413230363125353440833357363432353731383648373947403812393311424830544143295344422252434521514644145045471349484638564741375550565846495157455250644451536343545270425355694156547648554975475862505759496058805961796260666157656468521246365511236664621286567611276866721266763711257074546971537270687173677472787369777680567577557876747779738078607975598286888183878482968385958684104858110388948218878981179088110248991109239290114229193113219492982093879719961028495978398969497999310098112991011111021001061019510510411086103105851061041021051071011081061161071091151101089010910389112116100120111113991191141129211811311591117116114108122115111107121118122124114117119123113120118130112119121129111122120136116121117135115124128118641231251176312612414068125127139671281261326612712313165130134120129131119132130128131133127134132138133129137136140122135137121138136134137139133140138126139135125voidN4CGAL7Point_3INS_5EpickEEE40

000

97

100

110

120

35

020

80

001.5

131

101.5

140

121.5

77

021.5

139

0.512.5

105

200

137

201

\ No newline at end of file From 26322683d7152732864cb2df49ccc6084a40adbc Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Thu, 14 Oct 2021 17:06:41 +0200 Subject: [PATCH 03/13] Modify save of cmap/gmap to deal with the case of attributes that do not store darts. --- .../CGAL/Combinatorial_map_save_load.h | 94 +++++++++---------- ...inear_cell_complex_for_combinatorial_map.h | 12 +++ .../Linear_cell_complex_for_generalized_map.h | 12 +++ 3 files changed, 67 insertions(+), 51 deletions(-) diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h b/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h index ddf1da00724..70a3d4be17a 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h @@ -164,12 +164,6 @@ namespace CGAL { std::map& myDarts) { - // to check all i-cells of the map - typename CMap::template Attribute_range::type::const_iterator - it_attrib, itend_attrib; - it_attrib=amap.template attributes().begin(); - itend_attrib=amap.template attributes().end(); - // add dimension & type boost::property_tree::ptree& ndim = ptree.add("dimension", ""); ndim.put(".index", i); @@ -177,16 +171,20 @@ namespace CGAL { ndim.add("type_point", typeid(typename CMap::Point).name()); // for every attribute of the dimension - for (; it_attrib!=itend_attrib; ++it_attrib) + for (auto it=amap.template one_dart_per_cell().begin(), + itend=amap.template one_dart_per_cell().end(); it!=itend; ++it) { - // make composant, dart and property node - boost::property_tree::ptree & nattr = ndim.add("a", ""); - /* boost::property_tree::ptree & ndarts = */ - nattr.add("d", myDarts[it_attrib->dart()]); + if (amap.template attribute(it)!=nullptr) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", myDarts[it]); - // update property node to add a value node (from basic or custom type - write_cmap_attribute_node(nattr, it_attrib->info()); - write_cmap_attribute_node(nattr, it_attrib->point()); + // update property node to add a value node (from basic or custom type + write_cmap_attribute_node(nattr, amap.template info(it)); + write_cmap_attribute_node(nattr, amap.point(it)); + } } } }; @@ -199,12 +197,6 @@ namespace CGAL { std::map& myDarts) { - // to check all i-cells of the map - typename CMap::template Attribute_range::type::const_iterator - it_attrib, itend_attrib; - it_attrib=amap.template attributes().begin(); - itend_attrib=amap.template attributes().end(); - // add dimension & type boost::property_tree::ptree& ndim = ptree.add("dimension", ""); ndim.put(".index", i); @@ -212,15 +204,19 @@ namespace CGAL { ndim.add("type_point", typeid(typename CMap::Point).name()); // for every attribute of the dimension - for (; it_attrib!=itend_attrib; ++it_attrib) + for (auto it=amap.template one_dart_per_cell().begin(), + itend=amap.template one_dart_per_cell().end(); it!=itend; ++it) { - // make composant, dart and property node - boost::property_tree::ptree & nattr = ndim.add("a", ""); - /* boost::property_tree::ptree & ndarts = */ - nattr.add("d", myDarts[it_attrib->dart()]); + if (amap.template attribute(it)!=nullptr) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", myDarts[it]); - // update property node to add a value node (from basic or custom type - write_cmap_attribute_node(nattr, it_attrib->point()); + // update property node to add a value node (from basic or custom type + write_cmap_attribute_node(nattr, amap.point(it)); + } } } }; @@ -233,12 +229,6 @@ namespace CGAL { std::map& myDarts) { - // to check all i-cells of the map - typename CMap::template Attribute_range::type::const_iterator - it_attrib, itend_attrib; - it_attrib=amap.template attributes().begin(); - itend_attrib=amap.template attributes().end(); - // add dimension & type boost::property_tree::ptree& ndim = ptree.add("dimension", ""); ndim.put(".index", i); @@ -247,15 +237,19 @@ namespace CGAL { ndim.add("type_point", "void"); // for every attribute of the dimension - for (; it_attrib!=itend_attrib; ++it_attrib) + for (auto it=amap.template one_dart_per_cell().begin(), + itend=amap.template one_dart_per_cell().end(); it!=itend; ++it) { - // make composant, dart and property node - boost::property_tree::ptree & nattr = ndim.add("a", ""); - /* boost::property_tree::ptree & ndarts = */ - nattr.add("d", myDarts[it_attrib->dart()]); + if (amap.template attribute(it)!=nullptr) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", myDarts[it]); - // update property node to add a value node (from basic or custom type - write_cmap_attribute_node(nattr, it_attrib->info()); + // update property node to add a value node (from basic or custom type + write_cmap_attribute_node(nattr, amap.template info(it)); + } } } }; @@ -268,12 +262,6 @@ namespace CGAL { std::map& myDarts) { - // to check all i-cells of the map - typename CMap::template Attribute_range::type::const_iterator - it_attrib, itend_attrib; - it_attrib=amap.template attributes().begin(); - itend_attrib=amap.template attributes().end(); - // add dimension & type boost::property_tree::ptree& ndim = ptree.add("dimension", ""); ndim.put(".index", i); @@ -281,12 +269,16 @@ namespace CGAL { ndim.add("type_point", "void"); // for every attribute of the dimension - for (; it_attrib!=itend_attrib; ++it_attrib) + for (auto it=amap.template one_dart_per_cell().begin(), + itend=amap.template one_dart_per_cell().end(); it!=itend; ++it) { - // make composant, dart and property node - boost::property_tree::ptree & nattr = ndim.add("a", ""); - /* boost::property_tree::ptree & ndarts = */ - nattr.add("d", myDarts[it_attrib->dart()]); + if (amap.template attribute(it)!=nullptr) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", myDarts[it]); + } } } }; diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_combinatorial_map.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_combinatorial_map.h index 19d81b140b8..b1761257ab1 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_combinatorial_map.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_combinatorial_map.h @@ -146,6 +146,18 @@ namespace CGAL { return *this; } + friend std::ostream& operator<< (std::ostream& os, const Self& amap) + { + save_combinatorial_map(amap, os); + return os; + } + + friend std::ifstream& operator>> (std::ifstream& is, Self& amap) + { + load_combinatorial_map(is, amap); + return is; + } + /** Import the given hds which should be a model of an halfedge graph. */ template void import_from_halfedge_graph(const HEG& heg , diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_generalized_map.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_generalized_map.h index de9900a1c8d..5bd176fd2b7 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_generalized_map.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_generalized_map.h @@ -145,6 +145,18 @@ namespace CGAL { Base::operator=(alcc); return *this; } + + friend std::ostream& operator<< (std::ostream& os, const Self& amap) + { + save_generalized_map(amap, os); + return os; + } + + friend std::ifstream& operator>> (std::ifstream& is, Self& amap) + { + load_generalized_map(is, amap); + return is; + } }; } // namespace CGAL From 5c57f83fdad2da0c02d3afaff1ec427f1fa7cfbc Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Thu, 14 Oct 2021 17:19:33 +0200 Subject: [PATCH 04/13] Replace std::map by std::unordered_map for save/load of CMap/GMap. --- .../include/CGAL/Combinatorial_map.h | 3 +- .../CGAL/Combinatorial_map_save_load.h | 34 +++++++++---------- .../include/CGAL/Generalized_map_save_load.h | 8 ++--- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index 32ea6e66ad5..d7ff7469919 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -2581,7 +2582,7 @@ namespace CGAL { /// @return the size (in number of darts) of the biggest cc. std::size_t keep_biggest_connected_component() { - std::map ccs; + std::unordered_map ccs; size_type treated=get_new_mark(); for (auto it=darts().begin(), itend=darts().end(); it!=itend; ++it) diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h b/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h index 70a3d4be17a..d5847071994 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -161,8 +161,8 @@ namespace CGAL { struct My_functor_cmap_save_one_attrib { static void run(CMap& amap, boost::property_tree::ptree& ptree, - std::map& myDarts) + std::unordered_map& myDarts) { // add dimension & type boost::property_tree::ptree& ndim = ptree.add("dimension", ""); @@ -194,8 +194,8 @@ namespace CGAL { struct My_functor_cmap_save_one_attrib { static void run(CMap& amap, boost::property_tree::ptree& ptree, - std::map& myDarts) + std::unordered_map& myDarts) { // add dimension & type boost::property_tree::ptree& ndim = ptree.add("dimension", ""); @@ -226,8 +226,8 @@ namespace CGAL { struct My_functor_cmap_save_one_attrib { static void run(CMap& amap, boost::property_tree::ptree& ptree, - std::map& myDarts) + std::unordered_map& myDarts) { // add dimension & type boost::property_tree::ptree& ndim = ptree.add("dimension", ""); @@ -259,8 +259,8 @@ namespace CGAL { struct My_functor_cmap_save_one_attrib { static void run(CMap& amap, boost::property_tree::ptree& ptree, - std::map& myDarts) + std::unordered_map& myDarts) { // add dimension & type boost::property_tree::ptree& ndim = ptree.add("dimension", ""); @@ -288,8 +288,8 @@ namespace CGAL { { template static void run(CMap& amap, boost::property_tree::ptree& ptree, - std::map& myDarts) + std::unordered_map& myDarts) { My_functor_cmap_save_one_attrib::run(amap, ptree, myDarts); } @@ -297,12 +297,12 @@ namespace CGAL { template < class CMap > boost::property_tree::ptree cmap_save_darts - (CMap& amap, std::map& myDarts) + (CMap& amap, std::unordered_map& myDarts) { CGAL_assertion( myDarts.empty() ); - // First we numbered each dart by using the std::map. + // First we numbered each dart by using the unordered_map. typename CMap::Dart_range::const_iterator it(amap.darts().begin()); for(typename CMap::size_type num=1; num<=amap.number_of_darts(); ++num, ++it) @@ -341,8 +341,8 @@ namespace CGAL { template < class CMap > boost::property_tree::ptree cmap_save_attributes - (const CMap& amap, std::map& myDarts) + (const CMap& amap, std::unordered_map& myDarts) { using boost::property_tree::ptree; ptree pt; @@ -375,7 +375,7 @@ namespace CGAL { f(tree); // map dart => number - std::map myDarts; + std::unordered_map myDarts; // Save darts ptree pt_darts=cmap_save_darts(amap, myDarts); diff --git a/Generalized_map/include/CGAL/Generalized_map_save_load.h b/Generalized_map/include/CGAL/Generalized_map_save_load.h index 1b727e84493..bd9b2480756 100644 --- a/Generalized_map/include/CGAL/Generalized_map_save_load.h +++ b/Generalized_map/include/CGAL/Generalized_map_save_load.h @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include #include @@ -70,12 +70,12 @@ namespace CGAL { template < class GMap > boost::property_tree::ptree gmap_save_darts (const GMap& amap, - std::map& myDarts) { CGAL_assertion( myDarts.empty() ); - // First we numbered each dart by using the std::map. + // First we numbered each dart by using the unordered_map. typename GMap::Dart_range::const_iterator it(amap.darts().begin()); for(typename GMap::size_type num=1; num<=amap.number_of_darts(); ++num, ++it) @@ -119,7 +119,7 @@ namespace CGAL { ptree tree; // map dart => number - std::map myDarts; + std::unordered_map myDarts; // Save darts ptree pt_darts=gmap_save_darts(amap, myDarts); From f21ab5a1a112a0692c3ee3b26ddccca13512bf98 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Thu, 14 Oct 2021 17:48:43 +0200 Subject: [PATCH 05/13] When cells have id, store the max id. --- .../include/CGAL/Cell_attribute.h | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/Combinatorial_map/include/CGAL/Cell_attribute.h b/Combinatorial_map/include/CGAL/Cell_attribute.h index 4409b2ebfe3..99b502ec202 100644 --- a/Combinatorial_map/include/CGAL/Cell_attribute.h +++ b/Combinatorial_map/include/CGAL/Cell_attribute.h @@ -14,6 +14,7 @@ #include #include +#include namespace CGAL { @@ -83,15 +84,27 @@ namespace CGAL { const std::size_t& id() const { return m_id; } - protected: - void set_id(std::size_t id) - { m_id=id; } + static const std::size_t& max_id() + { return m_max_id; } protected: - /// id of the cell - std::size_t m_id; + void set_id(std::size_t id) + { + m_id=id; + if (m_id+1>m_max_id) { m_max_id=m_id+1; } + } + + static void reset_max_id() + { m_max_id=0; } + + protected: + std::size_t m_id; ///< id of the cell + static std::size_t m_max_id; ///< max id used (warning: never decreases) }; + template + std::size_t Add_id::m_max_id=0; + /// If the tag WithId is false, we do not add id to cells. template <> class Add_id From 3fb45bdd5a5b4c8fb1eed4160ab58bd76f33dbc4 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Thu, 14 Oct 2021 17:52:03 +0200 Subject: [PATCH 06/13] Improve sew_3_same_facets complexity --- .../include/CGAL/Linear_cell_complex_base.h | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h index d1d0d5b7fa8..bdc4abb22ae 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h @@ -455,7 +455,9 @@ namespace CGAL { { unsigned int res = 0; - std::map > one_dart_per_facet; + // We store one dart per face, the face being accessed through its + // minimal and maximal points. + std::map>> one_dart_per_facet; size_type mymark = get_new_mark(); // First we fill the std::map by one dart per facet, and by using @@ -466,56 +468,58 @@ namespace CGAL { if ( !is_marked(it, mymark) && is_marked(it, AMark) ) { Point min_point=point(it); - Dart_handle min_dart = it; + Point max_point=min_point; + Dart_handle min_dart=it; mark(it, mymark); - typename Base::template - Dart_of_cell_range<2>::iterator it2(*this,it); + typename Base::template Dart_of_cell_range<2>::iterator it2(*this,it); ++it2; for ( ; it2.cont(); ++it2 ) { - Point cur_point=point(it2); + Point& cur_point=point(it2); this->mark(it2, mymark); if ( cur_point < min_point ) { min_point = cur_point; min_dart = it2; } + if (cur_point>max_point) + { max_point=cur_point; } } - one_dart_per_facet[min_point].push_back(min_dart); + one_dart_per_facet[min_point][max_point].push_back(min_dart); } else this->mark(it, mymark); } // Second we run through the map: candidates for sew3 have necessary the - // same minimal point. - typename std::map >::iterator - itmap=one_dart_per_facet.begin(), - itmapend=one_dart_per_facet.end(); - - for (; itmap!=itmapend; ++itmap) + // same minimal and maximal points. + for (auto itmap=one_dart_per_facet.begin(), + itmapend=one_dart_per_facet.end(); itmap!=itmapend; ++itmap) { - for (typename std::vector::iterator - it1=(itmap->second).begin(), - it1end=(itmap->second).end(); it1!=it1end; ++it1) + for (auto itmap2=(itmap->second).begin(), + itmap2end=(itmap->second).end(); itmap2!=itmap2end; ++itmap2) { - typename std::vector::iterator it2=it1; - for (++it2; it2!=it1end; ++it2) + for (typename std::vector::iterator + it1=(itmap2->second).begin(), + it1end=(itmap2->second).end(); it1!=it1end; ++it1) { - if (*it1!=*it2 && - !this->template is_opposite_exist<3>(*it1) && - !this->template is_opposite_exist<3>(*it2) && - are_facets_opposite_and_same_geometry - (*it1, this->previous(*it2))) + typename std::vector::iterator it2=it1; + for (++it2; it2!=it1end; ++it2) { + if (*it1!=*it2 && + !this->template is_opposite_exist<3>(*it1) && + !this->template is_opposite_exist<3>(*it2) && + are_facets_opposite_and_same_geometry + (*it1, this->previous(*it2))) + { ++res; - this->template sew<3>(*it1, - this->other_orientation(previous(*it2))); + this->template sew<3>(*it1, + this->other_orientation(previous(*it2))); + } } } } } - CGAL_assertion( this->is_whole_map_marked(mymark) ); this->free_mark(mymark); return res; From 2f5841e179a9f0bedf3d479933bb13da3cae3720 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Thu, 14 Oct 2021 17:53:01 +0200 Subject: [PATCH 07/13] Use std::unorderd_map everywhere in CMap, GMap and LCC. --- .../include/CGAL/Combinatorial_map.h | 49 +++++++++---------- .../include/CGAL/Generalized_map.h | 40 +++++++-------- ...inear_cell_complex_for_combinatorial_map.h | 13 ++--- .../unsew_edgewidth_repeatedly.cpp | 4 +- .../internal/Generic_map_selector.h | 12 ++--- .../internal/Shortest_noncontractible_cycle.h | 4 +- 6 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index d7ff7469919..4dd8e7822d8 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -44,7 +44,6 @@ #include #include #include -#include #include #include @@ -231,8 +230,8 @@ namespace CGAL { typename Converters, typename DartInfoConverter, typename PointConverter> void generic_copy(CMap2& amap, - boost::unordered_map* origin_to_copy, - boost::unordered_map* copy_to_origin, + std::unordered_map* origin_to_copy, + std::unordered_map* copy_to_origin, const Converters& converters, const DartInfoConverter& dartinfoconverter, const PointConverter& pointconverter, @@ -260,7 +259,7 @@ namespace CGAL { // Create an mapping between darts of the two maps (originals->copies). // (here we cannot use CGAL::Unique_hash_map because it does not provide // iterators... - boost::unordered_map local_dartmap; + std::unordered_map local_dartmap; if (origin_to_copy==NULL) // Use local_dartmap if user does not provides its own unordered_map { origin_to_copy=&local_dartmap; } @@ -288,7 +287,7 @@ namespace CGAL { unsigned int min_dim=(dimension::iterator + typename std::unordered_map::iterator dartmap_iter, dartmap_iter_end=origin_to_copy->end(); for (dartmap_iter=origin_to_copy->begin(); dartmap_iter!=dartmap_iter_end; ++dartmap_iter) @@ -323,9 +322,9 @@ namespace CGAL { template void copy(CMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, const DartInfoConverter& dartinfoconverter, @@ -344,9 +343,9 @@ namespace CGAL { template void copy_from_const(const CMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, const DartInfoConverter& dartinfoconverter, @@ -364,9 +363,9 @@ namespace CGAL { // (2a) copy(amap, converters, dartinfoconverter) template void copy(CMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, const DartInfoConverter& dartinfoconverter, @@ -383,9 +382,9 @@ namespace CGAL { // (2b) copy_from_const(const amap, converters, dartinfoconverter) template void copy_from_const(const CMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, const DartInfoConverter& dartinfoconverter, @@ -402,9 +401,9 @@ namespace CGAL { // (3a) copy(amap, converters) template void copy(CMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, bool copy_perforated_darts=false, @@ -418,9 +417,9 @@ namespace CGAL { // (3b) copy_from_const(const amap, converters) template void copy_from_const(const CMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, bool copy_perforated_darts=false, @@ -434,9 +433,9 @@ namespace CGAL { // (4a) copy(amap) template void copy(CMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy=nullptr, - boost::unordered_map + std::unordered_map * copy_to_origin=nullptr, bool copy_perforated_darts=false, size_type mark_perforated=INVALID_MARK) @@ -449,9 +448,9 @@ namespace CGAL { // (4b) copy_from_const(const amap) template void copy_from_const(const CMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy=nullptr, - boost::unordered_map + std::unordered_map * copy_to_origin=nullptr, bool copy_perforated_darts=false, size_type mark_perforated=INVALID_MARK) @@ -555,10 +554,10 @@ namespace CGAL { /** Import the given hds which should be a model of an halfedge graph. */ template void import_from_halfedge_graph(const HEG& heg, - boost::unordered_map + std::unordered_map ::halfedge_descriptor, Dart_handle>* origin_to_copy=NULL, - boost::unordered_map + std::unordered_map ::halfedge_descriptor>* copy_to_origin=NULL, @@ -568,7 +567,7 @@ namespace CGAL { // Create an mapping between darts of the two maps (originals->copies). // (here we cannot use CGAL::Unique_hash_map because it does not provide // iterators... - boost::unordered_map + std::unordered_map ::halfedge_descriptor, Dart_handle> local_dartmap; if (origin_to_copy==NULL) // Used local_dartmap if user does not provides its own unordered_map @@ -591,7 +590,7 @@ namespace CGAL { } } - typename boost::unordered_map + typename std::unordered_map ::halfedge_descriptor, Dart_handle>::iterator dartmap_iter, dartmap_iter_end=origin_to_copy->end(); for (dartmap_iter=origin_to_copy->begin(); dartmap_iter!=dartmap_iter_end; diff --git a/Generalized_map/include/CGAL/Generalized_map.h b/Generalized_map/include/CGAL/Generalized_map.h index ad8de549631..31623b6fbeb 100644 --- a/Generalized_map/include/CGAL/Generalized_map.h +++ b/Generalized_map/include/CGAL/Generalized_map.h @@ -196,8 +196,8 @@ namespace CGAL { typename Converters, typename DartInfoConverter, typename PointConverter> void generic_copy(GMap2& amap, - boost::unordered_map* origin_to_copy, - boost::unordered_map* copy_to_origin, + std::unordered_map* origin_to_copy, + std::unordered_map* copy_to_origin, const Converters& converters, const DartInfoConverter& dartinfoconverter, const PointConverter& pointconverter, @@ -223,7 +223,7 @@ namespace CGAL { // Create an mapping between darts of the two maps (originals->copies). // (here we cannot use CGAL::Unique_hash_map because it does not provide // iterators... - boost::unordered_map local_dartmap; + std::unordered_map local_dartmap; if (origin_to_copy==NULL) // Use local_dartmap if user does not provides its own unordered_map { origin_to_copy=&local_dartmap; } @@ -251,7 +251,7 @@ namespace CGAL { unsigned int min_dim=(dimension::iterator + typename std::unordered_map::iterator dartmap_iter, dartmap_iter_end=origin_to_copy->end(); for (dartmap_iter=origin_to_copy->begin(); dartmap_iter!=dartmap_iter_end; ++dartmap_iter) @@ -286,9 +286,9 @@ namespace CGAL { template void copy(GMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, const DartInfoConverter& dartinfoconverter, @@ -307,9 +307,9 @@ namespace CGAL { template void copy_from_const(const GMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, const DartInfoConverter& dartinfoconverter, @@ -327,9 +327,9 @@ namespace CGAL { // (2a) copy(amap, converters, dartinfoconverter) template void copy(GMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, const DartInfoConverter& dartinfoconverter, @@ -346,9 +346,9 @@ namespace CGAL { // (2b) copy_from_const(const amap, converters, dartinfoconverter) template void copy_from_const(const GMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, const DartInfoConverter& dartinfoconverter, @@ -365,9 +365,9 @@ namespace CGAL { // (3a) copy(amap, converters) template void copy(GMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, bool copy_perforated_darts=false, @@ -381,9 +381,9 @@ namespace CGAL { // (3b) copy_from_const(const amap, converters) template void copy_from_const(const GMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy, - boost::unordered_map + std::unordered_map * copy_to_origin, const Converters& converters, bool copy_perforated_darts=false, @@ -397,9 +397,9 @@ namespace CGAL { // (4a) copy(amap) template void copy(GMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy=nullptr, - boost::unordered_map + std::unordered_map * copy_to_origin=nullptr, bool copy_perforated_darts=false, size_type mark_perforated=INVALID_MARK) @@ -412,9 +412,9 @@ namespace CGAL { // (4b) copy_from_const(const amap) template void copy_from_const(const GMap2& amap, - boost::unordered_map + std::unordered_map * origin_to_copy=nullptr, - boost::unordered_map + std::unordered_map * copy_to_origin=nullptr, bool copy_perforated_darts=false, size_type mark_perforated=INVALID_MARK) diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_combinatorial_map.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_combinatorial_map.h index b1761257ab1..848951d424d 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_combinatorial_map.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_for_combinatorial_map.h @@ -19,6 +19,7 @@ #include #include #include +#include namespace CGAL { @@ -162,16 +163,16 @@ namespace CGAL { template void import_from_halfedge_graph(const HEG& heg , const PointConverter& pointconverter, - boost::unordered_map + std::unordered_map ::halfedge_descriptor, Dart_handle>* origin_to_copy=NULL, - boost::unordered_map + std::unordered_map ::halfedge_descriptor>* copy_to_origin=NULL) { - boost::unordered_map + std::unordered_map ::halfedge_descriptor, Dart_handle> local_dartmap; if (origin_to_copy==NULL) // Used local_dartmap if user does not provides its own unordered_map @@ -183,7 +184,7 @@ namespace CGAL { Point_property_map; Point_property_map ppmap = get(CGAL::vertex_point, heg); - typename boost::unordered_map + typename std::unordered_map ::halfedge_descriptor, Dart_handle>::iterator dartmap_iter, dartmap_iter_end=origin_to_copy->end(); for (dartmap_iter=origin_to_copy->begin(); dartmap_iter!=dartmap_iter_end; @@ -202,10 +203,10 @@ namespace CGAL { /** Import the given hds which should be a model of an halfedge graph. */ template void import_from_halfedge_graph(const HEG& heg, - boost::unordered_map + std::unordered_map ::halfedge_descriptor, Dart_handle>* origin_to_copy=NULL, - boost::unordered_map + std::unordered_map ::halfedge_descriptor>* copy_to_origin=NULL) diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/unsew_edgewidth_repeatedly.cpp b/Surface_mesh_topology/examples/Surface_mesh_topology/unsew_edgewidth_repeatedly.cpp index 47c1d952004..5c18a4a0ec2 100644 --- a/Surface_mesh_topology/examples/Surface_mesh_topology/unsew_edgewidth_repeatedly.cpp +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/unsew_edgewidth_repeatedly.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include using LCC_3 =CGAL::Linear_cell_complex_for_generalized_map<2, 3>; using Dart_handle =LCC_3::Dart_handle; @@ -97,7 +97,7 @@ int main(int argc, char* argv[]) CGAL::load_off(lccoriginal, inp); std::cout<<"File '"< origin_to_copy; + std::unordered_map origin_to_copy; lcccopy.copy(lccoriginal, &origin_to_copy, nullptr); LCC_3::size_type is_root=lccoriginal.get_new_mark(); diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Generic_map_selector.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Generic_map_selector.h index fcc5322c084..b8deff441ef 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Generic_map_selector.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Generic_map_selector.h @@ -44,9 +44,9 @@ namespace internal { using Mesh_original = Mesh_; using Generic_map = CGAL::Generalized_map<2, Items_>; using Dart_const_handle_original = typename Mesh_original::Dart_const_handle; - using Copy_to_origin_map = boost::unordered_map; - using Origin_to_copy_map = boost::unordered_map; static void copy(Generic_map& target, const Mesh_original& source, @@ -64,9 +64,9 @@ namespace internal { using Mesh_original = Mesh_; using Generic_map = CGAL::Combinatorial_map<2, Items_>; using Dart_const_handle_original = typename Mesh_original::Dart_const_handle; - using Copy_to_origin_map = boost::unordered_map; - using Origin_to_copy_map = boost::unordered_map; static void copy(Generic_map& target, const Mesh_original& source, @@ -83,9 +83,9 @@ namespace internal { using Mesh_original = Mesh_; using Generic_map = CGAL::Combinatorial_map<2, Items_>; using Dart_const_handle_original = typename boost::graph_traits::halfedge_descriptor; - using Copy_to_origin_map = boost::unordered_map; - using Origin_to_copy_map = boost::unordered_map; static void copy(Generic_map& target, const Mesh_original& source, diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Shortest_noncontractible_cycle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Shortest_noncontractible_cycle.h index fd5fbb83d0d..a233c29b22f 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Shortest_noncontractible_cycle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Shortest_noncontractible_cycle.h @@ -65,8 +65,8 @@ public: using Path =CGAL::Surface_mesh_topology::Path_on_surface; // Associations between original darts and their copy. - using Origin_to_copy=boost::unordered_map; - using Copy_to_origin=boost::unordered_map; + using Origin_to_copy=std::unordered_map; + using Copy_to_origin=std::unordered_map; /// @return the local map const Local_map& get_local_map() const From ffca80cf6ebacd86083ab9c59a20444fe8462bdc Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Thu, 14 Oct 2021 18:00:07 +0200 Subject: [PATCH 08/13] Cannot use an unordered_map here. --- Combinatorial_map/include/CGAL/Combinatorial_map.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index 4dd8e7822d8..44b8cdd5f9c 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -2581,7 +2582,7 @@ namespace CGAL { /// @return the size (in number of darts) of the biggest cc. std::size_t keep_biggest_connected_component() { - std::unordered_map ccs; + std::map ccs; size_type treated=get_new_mark(); for (auto it=darts().begin(), itend=darts().end(); it!=itend; ++it) From 84ca88f8cc2cadf1e567484e344419dbad3edc8f Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Tue, 19 Oct 2021 20:16:43 +0200 Subject: [PATCH 09/13] Remove the maxid --- Combinatorial_map/include/CGAL/Cell_attribute.h | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Combinatorial_map/include/CGAL/Cell_attribute.h b/Combinatorial_map/include/CGAL/Cell_attribute.h index 99b502ec202..40ae79e7d89 100644 --- a/Combinatorial_map/include/CGAL/Cell_attribute.h +++ b/Combinatorial_map/include/CGAL/Cell_attribute.h @@ -84,27 +84,14 @@ namespace CGAL { const std::size_t& id() const { return m_id; } - static const std::size_t& max_id() - { return m_max_id; } - protected: void set_id(std::size_t id) - { - m_id=id; - if (m_id+1>m_max_id) { m_max_id=m_id+1; } - } - - static void reset_max_id() - { m_max_id=0; } + { m_id=id; } protected: std::size_t m_id; ///< id of the cell - static std::size_t m_max_id; ///< max id used (warning: never decreases) }; - template - std::size_t Add_id::m_max_id=0; - /// If the tag WithId is false, we do not add id to cells. template <> class Add_id From 6f460256522e0438504fca4d1daa8deab7459a8c Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Fri, 5 Nov 2021 10:26:48 +0100 Subject: [PATCH 10/13] More small improvments in sew3_same_facets (undocumented function) --- .../include/CGAL/Linear_cell_complex_base.h | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h index bdc4abb22ae..56fe0a14f7a 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h @@ -450,7 +450,9 @@ namespace CGAL { } /// Sew3 the marked facets having same geometry - /// (a facet is considered marked if one of its dart is marked). + /// (a facet is considered marked if ALL its darts are marked). + /// Only marked faces are proceed, but they can be 3-sewn with non + /// marked faces. unsigned int sew3_same_facets(size_type AMark) { unsigned int res = 0; @@ -465,19 +467,19 @@ namespace CGAL { for (typename Dart_range::iterator it(darts().begin()), itend(darts().end()); it!=itend; ++it ) { - if ( !is_marked(it, mymark) && is_marked(it, AMark) ) + if (!is_marked(it, mymark) && !this->template is_opposite_exist<3>(it)) { Point min_point=point(it); Point max_point=min_point; Dart_handle min_dart=it; - mark(it, mymark); - typename Base::template Dart_of_cell_range<2>::iterator it2(*this,it); + auto it2=this->template darts_of_cell_basic<2>(it, mymark).begin(); + this->mark(it2, mymark); ++it2; for ( ; it2.cont(); ++it2 ) { - Point& cur_point=point(it2); this->mark(it2, mymark); - if ( cur_point < min_point ) + Point& cur_point=point(it2); + if (cur_pointmark(it, mymark); + { this->mark(it, mymark); } } // Second we run through the map: candidates for sew3 have necessary the @@ -503,18 +505,26 @@ namespace CGAL { it1=(itmap2->second).begin(), it1end=(itmap2->second).end(); it1!=it1end; ++it1) { - typename std::vector::iterator it2=it1; - for (++it2; it2!=it1end; ++it2) + // We only proceed 3-free marked faces for it1 + if (!this->template is_opposite_exist<3>(*it1) && + is_marked(*it1, AMark)) { - if (*it1!=*it2 && - !this->template is_opposite_exist<3>(*it1) && - !this->template is_opposite_exist<3>(*it2) && - are_facets_opposite_and_same_geometry - (*it1, this->previous(*it2))) + typename std::vector::iterator it2=it1; { - ++res; - this->template sew<3>(*it1, - this->other_orientation(previous(*it2))); + for (++it2; it2!=it1end; ) + { + assert(*it1!=*it2); + if (!this->template is_opposite_exist<3>(*it2) && + are_facets_opposite_and_same_geometry + (*it1, this->previous(*it2))) + { + ++res; + this->template sew<3>(*it1, + this->other_orientation(previous(*it2))); + it2=it1end; // to leave the "for loop" since it1 is no more 3-free + } + else { ++it2; } + } } } } From b93aff65ead3831183eaed1e7dbc4ea52f19baf9 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Thu, 25 Nov 2021 11:16:10 +0100 Subject: [PATCH 11/13] Do not clear a cmap before to copy it. --- Combinatorial_map/include/CGAL/Combinatorial_map.h | 2 +- Generalized_map/include/CGAL/Generalized_map.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index 44b8cdd5f9c..5f409521c1e 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -239,7 +239,7 @@ namespace CGAL { bool copy_perforated_darts=false, size_type mark_perforated=INVALID_MARK) { - this->clear(); + // this->clear(); /*this->mnb_used_marks = amap.mnb_used_marks; this->mmask_marks = amap.mmask_marks; diff --git a/Generalized_map/include/CGAL/Generalized_map.h b/Generalized_map/include/CGAL/Generalized_map.h index 31623b6fbeb..73fa3becf5e 100644 --- a/Generalized_map/include/CGAL/Generalized_map.h +++ b/Generalized_map/include/CGAL/Generalized_map.h @@ -204,7 +204,7 @@ namespace CGAL { bool copy_perforated_darts=false, size_type mark_perforated=INVALID_MARK) { - this->clear(); + //this->clear(); /*this->mnb_used_marks = amap.mnb_used_marks; this->mmask_marks = amap.mmask_marks; From c56dc46679ec2041123ea0fd69c1ab06a7f9a704 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Tue, 7 Dec 2021 16:43:10 +0100 Subject: [PATCH 12/13] Fix a warning (and some strange indentation) --- .../CGAL/Linear_cell_complex_constructors.h | 2 +- .../Linear_cell_complex_incremental_builder.h | 188 +++++++++--------- 2 files changed, 97 insertions(+), 93 deletions(-) diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h index e0090132210..845664fcbb4 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h @@ -245,7 +245,7 @@ namespace CGAL { } */ for (std::size_t j=0; j } }; /////////////////////////////////////////////////////////////////////////////// - // Incremental builder - template < class LCC_ > - class Linear_cell_complex_incremental_builder_3 +// Incremental builder +template < class LCC_ > +class Linear_cell_complex_incremental_builder_3 +{ +public: + typedef LCC_ LCC; + typedef typename LCC::Dart_handle DH; + typedef typename LCC::Vertex_attribute_handle VAH; + typedef typename LCC::Point Point_3; + typedef typename LCC::size_type size_type; + + Linear_cell_complex_incremental_builder_3(LCC & alcc) : + lcc(alcc) + {} + + VAH add_vertex(const Point_3& p) { - public: - typedef LCC_ LCC; - typedef typename LCC::Dart_handle DH; - typedef typename LCC::Vertex_attribute_handle VAH; - typedef typename LCC::Point Point_3; - typedef typename LCC::size_type size_type; - - Linear_cell_complex_incremental_builder_3(LCC & alcc) : - lcc(alcc) - {} - - VAH add_vertex(const Point_3& p) - { VAH res=lcc.create_vertex_attribute(p); - vertex_map.push_back(res); - return res; - } + vertex_map.push_back(res); + return res; + } - void begin_facet() + void begin_facet() { // std::cout<<"Begin facet: "<::run(lcc, vertex_map[i], prev_dart); - if ( prev_dart!=lcc.null_handle ) - { - DH opposite=Find_opposite_2_with_control:: - run(lcc, - vertex_to_dart_map_in_surface, - lcc.vertex_attribute(prev_dart), - lcc.vertex_attribute(cur_dart)); - if ( opposite!=lcc.null_handle ) - { - CGAL_assertion( lcc.template is_free<2>(opposite) ); - lcc.template set_opposite<2>(prev_dart, opposite); - } - - Add_edge_in_associative_array::run(lcc, prev_dart, - vertex_to_dart_map_in_surface); - - if (imax_vertex) { max_vertex=i; } - } - else - { first_dart=cur_dart; min_vertex=max_vertex=i; min_dart=cur_dart; } - - prev_dart=cur_dart; - } - - // End of the facet. Return the first dart of this facet. - DH end_facet() + if ( prev_dart!=lcc.null_handle ) { - CGAL_assertion( first_dart!=lcc.null_handle && prev_dart!=lcc.null_handle ); - - Add_vertex_to_face::run_for_last(lcc, - lcc.vertex_attribute(first_dart), - prev_dart); - - lcc.set_next(prev_dart, first_dart); - DH opposite=Find_opposite_2_with_control:: - run(lcc, - vertex_to_dart_map_in_surface, - lcc.vertex_attribute(prev_dart), - lcc.vertex_attribute(first_dart)); + run(lcc, + vertex_to_dart_map_in_surface, + lcc.vertex_attribute(prev_dart), + lcc.vertex_attribute(cur_dart)); if ( opposite!=lcc.null_handle ) { CGAL_assertion( lcc.template is_free<2>(opposite) ); @@ -289,32 +255,70 @@ struct Add_edge_in_associative_array Add_edge_in_associative_array::run(lcc, prev_dart, vertex_to_dart_map_in_surface); - opposite=opposite_face(); - if(opposite!=nullptr) + if (imax_vertex) { max_vertex=i; } + } + else + { first_dart=cur_dart; min_vertex=max_vertex=i; min_dart=cur_dart; } + + prev_dart=cur_dart; + } + + // End of the facet. Return the first dart of this facet. + DH end_facet() + { + CGAL_assertion( first_dart!=lcc.null_handle && prev_dart!=lcc.null_handle ); + + Add_vertex_to_face::run_for_last(lcc, + lcc.vertex_attribute(first_dart), + prev_dart); + + lcc.set_next(prev_dart, first_dart); + + DH opposite=Find_opposite_2_with_control:: + run(lcc, + vertex_to_dart_map_in_surface, + lcc.vertex_attribute(prev_dart), + lcc.vertex_attribute(first_dart)); + if ( opposite!=lcc.null_handle ) { - if(!lcc.template is_free<3>(opposite)) + CGAL_assertion( lcc.template is_free<2>(opposite) ); + lcc.template set_opposite<2>(prev_dart, opposite); + } + + Add_edge_in_associative_array::run(lcc, prev_dart, + vertex_to_dart_map_in_surface); + + if(LCC::dimension>2) + { + opposite=opposite_face(); + if(opposite!=nullptr) { - std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: it exists more than 2 faces with same indices."<(opposite)) + { + std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: " + <<"it exists more than 2 faces with same indices."<(lcc.other_orientation(opposite), min_dart); } } - else - { lcc.template sew<3>(lcc.other_orientation(opposite), min_dart); } - } - add_face_in_array(); - return first_dart; + add_face_in_array(); } + return first_dart; + } - DH add_facet(std::initializer_list l) - { - begin_facet(); - for (std::size_t i:l) - { add_vertex_to_facet(i); } - return end_facet(); - } + DH add_facet(std::initializer_list l) + { + begin_facet(); + for (std::size_t i:l) + { add_vertex_to_facet(i); } + return end_facet(); + } - void begin_surface() - { - vertex_to_dart_map_in_surface.clear(); - } + void begin_surface() + { + vertex_to_dart_map_in_surface.clear(); + } // End of the surface. Return one dart of the created surface. DH end_surface() @@ -327,7 +331,7 @@ struct Add_edge_in_associative_array * orientation. */ bool are_facets_opposite_and_same_vertex_handles(DH d1, DH d2) const - { + { DH s1=d1; DH s2=d2; do @@ -347,7 +351,7 @@ struct Add_edge_in_associative_array } DH opposite_face() - { + { auto it1=faces.find(min_vertex); if(it1==faces.end()) { return nullptr; } auto it2=it1->second.find(max_vertex); @@ -356,16 +360,16 @@ struct Add_edge_in_associative_array { if (are_facets_opposite_and_same_vertex_handles(*it3, min_dart)) { return lcc.previous(*it3); } - } - return nullptr; } + return nullptr; + } void add_face_in_array() - { + { faces[min_vertex][max_vertex].push_back(min_dart); - } + } - private: +private: LCC& lcc; std::vector vertex_map; // Map each index to the corresponding vertex handle @@ -378,7 +382,7 @@ struct Add_edge_in_associative_array DH prev_dart; /// Prev dart of the current face DH min_dart; /// dart with the min vertex of the current facet. std::size_t min_vertex, max_vertex; /// min and max indices of vertices of the current face - }; +}; } //namespace CGAL From b0c9cf958b12508fb5d8eb3f30da6465f0e57c70 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Fri, 10 Dec 2021 16:32:44 +0100 Subject: [PATCH 13/13] Really remove the warning in LCC incremental builder --- .../Linear_cell_complex_incremental_builder.h | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder.h index a307fe84905..5720390772b 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder.h @@ -19,6 +19,7 @@ #include namespace CGAL { +/////////////////////////////////////////////////////////////////////////////// template struct Add_vertex_to_face @@ -206,6 +207,31 @@ struct Add_edge_in_associative_array } }; /////////////////////////////////////////////////////////////////////////////// +template +struct Sew3_for_LCC_incremental_builder +{ + static void run(LCC_& lcc, + typename LCC_::Dart_handle dh1, typename LCC_::Dart_handle dh2) + { + if(dh1!=nullptr) + { + if(!lcc.template is_free<3>(dh1)) + { + std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: " + <<"it exists more than 2 faces with same indices."<(lcc.other_orientation(dh1), dh2); } + } + } +}; +template +struct Sew3_for_LCC_incremental_builder +{ + static void run(LCC_&, typename LCC_::Dart_handle, typename LCC_::Dart_handle) + {} +}; +/////////////////////////////////////////////////////////////////////////////// // Incremental builder template < class LCC_ > class Linear_cell_complex_incremental_builder_3 @@ -292,16 +318,7 @@ public: if(LCC::dimension>2) { opposite=opposite_face(); - if(opposite!=nullptr) - { - if(!lcc.template is_free<3>(opposite)) - { - std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: " - <<"it exists more than 2 faces with same indices."<(lcc.other_orientation(opposite), min_dart); } - } + Sew3_for_LCC_incremental_builder::run(lcc, opposite, min_dart); add_face_in_array(); } return first_dart;