Create compute_edgewidth in CST and modify an example

This commit is contained in:
Thien Hoang 2019-07-28 23:12:24 +07:00
parent 07dde8e9aa
commit fad13bb4ee
4 changed files with 58 additions and 40 deletions

View File

@ -1,6 +1,7 @@
#include <CGAL/Linear_cell_complex_for_generalized_map.h> #include <CGAL/Linear_cell_complex_for_generalized_map.h>
#include <CGAL/Linear_cell_complex_constructors.h> #include <CGAL/Linear_cell_complex_constructors.h>
#include <CGAL/Shortest_noncontractible_cycle.h> #include <CGAL/Curves_on_surface_topology.h>
#include <CGAL/Path_on_surface.h>
#include <CGAL/IO/Color.h> #include <CGAL/IO/Color.h>
#include <CGAL/draw_linear_cell_complex.h> #include <CGAL/draw_linear_cell_complex.h>
#include <CGAL/squared_distance_3.h> #include <CGAL/squared_distance_3.h>
@ -15,6 +16,7 @@ using Dart_handle = LCC_3::Dart_handle;
using Dart_const_handle = LCC_3::Dart_const_handle; using Dart_const_handle = LCC_3::Dart_const_handle;
using Dart_container = std::vector<Dart_handle>; using Dart_container = std::vector<Dart_handle>;
using Point = LCC_3::Point; using Point = LCC_3::Point;
using Path_on_surface = CGAL::Surface_mesh_topology::Path_on_surface<LCC_3>;
struct Weight_functor { struct Weight_functor {
Weight_functor(const LCC_3& lcc) : m_lcc(lcc) { } Weight_functor(const LCC_3& lcc) : m_lcc(lcc) { }
@ -28,7 +30,7 @@ private:
const LCC_3& m_lcc; const LCC_3& m_lcc;
}; };
using SNC = CGAL::Surface_mesh_topology::Shortest_noncontractible_cycle<LCC_3, Weight_functor>; using CST = CGAL::Surface_mesh_topology::Curves_on_surface_topology<LCC_3>;
struct Draw_functor : public CGAL::DefaultDrawingFunctorLCC { struct Draw_functor : public CGAL::DefaultDrawingFunctorLCC {
Draw_functor(LCC_3::size_type am1, LCC_3::size_type am2) : is_root(am1), 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) { for (int loop = 1; ; ++loop) {
std::cout << "Finding #" << loop << " edge-width:\n"; std::cout << "Finding #" << loop << " edge-width:\n";
Weight_functor wf(lcccopy); Weight_functor wf(lcccopy);
SNC snc(lcccopy, wf); CST cst(lcccopy);
SNC::Path cycle; Path_on_surface cycle = cst.compute_edgewidth(wf);
SNC::Distance_type x; if (cycle.length() == 0) {
snc.edge_width(cycle, &x);
if (cycle.size() == 0) {
std::cout << " Cannot find edge-width. Stop.\n"; std::cout << " Cannot find edge-width. Stop.\n";
break; break;
} }
for (LCC_3::Dart_of_cell_range<0>::iterator it=lcccopy.darts_of_cell<0>(cycle[0]).begin(), LCC_3::size_type is_root_copy = lcccopy.get_new_mark();
itend=lcccopy.darts_of_cell<0>(cycle[0]).end(); it!=itend; ++it) LCC_3::size_type belong_to_cycle_copy = lcccopy.get_new_mark();
{
if (copy_to_origin.count(it)>0 && lcccopy.mark_cell<0>(cycle[0], is_root_copy);
!lccoriginal.is_marked(copy_to_origin[it], is_root)) double x = 0;
{ for (int i = 0; i < cycle.length(); ++i) {
lccoriginal.mark_cell<0>(copy_to_origin[it], is_root); x += wf(cycle[i]);
break; 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 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))
for (auto it=lcccopy.darts_of_cell<1>(e).begin(), lccoriginal.mark(copy_to_origin[dh], is_root);
itend=lcccopy.darts_of_cell<1>(e).end(); it!=itend; ++it) 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 (copy_to_origin.count(it)>0 && if (lcccopy.is_marked(dh, belong_to_cycle_copy) && !lcccopy.is_free<2>(dh))
!lccoriginal.is_marked(copy_to_origin[it], belong_to_cycle)) lcccopy.unsew<2>(dh);
{
lccoriginal.mark_cell<1>(copy_to_origin[it], belong_to_cycle);
break;
}
}
if (!lcccopy.is_free<2>(e))
{ lcccopy.unsew<2>(e); }
} }
std::cout << " Number of edges in cycle: " << cycle.size() << std::endl; lcccopy.free_mark(belong_to_cycle_copy);
lcccopy.free_mark(is_root_copy);
std::cout << " Number of edges in cycle: " << cycle.length() << std::endl;
std::cout << " Cycle length: " << x << std::endl; std::cout << " Cycle length: " << x << std::endl;
std::cout << " Root: " << lcccopy.point_of_vertex_attribute(lcccopy.vertex_attribute(cycle[0])) << std::endl; std::cout << " Root: " << lcccopy.point_of_vertex_attribute(lcccopy.vertex_attribute(cycle[0])) << std::endl;
} }

View File

