From a05200fb52f8693467d35f6bc14cb6bce8d5bdab Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Fri, 22 Nov 2019 13:30:20 +0100 Subject: [PATCH] End of cleanup. Remove debug code; rename data members; comment. --- .../basic_example_surface_mesh_topology.cpp | 4 +- .../data/double-torus.off | 453 ++++++ .../open_path_homotopy.cpp | 4 +- .../include/CGAL/Curves_on_surface_topology.h | 17 +- .../include/CGAL/Polygonal_schema_min_items.h | 2 - .../internal/Minimal_quadrangulation.h | 1268 +++++++---------- .../internal/Path_generators.h | 2 +- .../internal/Path_on_surface_with_rle.h | 24 +- 8 files changed, 962 insertions(+), 812 deletions(-) create mode 100644 Surface_mesh_topology/examples/Surface_mesh_topology/data/double-torus.off diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/basic_example_surface_mesh_topology.cpp b/Surface_mesh_topology/examples/Surface_mesh_topology/basic_example_surface_mesh_topology.cpp index 0a5185dd78f..048fb5a736d 100644 --- a/Surface_mesh_topology/examples/Surface_mesh_topology/basic_example_surface_mesh_topology.cpp +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/basic_example_surface_mesh_topology.cpp @@ -31,9 +31,9 @@ void create_path_3(Path_on_surface& p) int main() { LCC_3_cmap lcc; - if (!CGAL::load_off(lcc, "data/double-torus-example.off")) + if (!CGAL::load_off(lcc, "data/double-torus.off")) { - std::cout<<"ERROR reading file data/double-torus-example.off"<& p) int main() { SM sm; - std::ifstream in("data/double-torus-example.off"); + std::ifstream in("data/double-torus.off"); if (!in.is_open()) { - std::cout<<"ERROR reading file data/double-torus-example.off"<>sm; diff --git a/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h b/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h index 0aca07c72ee..c55df06ab5c 100644 --- a/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h +++ b/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h @@ -34,10 +34,11 @@ template class Curves_on_surface_topology { public: - typedef typename internal::Reduced_map Reduced_map; + typedef internal::Minimal_quadrangulation Minimal_quadrangulation; + typedef typename Minimal_quadrangulation::Reduced_map Reduced_map; - Curves_on_surface_topology(const Mesh& amap, bool /* display_time */=false) : - m_original_map(amap), + Curves_on_surface_topology(const Mesh& amesh, bool /* display_time */=false) : + m_original_mesh(amesh), m_minimal_quadrangulation(nullptr) {} @@ -51,8 +52,7 @@ public: if (m_minimal_quadrangulation==nullptr) { m_minimal_quadrangulation.reset - (new internal::Minimal_quadrangulation - (m_original_map, display_time)); + (new Minimal_quadrangulation(m_original_mesh, display_time)); } } @@ -61,7 +61,7 @@ public: const Reduced_map& get_minimal_quadrangulation() const { CGAL_assertion(is_minimal_quadrangulation_computed()); - return m_minimal_quadrangulation->get_map(); + return m_minimal_quadrangulation->get_reduced_map(); } /// @return true iff 'p' is contractible. @@ -93,9 +93,8 @@ public: } protected: - const Mesh& m_original_map; - mutable std::unique_ptr> - m_minimal_quadrangulation; + const Mesh& m_original_mesh; + mutable std::unique_ptr m_minimal_quadrangulation; }; } // namespace Surface_mesh_topology diff --git a/Surface_mesh_topology/include/CGAL/Polygonal_schema_min_items.h b/Surface_mesh_topology/include/CGAL/Polygonal_schema_min_items.h index 032480eaf08..1159c6058b3 100644 --- a/Surface_mesh_topology/include/CGAL/Polygonal_schema_min_items.h +++ b/Surface_mesh_topology/include/CGAL/Polygonal_schema_min_items.h @@ -23,8 +23,6 @@ #include -#include - namespace CGAL { namespace Surface_mesh_topology { diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 268398f583a..ed3a7c539a4 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -24,8 +24,8 @@ // Should be defined before to include Path_on_surface_with_rle.h // If nothing is defined, use V1 // #define CGAL_PWRLE_TURN_V1 // Compute turns by turning (method of CMap) -// #define CGAL_PWRLE_TURN_V2 // Compute turns by using an id of darts, given by an hash-table (built and given by Curves_on_surface_topology) -#define CGAL_PWRLE_TURN_V3 // Compute turns by using an id of darts, associated in Info of Darts (build by Curves_on_surface_topology) +// #define CGAL_PWRLE_TURN_V2 // Compute turns by using an id of darts, given by an hash-table (built and given by Minimal_quadrangulation) +#define CGAL_PWRLE_TURN_V3 // Compute turns by using an id of darts, associated in Info of Darts (build by Minimal_quadrangulation) #include @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -56,7 +56,6 @@ struct Reduced_map_items typedef CGAL::cpp11::tuple Attributes; }; }; -typedef CGAL::Combinatorial_map<2, Reduced_map_items> Reduced_map; template class Minimal_quadrangulation @@ -64,24 +63,45 @@ class Minimal_quadrangulation public: typedef Minimal_quadrangulation Self; typedef Mesh_ Mesh; - typedef Reduced_map Map_; - typedef typename Reduced_map::Dart_handle Dart_handle; - typedef typename Reduced_map::Dart_const_handle Dart_const_handle; - typedef typename Get_map::type Map; - // Associate each dart of the original map, not removed, a pair of darts in the - // reduced map. - typedef boost::unordered_map > TPaths; + typedef typename Get_map::type Original_map; // Mesh seen as a 2-map + typedef typename Original_map::Dart_const_handle Original_dart_const_handle; + + typedef CGAL::Combinatorial_map<2, Reduced_map_items> Reduced_map; + typedef typename Reduced_map::Dart_handle Dart_handle; + typedef typename Reduced_map::Dart_const_handle Dart_const_handle; + + // Associate each dart of the original map, not removed, a pair of darts in + // the reduced map. + typedef std::unordered_map > TPaths; + + // Associations between original darts and their copy. + // Use only locally during the construction of the minimal quadrangulation. + typedef std::unordered_map Origin_to_copy; + typedef std::unordered_map Copy_to_origin; #ifdef CGAL_PWRLE_TURN_V2 - typedef boost::unordered_map TDartIds; + typedef std::unordered_map TDartIds; #endif //CGAL_PWRLE_TURN_V2 - Minimal_quadrangulation(const Mesh& amap, bool display_time=false) : - m_original_map(amap) + /// @return the original map + const Original_map& get_original_map() const + { return m_original_map; } + + /// @return the reduced map + const Reduced_map& get_reduced_map() const + { return m_reduced_map; } + + /// @return the reduced map + Reduced_map& get_reduced_map() + { return m_reduced_map; } + + /// Constructor taking a mesh as parameter. + Minimal_quadrangulation(const Mesh& amesh, bool display_time=false) : + m_original_map(amesh) { - if (!m_original_map.is_without_boundary(1)) + if (!get_original_map().is_without_boundary(1)) { std::cerr<<"ERROR: the given amap has 1-boundaries; " <<"such a surface is not possible to process here." @@ -94,37 +114,20 @@ public: { t.start(); t2.start(); } // The mapping between darts of the original map into the copied map. - boost::unordered_map - origin_to_copy; + Origin_to_copy origin_to_copy; // The mapping between darts of the copy into darts of the original map. - boost::unordered_map - copy_to_origin; + Copy_to_origin copy_to_origin; - // We copy the original map, while keeping mappings between darts. - // m_map.copy(m_original_map, &origin_to_copy, ©_to_origin); + // We reserve three marks: m_mart_T and m_mark_L to mark darts in + // get_original_map() that belong to T or to L (i.e. edges contracted or + // removed), m_mark_perforated to mark perforated faces. + m_mark_T=get_original_map().get_new_mark(); + m_mark_L=get_original_map().get_new_mark(); + m_mark_perforated=get_reduced_map().get_new_mark(); - if (display_time) - { - t2.stop(); - std::cout<<"[TIME] Copy map: "<(dh2)) + get_reduced_map().mark(dh2, marktemp); + std::cout<(dh2)) <(dh2); + dh2=get_reduced_map().template beta<0,2>(dh2); } while(dh2!=it); } } - get_map().free_mark(marktemp); - get_map().display_darts(std::cout); + get_reduced_map().free_mark(marktemp); + get_reduced_map().display_darts(std::cout); #endif if (display_time) @@ -268,15 +247,14 @@ public: < pt=transform_original_path_into_quad_surface_for_torus(p); @@ -344,7 +322,7 @@ public: } // Here we have two non empty closed paths. - if (get_map().is_empty()) + if (get_reduced_map().is_empty()) { return true; } // Two closed paths on a sphere are always homotopic. CGAL::Timer t; @@ -352,7 +330,7 @@ public: { t.start(); } bool res=false; - if (m_map_is_a_torus_quadrangulation()) + if (reduced_map_is_a_torus()) { // Case of torus Path_on_surface pt1=transform_original_path_into_quad_surface_for_torus(p1); @@ -378,15 +356,6 @@ public: std::cout<<"Length of reduced paths: "<(dh1), dh2); + return compute_positive_turn_given_ids + (get_reduced_map().template beta<2>(dh1), dh2); #else // defined(CGAL_PWRLE_TURN_V2) || defined(CGAL_PWRLE_TURN_V3) - CGAL_assertion((!get_map().template is_free<1>(dh1))); - CGAL_assertion((!get_map().template is_free<2>(dh1))); + CGAL_assertion((!get_reduced_map().template is_free<1>(dh1))); + CGAL_assertion((!get_reduced_map().template is_free<2>(dh1))); - if (dh2==get_map().template beta<2>(dh1) && - dh2==get_map().template beta<1>(dh1)) + if (dh2==get_reduced_map().template beta<2>(dh1) && + dh2==get_reduced_map().template beta<1>(dh1)) { return 0; } - if (get_map().is_marked(dh1, m_mark_hole)) + if (get_reduced_map().is_marked(dh1, m_mark_hole)) { return std::numeric_limits::max(); } Dart_const_handle ddh1=dh1; std::size_t res=1; - while (get_map().template beta<1>(ddh1)!=dh2) + while (get_reduced_map().template beta<1>(ddh1)!=dh2) { - CGAL_assertion(!get_map().template is_free<2>(get_map().template beta<1>(ddh1))); + CGAL_assertion(!get_reduced_map().template is_free<2> + (get_reduced_map().template beta<1>(ddh1))); ++res; - ddh1=get_map().template beta<1, 2>(ddh1); - if (get_map().is_marked(ddh1, m_mark_hole)) + ddh1=get_reduced_map().template beta<1, 2>(ddh1); + if (get_reduced_map().is_marked(ddh1, m_mark_hole)) { return std::numeric_limits::max(); } - CGAL_assertion(!get_map().template is_free<1>(ddh1)); - CGAL_assertion(get_map().template beta<1>(ddh1)==dh2 || ddh1!=dh1); + CGAL_assertion(!get_reduced_map().template is_free<1>(ddh1)); + CGAL_assertion(get_reduced_map().template beta<1>(ddh1)==dh2 || ddh1!=dh1); } return res; #endif // defined(CGAL_PWRLE_TURN_V2) || defined(CGAL_PWRLE_TURN_V3) @@ -484,62 +457,56 @@ public: Dart_const_handle dh2) const { #if defined(CGAL_PWRLE_TURN_V2) || defined(CGAL_PWRLE_TURN_V3) - return compute_negative_turn_given_ids(get_map().template beta<2>(dh1), dh2); + return compute_negative_turn_given_ids + (get_reduced_map().template beta<2>(dh1), dh2); #else // defined(CGAL_PWRLE_TURN_V2) || defined(CGAL_PWRLE_TURN_V3) - CGAL_assertion((!get_map().template is_free<1>(dh1))); - CGAL_assertion((!get_map().template is_free<2>(dh1))); + CGAL_assertion((!get_reduced_map().template is_free<1>(dh1))); + CGAL_assertion((!get_reduced_map().template is_free<2>(dh1))); - if (dh2==get_map().template beta<2>(dh1) && - dh1==get_map().template beta<0>(dh2)) + if (dh2==get_reduced_map().template beta<2>(dh1) && + dh1==get_reduced_map().template beta<0>(dh2)) { return 0; } - if (get_map().is_marked(get_map().template beta <2>(dh1), m_mark_hole)) + if (get_reduced_map().is_marked + (get_reduced_map().template beta <2>(dh1), m_mark_hole)) { return std::numeric_limits::max(); } - dh1=get_map().template beta<2>(dh1); - dh2=get_map().template beta<2>(dh2); + dh1=get_reduced_map().template beta<2>(dh1); + dh2=get_reduced_map().template beta<2>(dh2); Dart_const_handle ddh1=dh1; std::size_t res=1; - while (get_map().template beta<0>(ddh1)!=dh2) + while (get_reduced_map().template beta<0>(ddh1)!=dh2) { - CGAL_assertion(!get_map().template is_free<2>(get_map().template beta<0>(ddh1))); + CGAL_assertion(!get_reduced_map().template is_free<2> + (get_reduced_map().template beta<0>(ddh1))); ++res; - ddh1=get_map().template beta<0, 2>(ddh1); - if (get_map().is_marked(ddh1, m_mark_hole)) + ddh1=get_reduced_map().template beta<0, 2>(ddh1); + if (get_reduced_map().is_marked(ddh1, m_mark_hole)) { return std::numeric_limits::max(); } - CGAL_assertion(!get_map().template is_free<0>(ddh1)); - CGAL_assertion(get_map().template beta<0>(ddh1)==dh2 || ddh1!=dh1); + CGAL_assertion(!get_reduced_map().template is_free<0>(ddh1)); + CGAL_assertion(get_reduced_map().template beta<0>(ddh1)==dh2 || ddh1!=dh1); } return res; #endif // defined(CGAL_PWRLE_TURN_V2) || defined(CGAL_PWRLE_TURN_V3) } - /// @returns the reduced map - const Reduced_map& get_map() const - { return m_map; } - - /// @returns the reduced map - Reduced_map& get_map() - { return m_map; } - protected: - /// @returns true iff the dart dh is contracted, i.e. if it belongs to T - /// or if it was contracted during the spur removal after the quadrangulation - bool is_contracted(typename Map::Dart_const_handle dh) const - { return m_original_map.is_marked(dh, m_mark_T); } + /// @return true iff the dart dh is contracted, i.e. if it belongs to T + bool is_contracted(Original_dart_const_handle dh) const + { return get_original_map().is_marked(dh, m_mark_T); } void count_edges_of_path_on_torus (const Path_on_surface& path, int& a, int& b) const { - CGAL_assertion(m_map_is_a_torus_quadrangulation()); + CGAL_assertion(reduced_map_is_a_torus()); - Dart_const_handle dha=get_map().darts().begin(); - Dart_const_handle dhb=get_map().template beta<1>(dha); + Dart_const_handle dha=get_reduced_map().darts().begin(); + Dart_const_handle dhb=get_reduced_map().template beta<1>(dha); a=0; b=0; for (std::size_t i=0; i(dha)) { ++a; } + else if (path[i]==get_reduced_map().template beta<2>(dha)) { ++a; } else if (path[i]==dhb) { --b; } - else if (path[i]==get_map().template beta<2>(dhb)) { ++b; } + else if (path[i]==get_reduced_map().template beta<2>(dhb)) { ++b; } } else { if (path[i]==dha) { ++a; } - else if (path[i]==get_map().template beta<2>(dha)) { --a; } + else if (path[i]==get_reduced_map().template beta<2>(dha)) { --a; } else if (path[i]==dhb) { ++b; } - else if (path[i]==get_map().template beta<2>(dhb)) { --b; } + else if (path[i]==get_reduced_map().template beta<2>(dhb)) { --b; } } } } Path_on_surface - transform_original_path_into_quad_surface_for_torus(const Path_on_surface& path) const + transform_original_path_into_quad_surface_for_torus + (const Path_on_surface& path) const { - CGAL_assertion(get_map().number_of_darts()==4); + CGAL_assertion(reduced_map_is_a_torus()); - Path_on_surface res(get_map()); + Path_on_surface res(get_reduced_map()); if (path.is_empty()) return res; Dart_const_handle cur; @@ -575,11 +543,11 @@ protected: if (!is_contracted(path[i]))// here flip doesn't matter { cur=get_first_dart_of_the_path(path[i], path.get_ith_flip(i), false); - CGAL_assertion(!get_map().is_marked(cur, m_mark_perforated)); + CGAL_assertion(!get_reduced_map().is_marked(cur, m_mark_perforated)); while(cur!=get_second_dart_of_the_path(path[i], path.get_ith_flip(i), false)) { res.push_back(cur, false, false); - cur=get_map().template beta<1>(cur); + cur=get_reduced_map().template beta<1>(cur); } } } @@ -621,178 +589,176 @@ protected: } /// Mark the edge containing adart in the original map. - void mark_edge(const Map& amap, typename Map::Dart_const_handle adart, - std::size_t amark) + void mark_original_edge(Original_dart_const_handle adart, + std::size_t amark) { - amap.mark(adart, amark); - if (!amap.template is_free<2>(adart)) - { amap.mark(amap.template beta<2>(adart), amark); } + get_original_map().mark(adart, amark); + if (!get_original_map().template is_free<2>(adart)) + { get_original_map().mark(get_original_map().template beta<2>(adart), + amark); } } - /// Erase the edge given by adart (which belongs to the map m_map, i.e. the - /// copy) from the associative array copy_to_origin, and erase the - /// corresponding edge (which belongs to the map m_original_map) from the - /// array origin_to_copy - void erase_edge_from_associative_arrays - (Dart_handle adart, - boost::unordered_map& - origin_to_copy, - boost::unordered_map& - copy_to_origin) + /// Mark the edge containing adart in the reduced map (which is 2-closed) + void mark_reduced_edge(Dart_const_handle adart, std::size_t amark) { - if (!m_original_map.template is_free<2>(copy_to_origin[adart])) + get_reduced_map().mark(adart, amark); + get_reduced_map().mark(get_reduced_map().template beta<2>(adart), amark); + } + + /// Erase the edge given by adart (which belongs to the map m_reduced_map, i.e. the + /// copy) from the associative array copy_to_origin, and erase the + /// corresponding edge (which belongs to the map get_original_map()) from the + /// array origin_to_copy + void erase_edge_from_associative_arrays(Dart_handle adart, + Origin_to_copy& origin_to_copy, + Copy_to_origin & copy_to_origin) + { + if (!get_original_map().template is_free<2>(copy_to_origin[adart])) { - origin_to_copy.erase(m_original_map.template beta<2> + origin_to_copy.erase(get_original_map().template beta<2> (copy_to_origin[adart])); - copy_to_origin.erase(get_map().template beta<2>(adart)); + copy_to_origin.erase(get_reduced_map().template beta<2>(adart)); } origin_to_copy.erase(copy_to_origin[adart]); copy_to_origin.erase(adart); } - typename Map::Dart_const_handle prev_in_boundary(typename Map::Dart_const_handle d) + Original_dart_const_handle prev_in_boundary(Original_dart_const_handle d) { - typename Map::Dart_const_handle res=m_original_map.template beta<0>(d); - while(!m_original_map.template is_free<2>(res)) - { res = m_original_map.template beta<2, 0>(res); } + Original_dart_const_handle res=get_original_map().template beta<0>(d); + while(!get_original_map().template is_free<2>(res)) + { res = get_original_map().template beta<2, 0>(res); } return res; } - /// Step 1) Transform m_map into an equivalent surface having only one + /// Step 1) Transform m_reduced_map into an equivalent surface having only one /// vertex. All edges contracted during this step belong to the spanning - /// tree T, and thus corresponding edges in m_original_map are marked. + /// tree T, and thus corresponding edges in get_original_map() are marked. /// Marks all darts belonging to T using a BFS void compute_T() { - typename Map::Dart_const_handle dh; - auto grey=m_original_map.get_new_mark(); - std::queue queue; - m_original_map.template mark_cell<0>(m_original_map.darts().begin(), grey); - queue.push(m_original_map.darts().begin()); + Original_dart_const_handle dh; + auto grey=get_original_map().get_new_mark(); + std::queue queue; + get_original_map().template mark_cell<0> + (get_original_map().darts().begin(), grey); + queue.push(get_original_map().darts().begin()); while (!queue.empty()) { dh=queue.front(); queue.pop(); - for (auto it=m_original_map.template darts_of_cell<0>(dh).begin(), - itend=m_original_map.template darts_of_cell<0>(dh).end(); + for (auto it=get_original_map().template darts_of_cell<0>(dh).begin(), + itend=get_original_map().template darts_of_cell<0>(dh).end(); it!=itend; ++it) { - if (!m_original_map.is_marked(m_original_map.template beta<1>(it), - grey)) + if (!get_original_map().is_marked + (get_original_map().template beta<1>(it), grey)) { - mark_edge(m_original_map, it, m_mark_T); - m_original_map.template mark_cell<0> - (m_original_map.template beta<1>(it), grey); - queue.push(m_original_map.template beta<1>(it)); + mark_original_edge(it, m_mark_T); + get_original_map().template mark_cell<0> + (get_original_map().template beta<1>(it), grey); + queue.push(get_original_map().template beta<1>(it)); } } } - m_original_map.free_mark(grey); + get_original_map().free_mark(grey); } void surface_simplification_in_one_vertex - (boost::unordered_map& - origin_to_copy, - boost::unordered_map& - copy_to_origin) + (Origin_to_copy& origin_to_copy,Copy_to_origin& copy_to_origin) { compute_T(); Dart_handle d1, d2; - for (typename Map::Dart_range::const_iterator - it=m_original_map.darts().begin(), itend=m_original_map.darts().end(); - it!=itend; ++it) + for (typename Original_map::Dart_range::const_iterator + it=get_original_map().darts().begin(), + itend=get_original_map().darts().end(); it!=itend; ++it) { - if (!m_original_map.is_marked(it, m_mark_T)) + if (!get_original_map().is_marked(it, m_mark_T)) { - if (m_original_map.template is_free<2>(it)) + if (get_original_map().template is_free<2>(it)) {// case of a boundary - d1=get_map().create_dart(); - d2=get_map().create_dart(); - get_map().template basic_link_beta_for_involution<2>(d1, d2); + d1=get_reduced_map().create_dart(); + d2=get_reduced_map().create_dart(); + get_reduced_map().template basic_link_beta_for_involution<2>(d1, d2); origin_to_copy[it]=d1; copy_to_origin[d1]=it; - get_map().mark(d2, m_mark_perforated); + get_reduced_map().mark(d2, m_mark_perforated); } - else if (typename Map::Dart_const_handle(it)< - m_original_map.template beta<2>(it)) + else if (Original_dart_const_handle(it)< + get_original_map().template beta<2>(it)) { - d1=get_map().create_dart(); - d2=get_map().create_dart(); - get_map().template basic_link_beta_for_involution<2>(d1, d2); + d1=get_reduced_map().create_dart(); + d2=get_reduced_map().create_dart(); + get_reduced_map().template basic_link_beta_for_involution<2>(d1, d2); origin_to_copy[it]=d1; - origin_to_copy[m_original_map.template beta<2>(it)]=d2; + origin_to_copy[get_original_map().template beta<2>(it)]=d2; copy_to_origin[d1]=it; - copy_to_origin[d2]=m_original_map.template beta<2>(it); + copy_to_origin[d2]=get_original_map().template beta<2>(it); - if (m_original_map.is_perforated(it)) - { get_map().mark(d1, m_mark_perforated); } - if (m_original_map.is_perforated(m_original_map.template beta<2>(it))) - { get_map().mark(d2, m_mark_perforated); } + if (get_original_map().is_perforated(it)) + { get_reduced_map().mark(d1, m_mark_perforated); } + if (get_original_map().is_perforated + (get_original_map().template beta<2>(it))) + { get_reduced_map().mark(d2, m_mark_perforated); } } } } /// Now we only need to do the basic_link_beta_1 - typename Map::Dart_const_handle dd1; - for (typename Map::Dart_range::const_iterator - it=m_original_map.darts().begin(), itend=m_original_map.darts().end(); - it!=itend; ++it) + Original_dart_const_handle dd1; + for (typename Original_map::Dart_range::const_iterator + it=get_original_map().darts().begin(), + itend=get_original_map().darts().end(); it!=itend; ++it) { - if (!m_original_map.is_marked(it, m_mark_T)) + if (!get_original_map().is_marked(it, m_mark_T)) { - dd1=m_original_map.template beta<1>(it); - while(m_original_map.is_marked(dd1, m_mark_T)) - { dd1=m_original_map.template beta<1>(dd1); } - get_map().basic_link_beta_1(origin_to_copy[it], origin_to_copy[dd1]); // let's link both - if (m_original_map.template is_free<2>(it)) + dd1=get_original_map().template beta<1>(it); + while(get_original_map().is_marked(dd1, m_mark_T)) + { dd1=get_original_map().template beta<1>(dd1); } + get_reduced_map().basic_link_beta_1(origin_to_copy[it], + origin_to_copy[dd1]); // let's link both + if (get_original_map().template is_free<2>(it)) { dd1=prev_in_boundary(it); - while(m_original_map.is_marked(dd1, m_mark_T)) + while(get_original_map().is_marked(dd1, m_mark_T)) { dd1=prev_in_boundary(dd1); } - get_map().basic_link_beta_1(get_map().template beta<2>(origin_to_copy[it]), - get_map().template beta<2>(origin_to_copy[dd1])); + get_reduced_map().basic_link_beta_1 + (get_reduced_map().template beta<2>(origin_to_copy[it]), + get_reduced_map().template beta<2>(origin_to_copy[dd1])); } } } } - /// Step 2) Initialize, for each edge of m_original_map not in the spanning + /// Step 2) Initialize, for each edge of get_original_map() not in the spanning /// tree T, the pair of darts of the edge in m_copy. This pair of edges /// will be updated later (in surface_simplification_in_one_face() and in /// surface_quadrangulate() ). - void initialize_length_two_paths - (const boost::unordered_map& - origin_to_copy) + void initialize_length_two_paths(Origin_to_copy& origin_to_copy) { m_paths.clear(); - for (typename Map::Dart_range::const_iterator - it=m_original_map.darts().begin(), - itend=m_original_map.darts().end(); it!=itend; ++it) + for (typename Original_map::Dart_range::const_iterator + it=get_original_map().darts().begin(), + itend=get_original_map().darts().end(); it!=itend; ++it) { - if (!m_original_map.is_marked(it, m_mark_T)) + if (!get_original_map().is_marked(it, m_mark_T)) { - if (m_original_map.template is_free<2>(it) || - typename Map::Dart_const_handle(it)(it)) - { - m_paths[it]=std::make_pair(origin_to_copy.at(it), nullptr); - /*get_map().template beta<2>(origin_to_copy.at(it))); - CGAL_assertion(m_paths[it].first!=m_paths[it].second); - CGAL_assertion(m_paths[it].first== - get_map().template beta<2>(m_paths[it].second));*/ - } + if (get_original_map().template is_free<2>(it) || + Original_dart_const_handle(it)(it)) + { m_paths[it]=std::make_pair(origin_to_copy.at(it), nullptr); } } } #ifdef CGAL_TRACE_CMAP_TOOLS std::cout<<"Number of darts in paths: "<& copy_to_origin) + Copy_to_origin& copy_to_origin) { Dart_handle dh; Dart_handle ddh; - auto grey=get_map().get_new_mark(); + auto grey=get_reduced_map().get_new_mark(); std::queue queue; - for (auto it=get_map().darts().begin(), itend=get_map().darts().end(); - it!=itend; ++it) + for (auto it=get_reduced_map().darts().begin(), + itend=get_reduced_map().darts().end(); it!=itend; ++it) { - if (!get_map().is_marked(it, grey)) + if (!get_reduced_map().is_marked(it, grey)) { - get_map().template mark_cell<2>(it, grey); - if (!get_map().is_marked(it, m_mark_perforated)) + get_reduced_map().template mark_cell<2>(it, grey); + if (!get_reduced_map().is_marked(it, m_mark_perforated)) { queue.push(it); @@ -828,18 +793,18 @@ protected: ddh=dh; do { - if (!get_map().is_marked(get_map().template beta<2>(ddh), grey) && - !get_map().is_marked(get_map().template beta<2>(ddh), - m_mark_perforated)) + if (!get_reduced_map().is_marked + (get_reduced_map().template beta<2>(ddh), grey) && + !get_reduced_map().is_marked + (get_reduced_map().template beta<2>(ddh), m_mark_perforated)) { - get_map().mark(ddh, toremove); - get_map().mark(get_map().template beta<2>(ddh), toremove); - mark_edge(m_original_map, copy_to_origin[ddh], m_mark_L); - get_map().template mark_cell<2>(get_map().template beta<2>(ddh), - grey); - queue.push(get_map().template beta<2>(ddh)); + mark_reduced_edge(ddh, toremove); + mark_original_edge(copy_to_origin[ddh], m_mark_L); + get_reduced_map().template mark_cell<2> + (get_reduced_map().template beta<2>(ddh), grey); + queue.push(get_reduced_map().template beta<2>(ddh)); } - ddh=get_map().template beta<1>(ddh); + ddh=get_reduced_map().template beta<1>(ddh); } while (dh!=ddh); } @@ -847,8 +812,8 @@ protected: } } - CGAL_assertion(get_map().is_whole_map_marked(grey)); - get_map().free_mark(grey); + CGAL_assertion(get_reduced_map().is_whole_map_marked(grey)); + get_reduced_map().free_mark(grey); } /// Update all length two paths, before edge removal. Edges that will be @@ -856,348 +821,128 @@ protected: /// updates, since they are associated only with their corresponding dart /// in the original map (and thus with only one dart and not two). void update_length_two_paths_before_edge_removals - (typename Map::size_type toremove, - const boost::unordered_map& copy_to_origin) + (typename Original_map::size_type toremove, Copy_to_origin& copy_to_origin) { - /* std::cout<<"************ PATH BEFORE: "<first) - <<" -> "<second.first) - <<", "; - if (it->second.second==nullptr) { std::cout<<"NULL "; } - else { std::cout<second.second)<<" "; } - if (get_map().is_marked(it->second.first, toremove)) - { std::cout<<" TO REMOVE 1"; } - if (it->second.second!=nullptr && - get_map().is_marked(it->second.second, toremove)) - { std::cout<<" TO REMOVE 2"; } - else - { - CGAL_assertion(it->second.second==nullptr || - get_map().is_marked(it->second.second, toremove)); - } - std::cout<(initdart)!=initdart */ /* && - !get_map().is_marked(get_map().template beta<2>(initdart), - m_mark_perforated) */) + if (!get_reduced_map().is_marked(initdart, toremove) && + !get_reduced_map().is_marked(initdart, m_mark_perforated)) { // Here we are on a border edge of a "real" face (i.e. non perforated) - /* - // and adjacent to a "real" face - std::cout<<"[BEGIN] Process ("<second) - <<", "<second,2)) - { std::cout<<"beta2=(free"; } - else - { std::cout<<"beta2=("<second,2)); } - std::cout<(initdart); - while(get_map().is_marked(curdart, toremove)) + curdart=get_reduced_map().template beta<0, 2>(initdart); + while(get_reduced_map().is_marked(curdart, toremove)) { // Here, all edges marked to remove are between two real faces. CGAL_assertion(copy_to_origin.count(curdart)==1); set_first_dart_of_the_path(copy_to_origin.find(curdart)->second, initdart); - /* std::cout<second))<second)); - /* std::cout<<" Dart updated1 for ("<second) - <<", "< "; - std::cout<second))<(curdart); + curdart=get_reduced_map().template beta<0, 2>(curdart); } - if (!get_map().is_marked(get_map().template beta<2>(curdart), - m_mark_perforated)) + if (!get_reduced_map().is_marked + (get_reduced_map().template beta<2>(curdart), m_mark_perforated)) { - d1=copy_to_origin.find(get_map().template beta<2>(curdart))->second; - if (m_original_map.template is_free<2>(d1) || - d1(d1)) + d1=copy_to_origin.find(get_reduced_map().template beta<2>(curdart))->second; + if (get_original_map().template is_free<2>(d1) || + d1(d1)) { m_paths[d1].second=initdart; } - /* std::cout<<" Dart updated2 for ("<(curdart))<<")" - <<" -> "; - std::cout<<" -> "< beta1=" - <(it)) - <<" beta2=" <(it)); - if (get_map().is_marked(it, m_mark_perforated)) - { std::cout<<" PERFORATED";} - std::cout<first) - <<" -> "<second.first) - <<", "; - if (it->second.second==nullptr) { std::cout<<"NULL "<second.second)<<" "<second.first, m_mark_perforated)) - { std::cout<<" PERFORATED-1"; } - if (it->second.second!=nullptr && - get_map().is_marked(it->second.second, m_mark_perforated)) - { std::cout<<" PERFORATED-2"; } - if (get_map().is_marked(it->second.first, toremove)) - { - CGAL_assertion(get_map().is_marked(it->second.second, toremove)); - std::cout<<" REMOVE-1"; - } - if (it->second.second!=nullptr && - get_map().is_marked(it->second.second, toremove)) - { - std::cout<<" REMOVE-2"; - } - std::cout<first, m_mark_T)); - CGAL_assertion(!get_map().is_marked(it->second.first, toremove)); - if (it->second.second!=nullptr) - { CGAL_assertion(!get_map().is_marked(it->second.second, toremove)); } - if (it->second.second==nullptr) - { - - std::cout<<"Test dart ("<first) - <<", "<second.first)<second.first, m_mark_perforated) || - get_map().is_marked - (get_map().template beta<2>(it->second.first), - m_mark_perforated)); - } - else - { - CGAL_assertion(!get_map().is_marked(it->second.first, m_mark_perforated)); - CGAL_assertion(!get_map().is_marked(it->second.second, m_mark_perforated)); - } - }*/ } /// Remove all loops after having merge all real faces in one. /// Erase from m_paths all darts linked with such a dart. - void remove_loops - (boost::unordered_map& - copy_to_origin) + void remove_non_perforated_loops(Copy_to_origin& copy_to_origin) { - get_map().set_automatic_attributes_management(false); + get_reduced_map().set_automatic_attributes_management(false); - bool updated=true; - typename Map::Dart_const_handle origin_dart; - // do + Original_dart_const_handle origin_dart; + for (typename Reduced_map::Dart_range::iterator + it=get_reduced_map().darts().begin(), + itend=get_reduced_map().darts().end(); it!=itend; ++it) { - updated=false; - for (typename Reduced_map::Dart_range::iterator - it=get_map().darts().begin(), itend=get_map().darts().end(); - it!=itend; ++it) - { - if (get_map().is_dart_used(it) && - !get_map().is_marked(it, m_mark_perforated) && - get_map().template beta<1>(it)==it) - { + if (get_reduced_map().is_dart_used(it) && + !get_reduced_map().is_marked(it, m_mark_perforated) && + get_reduced_map().template beta<1>(it)==it) + { // A non perforated loop. origin_dart=copy_to_origin[it]; - if (!m_original_map.template is_free<2>(origin_dart) && - origin_dart>m_original_map.template beta<2>(origin_dart)) - { origin_dart=m_original_map.template beta<2>(origin_dart); } + if (!get_original_map().template is_free<2>(origin_dart) && + origin_dart>get_original_map().template beta<2>(origin_dart)) + { origin_dart=get_original_map().template beta<2>(origin_dart); } - mark_edge(m_original_map, origin_dart, m_mark_T); + mark_original_edge(origin_dart, m_mark_T); - if (get_map().is_marked(get_map().template beta<2>(it), + if (get_reduced_map().is_marked(get_reduced_map().template beta<2>(it), m_mark_perforated)) - { get_map().template mark_cell<2>(it, m_mark_perforated); } + { get_reduced_map().template mark_cell<2>(it, m_mark_perforated); } - get_map().template remove_cell<1>(it); - updated=true; + get_reduced_map().template remove_cell<1>(it); } } - } - //while (updated); - get_map().set_automatic_attributes_management(true); - for (typename Reduced_map::Dart_range::iterator - it=get_map().darts().begin(), itend=get_map().darts().end(); - it!=itend; ++it) - { - CGAL_assertion(get_map().is_marked(it, m_mark_perforated) || - get_map().template beta<1>(it)!=it); - } + get_reduced_map().set_automatic_attributes_management(true); /// We remove from m_paths all associations having a removed dart for (auto it=m_paths.begin(), itend=m_paths.end(); it!=itend; ) { - if (!get_map().is_dart_used(it->second.first)) + if (!get_reduced_map().is_dart_used(it->second.first)) { - mark_edge(m_original_map, it->first, m_mark_T); + mark_original_edge(it->first, m_mark_T); it=m_paths.erase(it); } else if (it->second.second!=nullptr && - !get_map().is_dart_used(it->second.second)) + !get_reduced_map().is_dart_used(it->second.second)) { - mark_edge(m_original_map, it->first, m_mark_T); + mark_original_edge(it->first, m_mark_T); it=m_paths.erase(it); } else { ++it; } } } + /// Simplify the reduced map by merging all adjacent non perforated faces. void surface_simplification_in_one_face - (boost::unordered_map& - origin_to_copy, - boost::unordered_map& - copy_to_origin) + (Origin_to_copy& origin_to_copy, Copy_to_origin& copy_to_origin) { - get_map().set_automatic_attributes_management(false); + get_reduced_map().set_automatic_attributes_management(false); - typename Reduced_map::size_type - toremove=get_map().get_new_mark(); + typename Reduced_map::size_type toremove=get_reduced_map().get_new_mark(); compute_L(toremove, copy_to_origin); - if (get_map().number_of_marked_darts(toremove)==get_map().number_of_darts()) + if (get_reduced_map().number_of_marked_darts(toremove)== + get_reduced_map().number_of_darts()) { // Case of sphere; all darts are removed. m_paths.clear(); - get_map().clear(); + get_reduced_map().clear(); } else { + // Update the length two paths before to remove the edges. update_length_two_paths_before_edge_removals(toremove, copy_to_origin); - // We remove all the edges to remove. + // Then remove all the edges marekd to remove. for (typename Reduced_map::Dart_range::iterator - it=get_map().darts().begin(), itend=get_map().darts().end(); - it!=itend; ++it) + it=get_reduced_map().darts().begin(), + itend=get_reduced_map().darts().end(); it!=itend; ++it) { - if (get_map().is_dart_used(it) && get_map().is_marked(it, toremove)) + if (get_reduced_map().is_dart_used(it) && + get_reduced_map().is_marked(it, toremove)) { - CGAL_assertion(get_map().is_marked(get_map().template beta<2>(it), - toremove)); + CGAL_assertion(get_reduced_map().is_marked + (get_reduced_map().template beta<2>(it), toremove)); erase_edge_from_associative_arrays(it, origin_to_copy, copy_to_origin); - // TODO later (?) optimize and replace the remove_cell call by the modification by hand - // or develop a specialized version of remove_cell - get_map().template remove_cell<1>(it); + get_reduced_map().template remove_cell<1>(it); } } } - get_map().set_automatic_attributes_management(true); - get_map().free_mark(toremove); - - /* std::cout<<"************ PATH BEFORE : "<first) - <<" -> "<second.first) - <<", "; - if (it->second.second==nullptr) { std::cout<<"NULL "<second.second)<<" "<second.first, m_mark_perforated) && - get_map().template beta<1>(it->second.first)==it->second.first) - { std::cout<<" LOOP1"; } - if (it->second.second!=nullptr && - !get_map().is_marked(it->second.second, m_mark_perforated) && - get_map().template beta<1>(it->second.second)==it->second.second) - { std::cout<<" LOOP2"; } - std::cout<(it)==it?"loop":"")<(it)==it) - { - origin_dart=copy_to_origin[it]; - if (!m_original_map.template is_free<2>(origin_dart) && - origin_dart>m_original_map.template beta<2>(origin_dart)) - { origin_dart=m_original_map.template beta<2>(origin_dart); } - - CGAL_assertion(m_paths.find(origin_dart)!=m_paths.end()); - - std::cout<<" Erase "<(origin_dart)) - { CGAL_assertion(m_paths.find(m_original_map.template beta<2> - (origin_dart))==m_paths.end()); } - } - } - - std::cout<<"************ PATH AFTER: "<first) - <<" -> "<second.first) - <<", "; - if (it->second.second==nullptr) { std::cout<<"NULL "<second.second)<<" "<second.first, m_mark_perforated) && - get_map().template beta<1>(it->second.first)==it->second.first) - { std::cout<<" LOOP1"; } - if (it->second.second!=nullptr && - !get_map().is_marked(it->second.second, m_mark_perforated) && - get_map().template beta<1>(it->second.second)==it->second.second) - { std::cout<<" LOOP2"; } - std::cout<second.first, m_mark_perforated) || - get_map().template beta<1>(itp->second.first)!=itp->second.first); - } */ + get_reduced_map().set_automatic_attributes_management(true); + get_reduced_map().free_mark(toremove); } /// Step 4) quadrangulate the surface. @@ -1205,197 +950,150 @@ protected: { // Here the map has only one vertex and one face if we have a closed surface, // and maybe several faces if the surface has boundaries - typename Map::size_type oldedges=get_map().get_new_mark(); - get_map().negate_mark(oldedges); // now all edges are marked + typename Reduced_map::size_type oldedges=get_reduced_map().get_new_mark(); + get_reduced_map().negate_mark(oldedges); // now all edges are marked // 1) We insert a vertex in each face which is not perforated. // New edges created by the operation are not marked oldedges. - typename Map::size_type treated=get_map().get_new_mark(); + typename Reduced_map::size_type treated=get_reduced_map().get_new_mark(); for (typename Reduced_map::Dart_range::iterator - it=get_map().darts().begin(); it!=get_map().darts().end(); ++it) + it=get_reduced_map().darts().begin(); it!=get_reduced_map().darts().end(); ++it) { - if (!get_map().is_marked(it, treated)) + if (!get_reduced_map().is_marked(it, treated)) { - get_map().template mark_cell<2>(it, treated); - if (get_map().is_marked(it, oldedges) && - !get_map().is_marked(it, m_mark_perforated)) + get_reduced_map().template mark_cell<2>(it, treated); + if (get_reduced_map().is_marked(it, oldedges) && + !get_reduced_map().is_marked(it, m_mark_perforated)) { - CGAL_assertion(get_map().template beta<1>(it)!=it); - get_map().negate_mark(treated); // To mark new darts treated - get_map().insert_cell_0_in_cell_2(it); - get_map().negate_mark(treated); + CGAL_assertion(get_reduced_map().template beta<1>(it)!=it); + get_reduced_map().negate_mark(treated); // To mark new darts treated + get_reduced_map().insert_cell_0_in_cell_2(it); + get_reduced_map().negate_mark(treated); } } } - CGAL_assertion(get_map().is_whole_map_marked(treated)); - get_map().free_mark(treated); - - /* { - get_map().display_darts(std::cout)<& p=itp->second; - /* std::cout<<"Pair: "<(p.first)!=p.first); - CGAL_assertion(get_map().template beta<1>(p.second)!=p.second); - p.first=get_map().template beta<0, 2>(p.first); - p.second=get_map().template beta<0>(p.second); + CGAL_assertion(!get_reduced_map().is_marked(p.first, m_mark_perforated)); + CGAL_assertion(!get_reduced_map().is_marked(p.second, m_mark_perforated)); + CGAL_assertion(get_reduced_map().template beta<1>(p.first)!=p.first); + CGAL_assertion(get_reduced_map().template beta<1>(p.second)!=p.second); + p.first=get_reduced_map().template beta<0, 2>(p.first); + p.second=get_reduced_map().template beta<0>(p.second); } - else if (!get_map().is_marked(p.first, m_mark_perforated)) + else if (!get_reduced_map().is_marked(p.first, m_mark_perforated)) { // Edge between a real face and a perforated one, not updated during update_length_two_paths_before_edge_removals - CGAL_assertion(get_map().template beta<1>(p.first)!=p.first); - p.second=get_map().template beta<1>(p.first); - p.first=get_map().template beta<0, 2>(p.first); + CGAL_assertion(get_reduced_map().template beta<1>(p.first)!=p.first); + p.second=get_reduced_map().template beta<1>(p.first); + p.first=get_reduced_map().template beta<0, 2>(p.first); } - else if (!get_map().is_marked(get_map().template beta<2>(p.first), + else if (!get_reduced_map().is_marked(get_reduced_map().template beta<2>(p.first), m_mark_perforated)) { // Edge between a perforated face and a real one, not updated during update_length_two_paths_before_edge_removals - CGAL_assertion(get_map().template beta<1>(p.first)!=p.first); - p.second=get_map().template beta<0, 2>(p.first); - p.first=get_map().template beta<1>(p.first); + CGAL_assertion(get_reduced_map().template beta<1>(p.first)!=p.first); + p.second=get_reduced_map().template beta<0, 2>(p.first); + p.first=get_reduced_map().template beta<1>(p.first); } - /* std::cout<<" -> "<(it), m_mark_perforated)) - { get_map().template mark_cell<2>(it, m_mark_perforated); } - get_map().template remove_cell<1>(it); + get_reduced_map().unmark(it, oldedges); + if (get_reduced_map().is_marked + (get_reduced_map().template beta<2>(it), m_mark_perforated)) + { get_reduced_map().template mark_cell<2>(it, m_mark_perforated); } + get_reduced_map().template remove_cell<1>(it); } + else { get_reduced_map().unmark(it, oldedges); } } - /* FOR DEBUG for (typename Reduced_map::Dart_range::iterator - it=get_map().darts().begin(); it!=get_map().darts().end(); - ++it) - { - if (get_map().is_marked(it, m_mark_hole)) - { assert(get_map().template is_whole_cell_marked<2>(it, m_mark_hole)); } - else - { assert(get_map().template is_whole_cell_unmarked<2>(it, m_mark_hole)); } - } */ - - get_map().free_mark(oldedges); - - /* std::cout<<"************ PATH AFTER: "<first) - <<" -> "<second.first) - <<", "; - if (it->second.second==nullptr) { std::cout<<"NULL "<second.second)<<" "<second.first)) - { std::cout<<" DELETE1"; } - if (it->second.second!=nullptr && - !get_map().is_dart_used(it->second.second)) - { std::cout<<" DELETE2"; } - std::cout<(it)==NULL) - { - get_map().template set_attribute<0>(it, get_map().template create_attribute<0>()); - } - } - auto treated=get_map().get_new_mark(); - for (auto it=get_map().darts().begin(), itend=get_map().darts().end(); it!=itend; ++it) - { - if (!get_map().is_marked(it, treated)) + if (get_reduced_map().template attribute<0>(it)==NULL) { + // We count the degree, while testing if there is a perforated face + // incident to the vertex. deg=0; hole_detected=false; dh=it; - // first we compute the degree do { ++deg; - hole_detected=hole_detected || get_map().is_marked(dh, m_mark_perforated); - dh=get_map().template beta<2, 1>(dh); + if (get_reduced_map().is_marked(dh, m_mark_perforated)) + { hole_detected=true; } + dh=get_reduced_map().template beta<2, 1>(dh); } while(dh!=it); - // then we set the vertex attribute to deg id there is a hole and -deg otherwise - do - { - if (hole_detected) - { get_map().template info<0>(dh)=deg; } - else - { get_map().template info<0>(dh)=-deg; } - get_map().mark(dh, treated); - dh=get_map().template beta<2, 1>(dh); - } - while(it!=dh); + // Then we set the vertex attribute to deg id there is a + // hole and -deg otherwise + if (!hole_detected) { deg=-deg; } + + // We create the 0-attribute + get_reduced_map().template set_attribute<0> + (it, get_reduced_map().template create_attribute<0>(deg)); } } - get_map().free_mark(treated); } void initialize_ids() { std::size_t id; Dart_handle dh, ddh; - auto treated=get_map().get_new_mark(); + auto treated=get_reduced_map().get_new_mark(); - for (auto it=get_map().darts().begin(), itend=get_map().darts().end(); - it!=itend; ++it) + for (auto it=get_reduced_map().darts().begin(), + itend=get_reduced_map().darts().end(); it!=itend; ++it) { - if (!get_map().is_marked(it, treated)) + if (!get_reduced_map().is_marked(it, treated)) { id=0; - if (get_map().template info<0>(it)<0) + if (get_reduced_map().template info<0>(it)<0) {// there are no holes around this vertex // we just set the ids from 0 to deg(v)-1 dh=it; do { - #ifdef CGAL_PWRLE_TURN_V2 +#ifdef CGAL_PWRLE_TURN_V2 m_dart_ids[dh]=id; - #else // CGAL_PWRLE_TURN_V2 +#else // CGAL_PWRLE_TURN_V2 // this is for the turn V3 - get_map().info(dh)=id; + get_reduced_map().info(dh)=id; #endif // CGAL_PWRLE_TURN_V2 ++id; - get_map().mark(dh, treated); - dh=get_map().template beta<2, 1>(dh); + get_reduced_map().mark(dh, treated); + dh=get_reduced_map().template beta<2, 1>(dh); } while(dh!=it); } @@ -1405,32 +1103,32 @@ protected: // then we add 1 to the next dart if we dont cross a hole // and we add deg(v)+1 if we cross a hole dh=it; - while(!get_map().is_marked(dh, m_mark_perforated)) + while(!get_reduced_map().is_marked(dh, m_mark_perforated)) { - dh=get_map().template beta<2, 1>(dh); + dh=get_reduced_map().template beta<2, 1>(dh); } // now dh is right after a hole ddh=dh; do { - #ifdef CGAL_PWRLE_TURN_V2 +#ifdef CGAL_PWRLE_TURN_V2 m_dart_ids[ddh]=id; - #else // CGAL_PWRLE_TURN_V2 +#else // CGAL_PWRLE_TURN_V2 // this is for the turn V3 - get_map().info(ddh)=id; + get_reduced_map().info(ddh)=id; #endif // CGAL_PWRLE_TURN_V2 - if (get_map().is_marked(get_map().template beta<2>(ddh), m_mark_perforated)) - { id+=get_map().template info<0>(ddh)+1; } + if (get_reduced_map().is_marked(get_reduced_map().template beta<2>(ddh), m_mark_perforated)) + { id+=get_reduced_map().template info<0>(ddh)+1; } else { id+=1; } - get_map().mark(ddh, treated); - ddh=get_map().template beta<2, 1>(ddh); + get_reduced_map().mark(ddh, treated); + ddh=get_reduced_map().template beta<2, 1>(ddh); } while(ddh!=dh); } } } - get_map().free_mark(treated); + get_reduced_map().free_mark(treated); } std::size_t get_dart_id(Dart_const_handle dh) const @@ -1439,28 +1137,28 @@ protected: return m_dart_ids.at(dh); #else // CGAL_PWRLE_TURN_V2 // this is for the turn V3 - return get_map().info(dh); + return get_reduced_map().info(dh); #endif // CGAL_PWRLE_TURN_V2 std::cerr<<"Error: impossible to get dart id without method V2 or V3."<::max(); } /// @return the positive turn given two darts using their ids (unsed for CGAL_PWRLE_TURN_V2 and V3) std::size_t compute_positive_turn_given_ids(Dart_const_handle dh1, Dart_const_handle dh2) const { - if (get_map().template info<0>(dh1)<0) + if (get_reduced_map().template info<0>(dh1)<0) {// there is no hole around dh1 and dh2 if (get_dart_id(dh1)<=get_dart_id(dh2)) { return get_dart_id(dh2)-get_dart_id(dh1); } // here we have to add the degree (i.e. substract the vertex info) - return get_dart_id(dh2)-get_map().template info<0>(dh1)-get_dart_id(dh1); + return get_dart_id(dh2)-get_reduced_map().template info<0>(dh1)-get_dart_id(dh1); } // here we know there is a hole just before the dart 0 (plus maybe other ones) if (get_dart_id(dh1)>get_dart_id(dh2) || // we crossed dart 0, so we crossed a hole - get_dart_id(dh2)-get_dart_id(dh1)>get_map().template info<0>(dh1)) // the gap is more than the degree, so we crossed a hole + get_dart_id(dh2)-get_dart_id(dh1)>get_reduced_map().template info<0>(dh1)) // the gap is more than the degree, so we crossed a hole {// so we return an "infinite" value return std::numeric_limits::max(); } @@ -1471,18 +1169,18 @@ protected: std::size_t compute_negative_turn_given_ids(Dart_const_handle dh1, Dart_const_handle dh2) const { - if (get_map().template info<0>(dh1)<0) + if (get_reduced_map().template info<0>(dh1)<0) {// there is no hole around dh1 and dh2 if (get_dart_id(dh1)>=get_dart_id(dh2)) { return get_dart_id(dh1)-get_dart_id(dh2); } // here we have to add the degree (i.e. substract the vertex info) - return get_dart_id(dh1)-get_map().template info<0>(dh1)-get_dart_id(dh2); + return get_dart_id(dh1)-get_reduced_map().template info<0>(dh1)-get_dart_id(dh2); } // here we know there is a hole just before the dart 0 (plus maybe other ones) if (get_dart_id(dh1)get_map().template info<0>(dh1)) // the gap is more than the degree, so we crossed a hole + get_dart_id(dh1)-get_dart_id(dh2)>get_reduced_map().template info<0>(dh1)) // the gap is more than the degree, so we crossed a hole {// so we return an "infinite" value return std::numeric_limits::max(); } @@ -1493,36 +1191,37 @@ protected: /// @return true iff the edge containing adart is associated with a path. /// (used for debug purpose because we are suppose to be able to /// test this by using directly the mark m_mark_T). - bool is_edge_has_path(typename Map::Dart_const_handle adart) const + bool is_edge_has_path(Original_dart_const_handle adart) const { - if (m_original_map.template is_free<2>(adart) || - adart(adart)) + if (get_original_map().template is_free<2>(adart) || + adart(adart)) { return m_paths.find(adart)!=m_paths.end(); } - return m_paths.find(m_original_map.template beta<2>(adart))!=m_paths.end(); + return m_paths.find(get_original_map().template beta<2>(adart))!=m_paths.end(); } /// @return true iff the edge containing adart is associated with a path /// of only 1 dart (case of an edge bewteen two perforated faces) - bool edge_path_has_only_one_dart(typename Map::Dart_const_handle adart) const + bool edge_path_has_only_one_dart(Original_dart_const_handle adart) const { return - (m_original_map.is_perforated(adart) && - (m_original_map.template is_free<2>(adart) || - m_original_map.is_perforated(m_original_map.template beta<2>(adart)))); + (get_original_map().is_perforated(adart) && + (get_original_map().template is_free<2>(adart) || + get_original_map().is_perforated + (get_original_map().template beta<2>(adart)))); } /// @return the pair of darts associated with the edge containing adart - /// in m_original_map. + /// in get_original_map(). /// @pre the edge containing adart must not belong to T. std::pair& get_pair_of_darts - (typename Map::Dart_const_handle adart) + (Original_dart_const_handle adart) { CGAL_assertion(!is_contracted(adart)); CGAL_assertion(is_edge_has_path(adart)); - if (m_original_map.template is_free<2>(adart) || - adart(adart)) - return m_paths.find(m_original_map.template beta<2>(adart))->second; + if (get_original_map().template is_free<2>(adart) || + adart(adart)) + return m_paths.find(get_original_map().template beta<2>(adart))->second; } /** @return the first dart of the length 2 path associated with adart. @@ -1533,52 +1232,53 @@ protected: * There is a special case for an edge between two perforated faces. In this * case there is only one dart in the path. */ - Dart_const_handle get_first_dart_of_the_path - (typename Map::Dart_const_handle adart, bool flip=false, - bool isquadrangulation=true) const + Dart_const_handle get_first_dart_of_the_path(Original_dart_const_handle adart, + bool flip=false, + bool isquadrangulation=true) const { CGAL_assertion(is_edge_has_path(adart)); - if (isquadrangulation && m_original_map.is_perforated(adart) && - (m_original_map.template is_free<2>(adart) || - m_original_map.is_perforated(m_original_map.template beta<2>(adart)))) + if (isquadrangulation && get_original_map().is_perforated(adart) && + (get_original_map().template is_free<2>(adart) || + get_original_map().is_perforated + (get_original_map().template beta<2>(adart)))) { - if (m_original_map.template is_free<2>(adart) || - adart(adart)) + if (get_original_map().template is_free<2>(adart) || + adart(adart)) { const std::pair& p=m_paths.find(adart)->second; - return flip?get_map().template beta<2>(p.first):p.first; + return flip?get_reduced_map().template beta<2>(p.first):p.first; } else { const std::pair& - p=m_paths.find(m_original_map.template beta<2>(adart))->second; - return flip?p.first:get_map().template beta<2>(p.first); + p=m_paths.find(get_original_map().template beta<2>(adart))->second; + return flip?p.first:get_reduced_map().template beta<2>(p.first); } } - CGAL_assertion(!m_original_map.is_perforated(adart) || - (!m_original_map.template is_free<2>(adart) && - !m_original_map.is_perforated - (m_original_map.template beta<2>(adart)))); + CGAL_assertion(!get_original_map().is_perforated(adart) || + (!get_original_map().template is_free<2>(adart) && + !get_original_map().is_perforated + (get_original_map().template beta<2>(adart)))); - if (m_original_map.template is_free<2>(adart) || - adart(adart)) + if (get_original_map().template is_free<2>(adart) || + adart(adart)) { const std::pair& p=m_paths.find(adart)->second; return flip? - (isquadrangulation?get_map().template beta<2>(p.second):p.second): + (isquadrangulation?get_reduced_map().template beta<2>(p.second):p.second): p.first; } const std::pair& - p=m_paths.find(m_original_map.template beta<2>(adart))->second; + p=m_paths.find(get_original_map().template beta<2>(adart))->second; return flip? p.first: - (isquadrangulation?get_map().template beta<2>(p.second):p.second); + (isquadrangulation?get_reduced_map().template beta<2>(p.second):p.second); } /** @return the second dart of the length 2 path associated with adart. @@ -1589,91 +1289,90 @@ protected: * @pre edge containing adart should be incident to at least one non * perforated face. */ - Dart_const_handle get_second_dart_of_the_path - (typename Map::Dart_const_handle adart, bool flip=false, - bool isquadrangulation=true) const + Dart_const_handle get_second_dart_of_the_path(Original_dart_const_handle adart, + bool flip=false, + bool isquadrangulation=true) const { CGAL_assertion(is_edge_has_path(adart)); - CGAL_assertion(!m_original_map.is_perforated(adart) || - (!m_original_map.template is_free<2>(adart) && - !m_original_map.is_perforated - (m_original_map.template beta<2>(adart)))); + CGAL_assertion(!get_original_map().is_perforated(adart) || + (!get_original_map().template is_free<2>(adart) && + !get_original_map().is_perforated + (get_original_map().template beta<2>(adart)))); - if (m_original_map.template is_free<2>(adart) || - adart(adart)) + if (get_original_map().template is_free<2>(adart) || + adart(adart)) { const std::pair& p=m_paths.find(adart)->second; return flip? - (isquadrangulation?get_map().template beta<2>(p.first):p.first): + (isquadrangulation?get_reduced_map().template beta<2>(p.first):p.first): p.second; } const std::pair& - p=m_paths.find(m_original_map.template beta<2>(adart))->second; + p=m_paths.find(get_original_map().template beta<2>(adart))->second; return flip? p.second: - (isquadrangulation?get_map().template beta<2>(p.first):p.first); + (isquadrangulation?get_reduced_map().template beta<2>(p.first):p.first); } /// @return the first dart of the path, direct version without taking into /// account possible flip and the two case of torus/quadrangulation. - Dart_handle get_first_dart_of_the_path_direct - (typename Map::Dart_const_handle adart) + Dart_handle get_first_dart_of_the_path_direct(Original_dart_const_handle adart) const { CGAL_assertion(is_edge_has_path(adart)); - if (m_original_map.template is_free<2>(adart) || - adart(adart)) + if (get_original_map().template is_free<2>(adart) || + adart(adart)) { return m_paths.find(adart)->second.first; } - return m_paths.find(m_original_map.template beta<2>(adart))->second.second; + return m_paths.find(get_original_map().template beta<2>(adart))->second.second; } - void set_first_dart_of_the_path(typename Map::Dart_const_handle adart, + void set_first_dart_of_the_path(Original_dart_const_handle adart, Dart_handle d) { CGAL_assertion(is_edge_has_path(adart)); - if (m_original_map.template is_free<2>(adart) || - adart(adart)) + if (get_original_map().template is_free<2>(adart) || + adart(adart)) { m_paths.find(adart)->second.first=d; } else - { m_paths.find(m_original_map.template beta<2>(adart))->second.second=d; } + { m_paths.find(get_original_map().template beta<2>(adart))->second.second=d; } } - void set_second_dart_of_the_path(typename Map::Dart_const_handle adart, - Dart_handle d) + void set_second_dart_of_the_path(Original_dart_const_handle adart, + Dart_handle d) { CGAL_assertion(is_edge_has_path(adart)); - if (m_original_map.template is_free<2>(adart) || - adart(adart)) + if (get_original_map().template is_free<2>(adart) || + adart(adart)) { m_paths.find(adart)->second.second=d; } else { m_paths.find(adart)->second.first=d; } } - bool m_map_is_a_torus_quadrangulation() const + bool reduced_map_is_a_torus() const { - if (get_map().number_of_darts()!=4) + if (get_reduced_map().number_of_darts()!=4) { return false; } - return (get_map().number_of_marked_darts(m_mark_perforated)==0); + return (get_reduced_map().number_of_marked_darts(m_mark_perforated)==0); } /// Test if m_paths are valid, i.e.: - /// 1) all the darts of m_original_map that do not belong to T are + /// 1) all the darts of get_original_map() that do not belong to T are /// associated with a pair of darts; - /// 2) all the darts of m_paths belong to m_map; + /// 2) all the darts of m_paths belong to m_reduced_map; /// 3) the origin of the second dart of the pair is the extremity of the /// first dart. - /// 4) all the darts of m_map are not free (both for beta 1 and 2) + /// 4) all the darts of m_reduced_map are not free (both for beta 1 and 2) /// 5) The two darts in a pair are different bool are_paths_valid() const { if (m_paths.empty()) { return true; } bool res=true; - for (auto it=m_original_map.darts().begin(), - itend=m_original_map.darts().end(); it!=itend; ++it) + for (auto it=get_original_map().darts().begin(), + itend=get_original_map().darts().end(); it!=itend; ++it) { if (!is_contracted(it)) @@ -1683,7 +1382,7 @@ protected: std::cout<<"ERROR: an edge that is not contracted " <<"has no associated path." <<"BTW is_marked(it)=" - <second.first)) + if (!get_reduced_map().is_dart_used(it->second.first)) { - std::cout<<"ERROR: first dart in m_paths does not exist anymore in m_map." + std::cout<<"ERROR: first dart in m_paths does not exist anymore in m_reduced_map." <second.first)) + else if (!get_reduced_map().darts().owns(it->second.first)) { - std::cout<<"ERROR: first dart in m_paths does not belong to m_map." + std::cout<<"ERROR: first dart in m_paths does not belong to m_reduced_map." <first)) { - if (!get_map().is_dart_used(it->second.second)) + if (!get_reduced_map().is_dart_used(it->second.second)) { - std::cout<<"ERROR: second dart in m_paths does not exist anymore in m_map." + std::cout<<"ERROR: second dart in m_paths does not exist anymore in m_reduced_map." <second.second)) + else if (!get_reduced_map().darts().owns(it->second.second)) { - std::cout<<"ERROR: second dart in m_paths does not belong to m_map." + std::cout<<"ERROR: second dart in m_paths does not belong to m_reduced_map." < - (get_map(), dd1, d2)) + (get_reduced_map(), dd1, d2)) { std::cout<<"ERROR: the two darts in a path are not consecutive." <::storage_type m_original_map; // The original map - Reduced_map m_map; /// the transformed map - TPaths m_paths; /// Pair of edges associated with each edge of m_original_map + /// The original map (the mesh seen as a 2-map) + const typename Get_map::storage_type m_original_map; + Reduced_map m_reduced_map; /// the reduced map + TPaths m_paths; /// Pair of edges associated with each edge of get_original_map() /// (except the edges that belong to the spanning tree T). - std::size_t m_mark_T; /// mark each edge of m_original_map that belong to the spanning tree T - std::size_t m_mark_L; /// mark each edge of m_original_map that belong to the dual spanning tree L - std::size_t m_mark_perforated; /// mark each edge of m_map that bounds a hole + std::size_t m_mark_T; /// mark each edge of get_original_map() that belong to the spanning tree T + std::size_t m_mark_L; /// mark each edge of get_original_map() that belong to the dual spanning tree L + std::size_t m_mark_perforated; /// mark each edge of m_reduced_map that bounds a hole #ifdef CGAL_PWRLE_TURN_V2 TDartIds m_dart_ids; /// Ids of each dart of the transformed map, between 0 and n-1 (n being the number of darts) diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_generators.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_generators.h index 25f41593a45..0db5bd6cbe3 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_generators.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_generators.h @@ -149,7 +149,7 @@ generate_random_connected_set_of_faces(const LCC& lcc, std::size_t nb, // Here we have a new face set.insert(lcc.template beta<2>(dh1)); - lcc.mark_cell<2>(lcc.template beta<2>(dh1), amark); + lcc.template mark_cell<2>(lcc.template beta<2>(dh1), amark); // We add it in the list of borders faces border_faces[border_faces.size()]=lcc.template beta<2>(dh1); diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h index 5c6a67b95f9..f89df6bdb6a 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h @@ -30,8 +30,8 @@ #include #include #include -#include -#include +#include +#include namespace CGAL { namespace Surface_mesh_topology { @@ -80,18 +80,18 @@ public: // Small wrapper allowing to use directly a combinatorial map as if it is a // minimal quadrangulation. -template +template class Light_MQ // MQ for minimal quadrangulation { public: - typedef Map__ Map_; + typedef Map_ Reduced_map; typedef Map_ Mesh; typedef typename Map_::Dart_const_handle Dart_const_handle; - Light_MQ(const Map_& m): m_map(m) + Light_MQ(const Reduced_map& m): m_map(m) {} - const Map_& get_map() const + const Reduced_map& get_reduced_map() const { return m_map; } std::size_t positive_turn(Dart_const_handle d1, Dart_const_handle d2) const @@ -101,7 +101,7 @@ public: { return m_map.negative_turn(d1, d2); } protected: - const Map_& m_map; + const Reduced_map& m_map; }; template // MQ for minimal quadrangulation @@ -109,7 +109,7 @@ class Path_on_surface_with_rle { public: typedef Path_on_surface_with_rle Self; - typedef typename MQ::Map_ Map; + typedef typename MQ::Reduced_map Map; typedef typename MQ::Mesh Mesh; typedef typename Map::Dart_handle Dart_handle; typedef typename Map::Dart_const_handle Dart_const_handle; @@ -124,14 +124,14 @@ public: { std::size_t operator() (const List_iterator& lit) const { - return boost::hash()(&*lit); + return std::hash()(&*lit); } }; - typedef boost::unordered_set Set_of_it; + typedef std::unordered_set Set_of_it; #ifdef CGAL_PWRLE_TURN_V2 - typedef boost::unordered_map TDartIds; + typedef std::unordered_map TDartIds; #endif //CGAL_PWRLE_TURN_V2 /// Constructor @@ -307,7 +307,7 @@ public: /// @return the underlying map. const Map& get_map() const - { return m_MQ.get_map(); } + { return m_MQ.get_reduced_map(); } /// clear the path. void clear()