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_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/draw_linear_cell_complex.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_container = std::vector<Dart_handle>;
using Point = LCC_3::Point;
using Path_on_surface = CGAL::Surface_mesh_topology::Path_on_surface<LCC_3>;
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<LCC_3, Weight_functor>;
using CST = CGAL::Surface_mesh_topology::Curves_on_surface_topology<LCC_3>;
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);
}
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 << " 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/Surface_mesh_topology/internal/Minimal_quadrangulation.h>
#include <CGAL/Surface_mesh_topology/internal/Shortest_noncontractible_cycle.h>
#include <CGAL/Face_graph_wrapper.h>
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<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_minimal_quadrangulation(nullptr)
m_minimal_quadrangulation(nullptr),
m_shortest_noncontractible_cycle(nullptr)
{}
~Curves_on_surface_topology()
@ -95,9 +98,19 @@ public:
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:
const Mesh& m_original_map;
Mesh& m_original_map;
mutable internal::Minimal_quadrangulation<Mesh>* m_minimal_quadrangulation;
mutable Shortest_noncontractible_cycle* m_shortest_noncontractible_cycle;
};
} // namespace Surface_mesh_topology

View File

@ -54,6 +54,7 @@ public:
Path_on_surface(const internal::Path_on_surface_with_rle<Mesh>& 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<bool>& get_flip() const
{ return m_flip; }
/// clear the path.
void clear()
{

View File

@ -10,6 +10,7 @@
namespace CGAL {
namespace Surface_mesh_topology {
namespace internal {
template <class Mesh_>
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<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)
{
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 <class WeightFunctor>
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