@ -24,6 +24,7 @@
#include <CGAL/license/Surface_mesh_topology.h> #include <CGAL/license/Surface_mesh_topology.h>
#include <CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h> #include <CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h>
#include <CGAL/Surface_mesh_topology/internal/Shortest_noncontractible_cycle.h>
#include <CGAL/Face_graph_wrapper.h> #include <CGAL/Face_graph_wrapper.h>
namespace CGAL { namespace CGAL {
@ -34,10 +35,12 @@ class Curves_on_surface_topology
{ {
public: public:
typedef typename internal::CMap_for_minimal_quadrangulation CMap_for_minimal_quadrangulation; typedef typename internal::CMap_for_minimal_quadrangulation CMap_for_minimal_quadrangulation;
typedef typename internal::Shortest_noncontractible_cycle<Mesh> 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_original_map(amap),
m_minimal_quadrangulation(nullptr) m_minimal_quadrangulation(nullptr),
m_shortest_noncontractible_cycle(nullptr)
{} {}
~Curves_on_surface_topology() ~Curves_on_surface_topology()
@ -95,9 +98,19 @@ public:
return m_minimal_quadrangulation->get_map(); return m_minimal_quadrangulation->get_map();
} }
template <class WeightFunctor>
Path_on_surface<Mesh> 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: protected:
const Mesh& m_original_map; Mesh& m_original_map;
mutable internal::Minimal_quadrangulation<Mesh>* m_minimal_quadrangulation; mutable internal::Minimal_quadrangulation<Mesh>* m_minimal_quadrangulation;
mutable Shortest_noncontractible_cycle* m_shortest_noncontractible_cycle;
}; };
} // namespace Surface_mesh_topology } // namespace Surface_mesh_topology

View File

@ -54,6 +54,7 @@ public:
Path_on_surface(const internal::Path_on_surface_with_rle<Mesh>& apath) : Path_on_surface(const internal::Path_on_surface_with_rle<Mesh>& apath) :
m_map(apath.get_map()), m_map(apath.get_map()),
m_flip(apath.get_flip()),
m_is_closed(apath.is_closed()) m_is_closed(apath.is_closed())
{ {
for (auto it=apath.m_path.begin(), itend=apath.m_path.end(); it!=itend; ++it) 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 const Map& get_map() const
{ return m_map; } { return m_map; }
const std::vector<bool>& get_flip() const
{ return m_flip; }
/// clear the path. /// clear the path.
void clear() void clear()
{ {

View File

@ -10,6 +10,7 @@
namespace CGAL { namespace CGAL {
namespace Surface_mesh_topology { namespace Surface_mesh_topology {
namespace internal {
template <class Mesh_> template <class Mesh_>
class Shortest_noncontractible_cycle { class Shortest_noncontractible_cycle {
@ -115,13 +116,13 @@ public:
using Attribute_handle_0 = typename Gmap::template Attribute_handle<0>::type; using Attribute_handle_0 = typename Gmap::template Attribute_handle<0>::type;
using size_type = typename Gmap::size_type; using size_type = typename Gmap::size_type;
using Dart_container = std::vector<Dart_handle>; using Dart_container = std::vector<Dart_handle>;
using Path = Path_on_surface<Mesh_original>; using Path = CGAL::Surface_mesh_topology::Path_on_surface<Mesh_original>;
Shortest_noncontractible_cycle(Mesh_original& gmap) : m_cycle(gmap) 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); // m_gmap.display_characteristics(std::cerr);
// std::cerr << '\n'; // std::cerr << '\n';
Gmap_wrapper::copy(m_gmap, gmap, m_origin_to_copy, m_copy_to_origin);
// Initialize m_is_hole // Initialize m_is_hole
m_is_hole = m_gmap.get_new_mark(); m_is_hole = m_gmap.get_new_mark();
for (auto it = m_gmap.darts().begin(), itend = m_gmap.darts().end(); it != itend; ++it) { for (auto it = m_gmap.darts().begin(), itend = m_gmap.darts().end(); it != itend; ++it) {
@ -162,13 +163,14 @@ public:
} }
template <class WeightFunctor> template <class WeightFunctor>
Path edge_width(typename WeightFunctor::Weight_t* length = NULL, Path compute_edgewidth(typename WeightFunctor::Weight_t* length = NULL,
const WeightFunctor& wf = Default_weight_functor()) const WeightFunctor& wf = Default_weight_functor())
{ {
m_cycle.clear(); m_cycle.clear();
bool first_check = true; bool first_check = true;
typename WeightFunctor::Weight_t min_length = 0; 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) { 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(); Dart_handle it = att_it->dart();
typename WeightFunctor::Weight_t temp_length; typename WeightFunctor::Weight_t temp_length;
if (first_check) { if (first_check) {
@ -181,6 +183,7 @@ public:
} }
} }
if (length != NULL) *length = min_length; if (length != NULL) *length = min_length;
// std::cerr << "====\n";
return m_cycle; return m_cycle;
} }
@ -480,6 +483,7 @@ private:
Path m_cycle; Path m_cycle;
}; };
} // namespace internal
} // namespace Surface_mesh_topology } // namespace Surface_mesh_topology
} // namespace CGAL } // namespace CGAL