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 0d88dc44202..6973fbd2a8c 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 @@ -1,6 +1,7 @@ #include #include -#include +#include +#include #include #include #include @@ -15,6 +16,7 @@ using Dart_handle = LCC_3::Dart_handle; using Dart_const_handle = LCC_3::Dart_const_handle; using Dart_container = std::vector; using Point = LCC_3::Point; +using Path_on_surface = CGAL::Surface_mesh_topology::Path_on_surface; struct Weight_functor { Weight_functor(const LCC_3& lcc) : m_lcc(lcc) { } @@ -28,7 +30,7 @@ private: const LCC_3& m_lcc; }; -using SNC = CGAL::Surface_mesh_topology::Shortest_noncontractible_cycle; +using CST = CGAL::Surface_mesh_topology::Curves_on_surface_topology; struct Draw_functor : public CGAL::DefaultDrawingFunctorLCC { Draw_functor(LCC_3::size_type am1, LCC_3::size_type am2) : is_root(am1), @@ -84,45 +86,40 @@ int main(int argc, char* argv[]) { for (int loop = 1; ; ++loop) { std::cout << "Finding #" << loop << " edge-width:\n"; Weight_functor wf(lcccopy); - SNC snc(lcccopy, wf); - SNC::Path cycle; - SNC::Distance_type x; - snc.edge_width(cycle, &x); - if (cycle.size() == 0) { + CST cst(lcccopy); + Path_on_surface cycle = cst.compute_edgewidth(wf); + if (cycle.length() == 0) { std::cout << " Cannot find edge-width. Stop.\n"; break; } - for (LCC_3::Dart_of_cell_range<0>::iterator it=lcccopy.darts_of_cell<0>(cycle[0]).begin(), - itend=lcccopy.darts_of_cell<0>(cycle[0]).end(); it!=itend; ++it) - { - if (copy_to_origin.count(it)>0 && - !lccoriginal.is_marked(copy_to_origin[it], is_root)) - { - lccoriginal.mark_cell<0>(copy_to_origin[it], is_root); - break; - } + LCC_3::size_type is_root_copy = lcccopy.get_new_mark(); + LCC_3::size_type belong_to_cycle_copy = lcccopy.get_new_mark(); + + lcccopy.mark_cell<0>(cycle[0], is_root_copy); + double x = 0; + for (int i = 0; i < cycle.length(); ++i) { + x += wf(cycle[i]); + if (!lcccopy.is_marked(cycle[i], belong_to_cycle_copy)) + lcccopy.mark_cell<1>(cycle[i], belong_to_cycle_copy); } - - for (auto e : cycle) - { - for (auto it=lcccopy.darts_of_cell<1>(e).begin(), - itend=lcccopy.darts_of_cell<1>(e).end(); it!=itend; ++it) - { - if (copy_to_origin.count(it)>0 && - !lccoriginal.is_marked(copy_to_origin[it], belong_to_cycle)) - { - lccoriginal.mark_cell<1>(copy_to_origin[it], belong_to_cycle); - break; - } - } - if (!lcccopy.is_free<2>(e)) - { lcccopy.unsew<2>(e); } + + for (auto dh = lcccopy.darts().begin(), dhend = lcccopy.darts().end(); dh != dhend; ++dh) { + if (lcccopy.is_marked(dh, is_root_copy) && !lccoriginal.is_marked(copy_to_origin[dh], is_root)) + lccoriginal.mark(copy_to_origin[dh], is_root); + if (lcccopy.is_marked(dh, belong_to_cycle_copy) && !lccoriginal.is_marked(copy_to_origin[dh], belong_to_cycle)) + lccoriginal.mark(copy_to_origin[dh], belong_to_cycle); + if (lcccopy.is_marked(dh, belong_to_cycle_copy) && !lcccopy.is_free<2>(dh)) + lcccopy.unsew<2>(dh); } + + lcccopy.free_mark(belong_to_cycle_copy); + lcccopy.free_mark(is_root_copy); - std::cout << " Number of edges in cycle: " << cycle.size() << std::endl; + std::cout << " Number of edges in cycle: " << cycle.length() << std::endl; std::cout << " Cycle length: " << x << std::endl; std::cout << " Root: " << lcccopy.point_of_vertex_attribute(lcccopy.vertex_attribute(cycle[0])) << std::endl; + } 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 b9fa07ac91a..051422bdd31 100644 --- a/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h +++ b/Surface_mesh_topology/include/CGAL/Curves_on_surface_topology.h @@ -24,6 +24,7 @@ #include #include +#include #include namespace CGAL { @@ -34,10 +35,12 @@ class Curves_on_surface_topology { public: typedef typename internal::CMap_for_minimal_quadrangulation CMap_for_minimal_quadrangulation; + typedef typename internal::Shortest_noncontractible_cycle Shortest_noncontractible_cycle; - Curves_on_surface_topology(const Mesh& amap, bool /* display_time */=false) : + Curves_on_surface_topology(Mesh& amap, bool /* display_time */=false) : m_original_map(amap), - m_minimal_quadrangulation(nullptr) + m_minimal_quadrangulation(nullptr), + m_shortest_noncontractible_cycle(nullptr) {} ~Curves_on_surface_topology() @@ -93,11 +96,21 @@ public: { CGAL_assertion(is_minimal_quadrangulation_computed()); return m_minimal_quadrangulation->get_map(); - } + } + + template + Path_on_surface compute_edgewidth(const WeightFunctor& wf) const + { + if (m_shortest_noncontractible_cycle==nullptr) + { m_shortest_noncontractible_cycle = new Shortest_noncontractible_cycle(m_original_map); } + + return m_shortest_noncontractible_cycle->compute_edgewidth(NULL, wf); + } protected: - const Mesh& m_original_map; + Mesh& m_original_map; mutable internal::Minimal_quadrangulation* m_minimal_quadrangulation; + mutable Shortest_noncontractible_cycle* m_shortest_noncontractible_cycle; }; } // namespace Surface_mesh_topology diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index 6eedb8d0deb..bee6fd8c27a 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -54,6 +54,7 @@ public: Path_on_surface(const internal::Path_on_surface_with_rle& apath) : m_map(apath.get_map()), + m_flip(apath.get_flip()), m_is_closed(apath.is_closed()) { for (auto it=apath.m_path.begin(), itend=apath.m_path.end(); it!=itend; ++it) @@ -104,6 +105,9 @@ public: const Map& get_map() const { return m_map; } + const std::vector& get_flip() const + { return m_flip; } + /// clear the path. void clear() { diff --git a/Surface_mesh_topology/include/CGAL/Shortest_noncontractible_cycle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Shortest_noncontractible_cycle.h similarity index 98% rename from Surface_mesh_topology/include/CGAL/Shortest_noncontractible_cycle.h rename to Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Shortest_noncontractible_cycle.h index fecda1d11d6..b3e804949f9 100644 --- a/Surface_mesh_topology/include/CGAL/Shortest_noncontractible_cycle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Shortest_noncontractible_cycle.h @@ -10,6 +10,7 @@ namespace CGAL { namespace Surface_mesh_topology { +namespace internal { template class Shortest_noncontractible_cycle { @@ -115,13 +116,13 @@ public: using Attribute_handle_0 = typename Gmap::template Attribute_handle<0>::type; using size_type = typename Gmap::size_type; using Dart_container = std::vector; - using Path = Path_on_surface; + using Path = CGAL::Surface_mesh_topology::Path_on_surface; Shortest_noncontractible_cycle(Mesh_original& gmap) : m_cycle(gmap) { - Gmap_wrapper::copy(m_gmap, gmap, m_origin_to_copy, m_copy_to_origin); // m_gmap.display_characteristics(std::cerr); // std::cerr << '\n'; + Gmap_wrapper::copy(m_gmap, gmap, m_origin_to_copy, m_copy_to_origin); // Initialize m_is_hole m_is_hole = m_gmap.get_new_mark(); for (auto it = m_gmap.darts().begin(), itend = m_gmap.darts().end(); it != itend; ++it) { @@ -162,13 +163,14 @@ public: } template - Path edge_width(typename WeightFunctor::Weight_t* length = NULL, - const WeightFunctor& wf = Default_weight_functor()) + Path compute_edgewidth(typename WeightFunctor::Weight_t* length = NULL, + const WeightFunctor& wf = Default_weight_functor()) { m_cycle.clear(); bool first_check = true; typename WeightFunctor::Weight_t min_length = 0; for (Attribute_handle_0 att_it = m_gmap.template attributes<0>().begin(), att_itend = m_gmap.template attributes<0>().end(); att_it != att_itend; ++att_it) { + // std::cerr << '.'; Dart_handle it = att_it->dart(); typename WeightFunctor::Weight_t temp_length; if (first_check) { @@ -181,6 +183,7 @@ public: } } if (length != NULL) *length = min_length; + // std::cerr << "====\n"; return m_cycle; } @@ -480,6 +483,7 @@ private: Path m_cycle; }; +} // namespace internal } // namespace Surface_mesh_topology } // namespace CGAL