Add comments; cut line > 80 car; some cleanup.

This commit is contained in:
Guillaume Damiand 2019-11-22 09:59:55 +01:00
parent 8d976c2192
commit a11e377561
2 changed files with 156 additions and 112 deletions

View File

@ -75,8 +75,9 @@ namespace CGAL
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/** Class Face_graph_wrapper: to wrap any model of FaceGraph into a Combinatorial map. /** Class Face_graph_wrapper: to wrap any model of FaceGraph into a
* For now, only for const models, i.e. does not support modification operators. * Combinatorial map. For now, only for const models, i.e. does not support
* modification operators.
*/ */
template<typename HEG_> template<typename HEG_>
class Face_graph_wrapper class Face_graph_wrapper
@ -139,7 +140,8 @@ public:
mnb_times_reserved_marks[i]=0; mnb_times_reserved_marks[i]=0;
} }
m_nb_darts=darts().size(); // Store locally the number of darts: the HEG must not be modified // Store locally the number of darts: the HEG must not be modified
m_nb_darts=darts().size();
m_all_marks=get(CGAL::dynamic_halfedge_property_t<std::bitset<NB_MARKS> >(), m_fg); m_all_marks=get(CGAL::dynamic_halfedge_property_t<std::bitset<NB_MARKS> >(), m_fg);
for (typename Dart_range::const_iterator it(darts().begin()), for (typename Dart_range::const_iterator it(darts().begin()),
@ -151,20 +153,17 @@ public:
{ return m_fg; } { return m_fg; }
template<unsigned int i> template<unsigned int i>
bool is_free(Dart_const_handle dh) const bool is_free(Dart_const_handle /* dh */) const
{ return false; } // Not possible to have a free dart with an HEG. { return false; } // Not possible to have a free dart with an HEG.
//return Is_free<HEG, i>::value(m_fg, dh); }
bool is_free(Dart_const_handle dh, unsigned int i) const bool is_free(Dart_const_handle dh, unsigned int i) const
{ { return false; } // Not possible to have a free dart with an HEG.
// if (i==2) { return Is_free<HEG, 2>::value(m_fg, dh); }
return false; // Not possible to have a free dart with an HEG.
}
bool is_perforated(Dart_const_handle dh) const bool is_perforated(Dart_const_handle dh) const
{ return is_border(dh, m_fg); } { return is_border(dh, m_fg); }
Dart_const_handle get_beta(Dart_const_handle ADart, int B1) const Dart_const_handle get_beta(Dart_const_handle ADart, int B1) const
{ {
CGAL_assertion(B1>=0 && B1<=(int)dimension); CGAL_assertion(B1>=0 && B1<=static_cast<int>(dimension));
if (B1==1) return Get_beta<HEG, 1>::value(m_fg, ADart); if (B1==1) return Get_beta<HEG, 1>::value(m_fg, ADart);
if (B1==2) return Get_beta<HEG, 2>::value(m_fg, ADart); if (B1==2) return Get_beta<HEG, 2>::value(m_fg, ADart);
return Get_beta<HEG, 0>::value(m_fg, ADart); return Get_beta<HEG, 0>::value(m_fg, ADart);
@ -172,7 +171,7 @@ public:
template<int B1> template<int B1>
Dart_const_handle get_beta(Dart_const_handle ADart) const Dart_const_handle get_beta(Dart_const_handle ADart) const
{ {
CGAL_assertion(B1>=0 && B1<=(int)dimension); CGAL_assertion(B1>=0 && B1<=static_cast<int>(dimension));
return Get_beta<HEG, B1>::value(m_fg, ADart); return Get_beta<HEG, B1>::value(m_fg, ADart);
} }
@ -182,8 +181,8 @@ public:
/* ?? bool is_dart_used(Dart_const_handle dh) const /* ?? bool is_dart_used(Dart_const_handle dh) const
{ return true; ?? } */ { return true; ?? } */
int highest_nonfree_dimension(Dart_const_handle dh) const int highest_nonfree_dimension(Dart_const_handle /* dh */) const
{ return 2; } //(Is_free<HEG, 2>(m_fg, dh)?1:2); } { return 2; }
Dart_const_handle previous(Dart_const_handle ADart) const Dart_const_handle previous(Dart_const_handle ADart) const
{ return get_beta<0>(ADart); } { return get_beta<0>(ADart); }
@ -207,8 +206,8 @@ public:
bool is_next_exist(Dart_const_handle) const bool is_next_exist(Dart_const_handle) const
{ return true; } { return true; }
template<unsigned int dim> template<unsigned int dim>
bool is_opposite_exist(Dart_const_handle ADart) const bool is_opposite_exist(Dart_const_handle /* ADart */) const
{ return true; } // !this->template is_free<dim>(ADart); } { return true; }
template<typename ...Betas> template<typename ...Betas>
Dart_handle beta(Dart_handle ADart, Betas... betas) Dart_handle beta(Dart_handle ADart, Betas... betas)
@ -775,7 +774,7 @@ protected:
template<class Base, class HEG> template<class Base, class HEG>
struct Get_map struct Get_map
{ {
typedef Face_graph_wrapper<HEG> type; typedef Face_graph_wrapper<HEG> type;
typedef const Face_graph_wrapper<HEG> storage_type; typedef const Face_graph_wrapper<HEG> storage_type;
Get_map(const HEG& heg): m_map(heg) {} Get_map(const HEG& heg): m_map(heg) {}
static const HEG& get_mesh(const storage_type& amap) static const HEG& get_mesh(const storage_type& amap)
@ -788,10 +787,10 @@ protected:
typename Storage, class Map> typename Storage, class Map>
struct Get_map<CGAL::Combinatorial_map_base<d, Refs, Items, Alloc, Storage>, Map> struct Get_map<CGAL::Combinatorial_map_base<d, Refs, Items, Alloc, Storage>, Map>
{ {
typedef Map type; typedef Map type;
typedef const Map& storage_type; typedef const Map& storage_type;
Get_map(const Map& heg): m_map(heg) {} Get_map(const Map& heg): m_map(heg) {}
static const Map& get_mesh(const storage_type& amap) static const Map& get_mesh(storage_type& amap)
{ return amap; } { return amap; }
storage_type m_map; storage_type m_map;
}; };
@ -800,10 +799,10 @@ protected:
typename Storage, class Map> typename Storage, class Map>
struct Get_map<CGAL::Generalized_map_base<d, Refs, Items, Alloc, Storage>, Map> struct Get_map<CGAL::Generalized_map_base<d, Refs, Items, Alloc, Storage>, Map>
{ {
typedef Map type; typedef Map type;
typedef const Map& storage_type; typedef const Map& storage_type;
Get_map(const Map& heg): m_map(heg) {} Get_map(const Map& heg): m_map(heg) {}
static const Map& get_mesh(const storage_type& amap) static const Map& get_mesh(storage_type& amap)
{ return amap; } { return amap; }
storage_type m_map; storage_type m_map;
}; };
@ -812,12 +811,13 @@ protected:
typename Alloc, typename Alloc,
template<unsigned int,class,class,class,class> template<unsigned int,class,class,class,class>
class Map, typename Refs, typename Storage, class LCC> class Map, typename Refs, typename Storage, class LCC>
struct Get_map<CGAL::Linear_cell_complex_base<d, d2, Traits, Items, Alloc, Map, Refs, Storage>, LCC> struct Get_map<CGAL::Linear_cell_complex_base<d, d2, Traits, Items, Alloc,
Map, Refs, Storage>, LCC>
{ {
typedef LCC type; typedef LCC type;
typedef const LCC& storage_type; typedef const LCC& storage_type;
Get_map(const LCC& heg): m_map(heg) {} Get_map(const LCC& heg): m_map(heg) {}
static const LCC& get_mesh(const storage_type& amap) static const LCC& get_mesh(storage_type& amap)
{ return amap; } { return amap; }
storage_type m_map; storage_type m_map;
}; };
@ -826,10 +826,10 @@ protected:
typename Storage, class Map> typename Storage, class Map>
struct Get_map<CGAL::Combinatorial_map<d, Items, Alloc, Storage>, Map> struct Get_map<CGAL::Combinatorial_map<d, Items, Alloc, Storage>, Map>
{ {
typedef Map type; typedef Map type;
typedef const Map& storage_type; typedef const Map& storage_type;
Get_map(const Map& heg): m_map(heg) {} Get_map(const Map& heg): m_map(heg) {}
static const Map& get_mesh(const storage_type& amap) static const Map& get_mesh(storage_type& amap)
{ return amap; } { return amap; }
storage_type m_map; storage_type m_map;
}; };
@ -838,10 +838,10 @@ protected:
struct Get_map<CGAL::Surface_mesh_topology:: struct Get_map<CGAL::Surface_mesh_topology::
Polygonal_schema_with_combinatorial_map<Items, Alloc, Storage>, Map> Polygonal_schema_with_combinatorial_map<Items, Alloc, Storage>, Map>
{ {
typedef Map type; typedef Map type;
typedef const Map& storage_type; typedef const Map& storage_type;
Get_map(const Map& heg): m_map(heg) {} Get_map(const Map& heg): m_map(heg) {}
static const Map& get_mesh(const storage_type& amap) static const Map& get_mesh(storage_type& amap)
{ return amap; } { return amap; }
storage_type m_map; storage_type m_map;
}; };
@ -850,10 +850,10 @@ protected:
typename Storage, class Map> typename Storage, class Map>
struct Get_map<CGAL::Generalized_map<d, Items, Alloc, Storage>, Map> struct Get_map<CGAL::Generalized_map<d, Items, Alloc, Storage>, Map>
{ {
typedef Map type; typedef Map type;
typedef const Map& storage_type; typedef const Map& storage_type;
Get_map(const Map& heg): m_map(heg) {} Get_map(const Map& heg): m_map(heg) {}
static const Map& get_mesh(const storage_type& amap) static const Map& get_mesh(storage_type& amap)
{ return amap; } { return amap; }
storage_type m_map; storage_type m_map;
}; };
@ -862,10 +862,10 @@ protected:
struct Get_map<CGAL::Surface_mesh_topology:: struct Get_map<CGAL::Surface_mesh_topology::
Polygonal_schema_with_generalized_map<Items, Alloc, Storage>, Map> Polygonal_schema_with_generalized_map<Items, Alloc, Storage>, Map>
{ {
typedef Map type; typedef Map type;
typedef const Map& storage_type; typedef const Map& storage_type;
Get_map(const Map& heg): m_map(heg) {} Get_map(const Map& heg): m_map(heg) {}
static const Map& get_mesh(const storage_type& amap) static const Map& get_mesh(storage_type& amap)
{ return amap; } { return amap; }
storage_type m_map; storage_type m_map;
}; };
@ -877,10 +877,10 @@ protected:
struct Get_map<CGAL::Linear_cell_complex_for_combinatorial_map struct Get_map<CGAL::Linear_cell_complex_for_combinatorial_map
<d, d2, Traits, Items, Alloc, Map, Storage>, LCC> <d, d2, Traits, Items, Alloc, Map, Storage>, LCC>
{ {
typedef LCC type; typedef LCC type;
typedef const LCC& storage_type; typedef const LCC& storage_type;
Get_map(const LCC& heg): m_map(heg) {} Get_map(const LCC& heg): m_map(heg) {}
static const LCC& get_mesh(const storage_type& amap) static const LCC& get_mesh(storage_type& amap)
{ return amap; } { return amap; }
storage_type m_map; storage_type m_map;
}; };
@ -892,10 +892,10 @@ protected:
struct Get_map<CGAL::Linear_cell_complex_for_generalized_map struct Get_map<CGAL::Linear_cell_complex_for_generalized_map
<d, d2, Traits, Items, Alloc, Map, Storage>, LCC> <d, d2, Traits, Items, Alloc, Map, Storage>, LCC>
{ {
typedef LCC type; typedef LCC type;
typedef const LCC& storage_type; typedef const LCC& storage_type;
Get_map(const LCC& heg): m_map(heg) {} Get_map(const LCC& heg): m_map(heg) {}
static const LCC& get_mesh(const storage_type& amap) static const LCC& get_mesh(storage_type& amap)
{ return amap; } { return amap; }
storage_type m_map; storage_type m_map;
}; };
@ -903,9 +903,9 @@ protected:
template<class Mesh_> template<class Mesh_>
struct Get_traits struct Get_traits
{ {
typedef Mesh_ Mesh; typedef Mesh_ Mesh;
typedef typename Mesh::Traits Kernel; typedef typename Mesh::Traits Kernel;
typedef typename Mesh::Point Point; typedef typename Mesh::Point Point;
typedef typename Mesh::Vector Vector; typedef typename Mesh::Vector Vector;
template<class Dart_handle> template<class Dart_handle>
@ -916,10 +916,10 @@ protected:
template<class P> template<class P>
struct Get_traits<CGAL::Surface_mesh<P> > struct Get_traits<CGAL::Surface_mesh<P> >
{ {
typedef CGAL::Surface_mesh<P> Mesh; typedef CGAL::Surface_mesh<P> Mesh;
typedef typename CGAL::Kernel_traits<P>::Kernel Kernel; typedef typename CGAL::Kernel_traits<P>::Kernel Kernel;
typedef typename Kernel::Point_3 Point; typedef typename Kernel::Point_3 Point;
typedef typename Kernel::Vector_3 Vector; typedef typename Kernel::Vector_3 Vector;
template<class Dart_handle> template<class Dart_handle>
static const Point& get_point(const Mesh& m, Dart_handle dh) static const Point& get_point(const Mesh& m, Dart_handle dh)
@ -933,9 +933,10 @@ protected:
struct Get_traits<CGAL::Polyhedron_3<PolyhedronTraits_3, struct Get_traits<CGAL::Polyhedron_3<PolyhedronTraits_3,
PolyhedronItems_3, T_HDS, Alloc> > PolyhedronItems_3, T_HDS, Alloc> >
{ {
typedef CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> Mesh; typedef CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_3,
typedef PolyhedronTraits_3 Kernel; T_HDS, Alloc> Mesh;
typedef typename Kernel::Point_3 Point; typedef PolyhedronTraits_3 Kernel;
typedef typename Kernel::Point_3 Point;
typedef typename Kernel::Vector_3 Vector; typedef typename Kernel::Vector_3 Vector;
template<class Dart_handle> template<class Dart_handle>

View File

@ -48,11 +48,12 @@
namespace CGAL { namespace CGAL {
namespace Surface_mesh_topology { namespace Surface_mesh_topology {
template<typename Mesh> template<typename Mesh_>
class Path_on_surface class Path_on_surface
{ {
public: public:
typedef Path_on_surface<Mesh> Self; typedef Path_on_surface<Mesh_> Self;
typedef Mesh_ Mesh;
typedef typename Get_map<Mesh, Mesh>::type Map; typedef typename Get_map<Mesh, Mesh>::type Map;
typedef typename Map::Dart_const_handle Dart_const_handle; typedef typename Map::Dart_const_handle Dart_const_handle;
@ -279,13 +280,15 @@ public:
if (is_empty()) return true; if (is_empty()) return true;
return m_map.template belong_to_same_cell<0>(m_flip.back() ? back() : m_map.other_extremity(back()), return m_map.template belong_to_same_cell<0>
flip ? m_map.other_extremity(dh) : dh); (m_flip.back() ? back() : m_map.other_extremity(back()),
flip ? m_map.other_extremity(dh) : dh);
} }
/// Add the given dart at the end of this path. /// Add the given dart at the end of this path.
/// @pre can_be_pushed(dh) /// @pre can_be_pushed(dh)
void push_back(Dart_const_handle dh, bool flip=false, bool update_isclosed=true) void push_back(Dart_const_handle dh, bool flip=false,
bool update_isclosed=true)
{ {
CGAL_assertion(dh!=Map::null_handle); CGAL_assertion(dh!=Map::null_handle);
/* This assert is too long, it is tested in the is_valid method. */ /* This assert is too long, it is tested in the is_valid method. */
@ -297,14 +300,17 @@ public:
} }
/// @return true iff the ith dart can be added at the end of the path. /// @return true iff the ith dart can be added at the end of the path.
bool can_be_pushed_by_index(std::size_t i, bool flip=false, bool update_isclosed=true) const bool can_be_pushed_by_index(std::size_t i, bool flip=false,
bool update_isclosed=true) const
{ return can_be_pushed(get_map().dart_handle(i), flip, update_isclosed); } { return can_be_pushed(get_map().dart_handle(i), flip, update_isclosed); }
/// Add the given ith dart at the end of this path. /// Add the given ith dart at the end of this path.
void push_back_by_index(std::size_t i, bool flip=false, bool update_isclosed=true) void push_back_by_index(std::size_t i, bool flip=false,
bool update_isclosed=true)
{ push_back(get_map().dart_handle(i), flip, update_isclosed); } { push_back(get_map().dart_handle(i), flip, update_isclosed); }
void push_back_by_index(std::initializer_list<std::size_t> l, bool update_isclosed=true) void push_back_by_index(std::initializer_list<std::size_t> l,
bool update_isclosed=true)
{ {
for (std::size_t i : l) for (std::size_t i : l)
{ push_back_by_index(i, false, update_isclosed); } { push_back_by_index(i, false, update_isclosed); }
@ -330,7 +336,8 @@ public:
} }
} }
void push_back_by_label(std::initializer_list<const char*> l, bool update_isclosed=true) void push_back_by_label(std::initializer_list<const char*> l,
bool update_isclosed=true)
{ {
for (const char* e : l) for (const char* e : l)
{ push_back_by_label(e, false, update_isclosed); } { push_back_by_label(e, false, update_isclosed); }
@ -373,14 +380,16 @@ public:
{ std::cout<<std::endl; } { std::cout<<std::endl; }
} }
/// @return the number of flips of this path.
unsigned int nb_flips() unsigned int nb_flips()
{ {
unsigned int res=0; unsigned int res=0;
for (unsigned int i=0; i<length(); ++i) for (unsigned int i=0; i<length(); ++i)
{ res+=m_flip[i]; } { if (m_flip[i]) ++res; }
return res; return res;
} }
/// Cut this path to keep only the n first darts.
void cut(std::size_t n, bool update_isclosed=true) void cut(std::size_t n, bool update_isclosed=true)
{ {
if (n>=length()) return; if (n>=length()) return;
@ -405,11 +414,15 @@ public:
update_is_closed(); update_is_closed();
} }
/// Debugging method.
void display_failed_extention(const std::string& /*name_of_function*/) void display_failed_extention(const std::string& /*name_of_function*/)
{ {
// std::cout<<"Cant extend the path this way ("<<name_of_function<<")"<<std::endl; // std::cout<<"Cant extend the path this way ("<<name_of_function<<")"
// <<std::endl;
} }
/// Extend the path straight positive.
/// @pre must be non empty.
void extend_straight_positive(std::size_t nb=1, bool update_isclosed=true) void extend_straight_positive(std::size_t nb=1, bool update_isclosed=true)
{ {
if (is_empty() || nb==0) if (is_empty() || nb==0)
@ -438,6 +451,8 @@ public:
if (update_isclosed) { update_is_closed(); } if (update_isclosed) { update_is_closed(); }
} }
/// Extend the path straight negative.
/// @pre must be non empty.
void extend_straight_negative(std::size_t nb=1, bool update_isclosed=true) void extend_straight_negative(std::size_t nb=1, bool update_isclosed=true)
{ {
if (is_empty() || nb==0) if (is_empty() || nb==0)
@ -466,9 +481,12 @@ public:
if (update_isclosed) { update_is_closed(); } if (update_isclosed) { update_is_closed(); }
} }
/// Extend the path given a positive turn.
/// @pre must be non empty.
void extend_positive_turn(std::size_t nb=1, bool update_isclosed=true) void extend_positive_turn(std::size_t nb=1, bool update_isclosed=true)
{ {
if (is_empty()) { display_failed_extention("extend_positive_turn"); return; } if (is_empty())
{ display_failed_extention("extend_positive_turn"); return; }
if (nb==0) if (nb==0)
{ {
@ -496,6 +514,8 @@ public:
push_back(dh, false, update_isclosed); push_back(dh, false, update_isclosed);
} }
/// Extend the path given a negative turn.
/// @pre must be non empty.
void extend_negative_turn(std::size_t nb=1, bool update_isclosed=true) void extend_negative_turn(std::size_t nb=1, bool update_isclosed=true)
{ {
if (is_empty()) { display_failed_extention("extend_negative_turn"); return; } if (is_empty()) { display_failed_extention("extend_negative_turn"); return; }
@ -526,13 +546,15 @@ public:
push_back(dh, true, update_isclosed); push_back(dh, true, update_isclosed);
} }
/// Push back a random dart, if the path is empty. /// Initializes this path to a random starting path.
/// @pre must be empty.
bool initialize_random_starting_dart(CGAL::Random& random, bool initialize_random_starting_dart(CGAL::Random& random,
bool update_isclosed=true) bool update_isclosed=true)
{ {
if (!is_empty() || get_map().is_empty()) { return false; }//some precautions if (!is_empty() || get_map().is_empty()) { return false; }
// first select a random edge by taking the lower index of the two darts when it is not a boundary // first select a random edge by taking the lower index of
// the two darts when it is not a boundary
unsigned int index=random.get_int(0, get_map().darts().capacity()); unsigned int index=random.get_int(0, get_map().darts().capacity());
while (!get_map().darts().is_used(index) || while (!get_map().darts().is_used(index) ||
(!get_map().template is_free<2>(get_map().dart_handle(index)) && (!get_map().template is_free<2>(get_map().dart_handle(index)) &&
@ -542,7 +564,8 @@ public:
if (index==get_map().darts().capacity()) index=0; if (index==get_map().darts().capacity()) index=0;
} }
// second we take randomly one of the two darts of this edge (potentially with the help of a flip) // second we take randomly one of the two darts of this edge
// (potentially with the help of a flip)
bool heads_or_tails=random.get_int(0, 2); bool heads_or_tails=random.get_int(0, 2);
if (get_map().template is_free<2>(get_map().dart_handle(index))) if (get_map().template is_free<2>(get_map().dart_handle(index)))
{ {
@ -553,17 +576,22 @@ public:
if (heads_or_tails) if (heads_or_tails)
{ push_back(get_map().dart_handle(index), false, update_isclosed); } { push_back(get_map().dart_handle(index), false, update_isclosed); }
else else
{ push_back(get_map().template beta<2>(get_map().dart_handle(index)), false, update_isclosed); } { push_back(get_map().template beta<2>(get_map().dart_handle(index)),
false, update_isclosed); }
} }
return true; return true;
} }
/// Initializes this path to a random starting path.
/// @pre must be empty.
bool initialize_random_starting_dart(bool update_isclosed=true) bool initialize_random_starting_dart(bool update_isclosed=true)
{ {
CGAL::Random& random=get_default_random(); CGAL::Random& random=get_default_random();
return initialize_random_starting_dart(random, update_isclosed); return initialize_random_starting_dart(random, update_isclosed);
} }
/// Extends this path with a random dart.
/// @pre must be non empty.
bool extend_path_randomly(CGAL::Random& random, bool extend_path_randomly(CGAL::Random& random,
bool allow_half_turn=true, bool allow_half_turn=true,
bool update_isclosed=true) bool update_isclosed=true)
@ -591,17 +619,20 @@ public:
{ {
candidats.push_back(std::make_pair(it, false)); candidats.push_back(std::make_pair(it, false));
if (get_map().template is_free<2>(get_map().template beta<0>(it))) if (get_map().template is_free<2>(get_map().template beta<0>(it)))
{ candidats.push_back(std::make_pair(get_map().template beta<0>(it), true)); } { candidats.push_back
(std::make_pair(get_map().template beta<0>(it), true)); }
} }
else else
{ {
if (get_map().template is_free<2>(get_map().template beta<0>(it))) if (get_map().template is_free<2>(get_map().template beta<0>(it)))
{ candidats.push_back(std::make_pair(get_map().template beta<0>(it), true)); } { candidats.push_back
(std::make_pair(get_map().template beta<0>(it), true)); }
candidats.push_back(std::make_pair(it, false)); candidats.push_back(std::make_pair(it, false));
} }
} }
//candidats is now the list of all the darts that can be pushed back to the path (maybe with a flip) //candidats is now the list of all the darts that can be pushed back to
//the first of them in the list is the opposite of back(), or back() itself if it is 2-free // the path (maybe with a flip) the first of them in the list is the
// opposite of back(), or back() itself if it is 2-free
unsigned int i=random.get_int(allow_half_turn?0:1, candidats.size()); unsigned int i=random.get_int(allow_half_turn?0:1, candidats.size());
auto it=candidats.begin(); auto it=candidats.begin();
@ -610,6 +641,8 @@ public:
return true; return true;
} }
/// Extends this path with a random dart.
/// @pre must be non empty.
bool extend_path_randomly(bool allow_half_turn=false, bool extend_path_randomly(bool allow_half_turn=false,
bool update_isclosed=true) bool update_isclosed=true)
{ {
@ -617,27 +650,26 @@ public:
return extend_path_randomly(random, allow_half_turn, update_isclosed); return extend_path_randomly(random, allow_half_turn, update_isclosed);
} }
void generate_random_path(std::size_t length, CGAL::Random& random=get_default_random(), /// Generates a random path, with a number of darts >= length.
bool allow_half_turns=true, bool update_isclosed=true) void generate_random_path(std::size_t length,
CGAL::Random& random=get_default_random(),
bool allow_half_turns=true,
bool update_isclosed=true)
{ {
m_path.reserve(m_path.size()+length); m_path.reserve(m_path.size()+length);
for (std::size_t i=0; i<length; ++i) for (std::size_t i=0; i<length; ++i)
{ { extend_path_randomly(random, allow_half_turns, true); }
extend_path_randomly(random, allow_half_turns, true);
/*std::cout<<"Dart "<<i<<" flip="<<back_flip()<<std::endl;
if (!is_valid())
{ return; }*/
}
if (update_isclosed) { update_is_closed(); } if (update_isclosed) { update_is_closed(); }
//CGAL_assertion(is_valid());
//simplify_flips();
} }
/// Generates a random path.
template<typename Path> template<typename Path>
void generate_random_path(CGAL::Random& random, void generate_random_path(CGAL::Random& random,
bool update_isclosed=true) bool update_isclosed=true)
{ generate_random_path(random.get_int(1, 10000), random, true, update_isclosed); } { generate_random_path(random.get_int(1, 10000),
random, true, update_isclosed); }
/// Generates a random path.
template<typename Path> template<typename Path>
void generate_random_path(std::size_t length, void generate_random_path(std::size_t length,
bool update_isclosed=true) bool update_isclosed=true)
@ -646,6 +678,7 @@ public:
generate_random_path(length, random, true, update_isclosed); generate_random_path(length, random, true, update_isclosed);
} }
/// Generates a random path.
template<typename Path> template<typename Path>
void generate_random_path(bool update_isclosed=true) void generate_random_path(bool update_isclosed=true)
{ {
@ -653,6 +686,7 @@ public:
generate_random_path(random, update_isclosed); generate_random_path(random, update_isclosed);
} }
/// Generates a random closed path.
void generate_random_closed_path(std::size_t length, CGAL::Random& random) void generate_random_closed_path(std::size_t length, CGAL::Random& random)
{ {
m_path.reserve(m_path.size()+length); m_path.reserve(m_path.size()+length);
@ -662,18 +696,20 @@ public:
extend_path_randomly(random, true, true); extend_path_randomly(random, true, true);
++i; ++i;
} }
//CGAL_assertion(is_valid());
//simplify_flips();
} }
/// Generates a random closed path.
void generate_random_closed_path(std::size_t length) void generate_random_closed_path(std::size_t length)
{ {
CGAL::Random& random=get_default_random(); CGAL::Random& random=get_default_random();
generate_random_closed_path(length, random); generate_random_closed_path(length, random);
} }
/// Generates a random closed path.
void generate_random_closed_path(CGAL::Random& random) void generate_random_closed_path(CGAL::Random& random)
{ generate_random_closed_path(random.get_int(1, 10000), random); } { generate_random_closed_path(random.get_int(1, 10000), random); }
/// Generates a random closed path.
void generate_random_closed_path() void generate_random_closed_path()
{ {
CGAL::Random& random=get_default_random(); CGAL::Random& random=get_default_random();
@ -681,16 +717,16 @@ public:
} }
/// Replace edge [i] by the path of darts along the face. /// Replace edge [i] by the path of darts along the face.
/// If this face does not exist (if it is a boundary) then replace the edge by the face on the other side. /// If this face does not exist (if it is a boundary) then replace the edge
/// Problem of complexity when used many times (like in update_path_randomly). /// by the face on the other side. Problem of complexity when used many times
/// (like in update_path_randomly).
void push_around_face(std::size_t i, bool update_isclosed=true) void push_around_face(std::size_t i, bool update_isclosed=true)
{ {
CGAL_assertion(i<length()); CGAL_assertion(i<length());
Self p2(get_mesh()); Self p2(get_mesh());
if (get_ith_flip(i) /*&& get_map().template is_free<2>(get_ith_dart(i))*/) if (get_ith_flip(i))
{// in this case the face of the ith dart doesn't exist {// in this case the face of the ith dart doesn't exist
//std::cout<<"flip"<<std::endl;
Dart_const_handle dh=get_map().template beta<1>(get_ith_dart(i)); Dart_const_handle dh=get_map().template beta<1>(get_ith_dart(i));
do do
{ {
@ -699,10 +735,8 @@ public:
} }
while(dh!=get_ith_dart(i)); while(dh!=get_ith_dart(i));
} }
else else
{ {
//std::cout<<"NO flip"<<std::endl;
Dart_const_handle dh=get_map().template beta<0>(get_ith_dart(i)); Dart_const_handle dh=get_map().template beta<0>(get_ith_dart(i));
do do
{ {
@ -711,12 +745,10 @@ public:
} }
while(dh!=get_ith_dart(i)); while(dh!=get_ith_dart(i));
} }
//CGAL_assertion(p2.is_valid());
p2.m_path.reserve(p2.length()+length()-i); p2.m_path.reserve(p2.length()+length()-i);
for (std::size_t j=i+1; j<length(); ++j) for (std::size_t j=i+1; j<length(); ++j)
{ p2.push_back(get_ith_dart(j), get_ith_flip(j), false); } { p2.push_back(get_ith_dart(j), get_ith_flip(j), false); }
//CGAL_assertion(p2.is_valid());
cut(i, false); cut(i, false);
m_path.reserve(length()+p2.length()); m_path.reserve(length()+p2.length());
@ -735,9 +767,7 @@ public:
if (is_empty()) return; if (is_empty()) return;
for (unsigned int i=0; i<nb; ++i) for (unsigned int i=0; i<nb; ++i)
{ { push_around_face(random.get_int(0, length()), false); }
push_around_face(random.get_int(0, length()), false);
}
if (update_isclosed) { update_is_closed(); } if (update_isclosed) { update_is_closed(); }
} }
@ -897,18 +927,21 @@ public:
if (m_path[i]==m_map.null_dart_handle) if (m_path[i]==m_map.null_dart_handle)
{ return false; } { return false; }
last_vertex=m_flip[i-1]?m_path[i-1]:get_map().template beta<1>(m_path[i-1]); last_vertex=m_flip[i-1]?m_path[i-1]:get_map().beta(m_path[i-1], 1);
if (last_vertex==Map::null_handle) if (last_vertex==Map::null_handle)
{ {
if (display_error) if (display_error)
{ std::cout<<"Invalid path: one of the vertices doesn't exist"<<std::endl; } { std::cout<<"Invalid path: one of the vertices doesn't exist"
<<std::endl; }
return false; return false;
} }
if (!m_map.template belong_to_same_cell<0>(m_flip[i]?get_map().template beta<1>(m_path[i]):m_path[i], last_vertex)) if (!m_map.template belong_to_same_cell<0>
(m_flip[i]?get_map().beta(m_path[i], 1):m_path[i], last_vertex))
{ {
if (display_error) if (display_error)
{ std::cout<<"Invalid path: dart "<<i-1<<" and dart "<<i<<" are not adjacents"<<std::endl; } { std::cout<<"Invalid path: dart "<<i-1<<" and dart "<<i
<<" are not adjacents"<<std::endl; }
return false; return false;
} }
} }
@ -918,13 +951,16 @@ public:
if (last_vertex==Map::null_handle) if (last_vertex==Map::null_handle)
{ {
if (display_error) if (display_error)
{ std::cout<<"Invalid path: one of the vertices doesn't exist"<<std::endl; } { std::cout<<"Invalid path: one of the vertices doesn't exist"
<<std::endl; }
return false; return false;
} }
if (!m_map.template belong_to_same_cell<0>(front_flip()?get_map().template beta<1>(front()):front(), last_vertex)) if (!m_map.template belong_to_same_cell<0>
(front_flip()?get_map().beta(front(), 1):front(), last_vertex))
{ {
if (display_error) if (display_error)
{ std::cout<<"Invalid path: m_is_closed is true but the path is not closed"<<std::endl; } { std::cout<<"Invalid path: m_is_closed is true but the path is "
<<"not closed"<<std::endl; }
return false; return false;
} }
} }
@ -933,13 +969,16 @@ public:
if (last_vertex==Map::null_handle) if (last_vertex==Map::null_handle)
{ {
if (display_error) if (display_error)
{ std::cout<<"Invalid path: one of the vertices doesn't exist"<<std::endl; } { std::cout<<"Invalid path: one of the vertices doesn't exist"
<<std::endl; }
return false; return false;
} }
if (m_map.template belong_to_same_cell<0>(front_flip()?get_map().template beta<1>(front()):front(), last_vertex)) if (m_map.template belong_to_same_cell<0>
(front_flip()?get_map().beta(front(), 1):front(), last_vertex))
{ {
if (display_error) if (display_error)
{ std::cout<<"Invalid path: m_is_closed is false but the path is closed"<<std::endl; } { std::cout<<"Invalid path: m_is_closed is false but the path "
<<"is closed"<<std::endl; }
return false; return false;
} }
} }
@ -956,11 +995,13 @@ public:
if (is_empty()) { m_is_closed=false; } if (is_empty()) { m_is_closed=false; }
else else
{ {
Dart_const_handle pend= m_flip.back() ? back() : m_map.other_extremity(back()); Dart_const_handle
pend=m_flip.back()?back():m_map.other_extremity(back());
if (pend==Map::null_handle) { m_is_closed=false; } if (pend==Map::null_handle) { m_is_closed=false; }
else else
{ {
Dart_const_handle pbegin = m_flip[0] ? m_map.other_extremity(m_path[0]) : m_path[0]; Dart_const_handle
pbegin=m_flip[0]?m_map.other_extremity(m_path[0]):m_path[0];
m_is_closed=m_map.template belong_to_same_cell<0>(pbegin, pend); m_is_closed=m_map.template belong_to_same_cell<0>(pbegin, pend);
} }
} }
@ -1025,9 +1066,7 @@ public:
if (!is_closed()) if (!is_closed())
{ {
for (int i=m_path.size()-1; i>=0; --i) for (int i=m_path.size()-1; i>=0; --i)
{ { m_path.push_back(m_path[i], !m_flip[i], false); }
m_path.push_back(m_path[i], !m_flip[i], false);
}
m_is_closed=true; m_is_closed=true;
} }
} }
@ -1042,29 +1081,31 @@ public:
CGAL_assertion(i<m_path.size()); CGAL_assertion(i<m_path.size());
CGAL_assertion (is_closed() || i<length()-1); CGAL_assertion (is_closed() || i<length()-1);
if (get_ith_flip(i) && get_map().template is_free<2>(get_ith_dart(i)) || if ((get_ith_flip(i) && get_map().template is_free<2>(get_ith_dart(i))) ||
get_next_flip(i) && get_map().template is_free<2>(get_next_dart(i))) (get_next_flip(i) && get_map().template is_free<2>(get_next_dart(i))))
{ return std::numeric_limits<std::size_t>::max(); } { return std::numeric_limits<std::size_t>::max(); }
return m_map.positive_turn(get_ith_real_dart(i), return m_map.positive_turn(get_ith_real_dart(i),
get_ith_real_dart(next_index(i))); get_ith_real_dart(next_index(i)));
} }
/// Same than next_positive_turn but turning in reverse orientation around vertex. /// Same than next_positive_turn but turning in reverse orientation
/// around vertex.
std::size_t next_negative_turn(std::size_t i) const std::size_t next_negative_turn(std::size_t i) const
{ {
// CGAL_assertion(is_valid()); // CGAL_assertion(is_valid());
CGAL_assertion(i<m_path.size()); CGAL_assertion(i<m_path.size());
CGAL_assertion (is_closed() || i<length()-1); CGAL_assertion (is_closed() || i<length()-1);
if (!get_ith_flip(i) && get_map().template is_free<2>(get_ith_dart(i)) || if ((!get_ith_flip(i) && get_map().template is_free<2>(get_ith_dart(i))) ||
!get_next_flip(i) && get_map().template is_free<2>(get_next_dart(i))) (!get_next_flip(i) && get_map().template is_free<2>(get_next_dart(i))))
{ return std::numeric_limits<std::size_t>::max(); } { return std::numeric_limits<std::size_t>::max(); }
return m_map.positive_turn(get_opposite_ith_real_dart(next_index(i)), return m_map.positive_turn(get_opposite_ith_real_dart(next_index(i)),
get_opposite_ith_real_dart(i)); get_opposite_ith_real_dart(i));
} }
/// Computes all positive turns of this path.
std::vector<std::size_t> compute_positive_turns() const std::vector<std::size_t> compute_positive_turns() const
{ {
std::vector<std::size_t> res; std::vector<std::size_t> res;
@ -1078,6 +1119,7 @@ public:
return res; return res;
} }
/// Computes all negative turns of this path.
std::vector<std::size_t> compute_negative_turns() const std::vector<std::size_t> compute_negative_turns() const
{ {
std::vector<std::size_t> res; std::vector<std::size_t> res;
@ -1091,8 +1133,9 @@ public:
return res; return res;
} }
std::vector<std::size_t> compute_turns(bool positive) const /// Computes all positive or negative turns of this path, depending on p.
{ return (positive?compute_positive_turns():compute_negative_turns()); } std::vector<std::size_t> compute_turns(bool p) const
{ return (p?compute_positive_turns():compute_negative_turns()); }
bool same_turns_from(const char* turns, bool same_turns_from(const char* turns,
const std::vector<std::size_t>& resplus, const std::vector<std::size_t>& resplus,
@ -1186,10 +1229,10 @@ public:
} }
protected: protected:
const typename Get_map<Mesh, Mesh>::storage_type m_map; // The underlying map const Map m_map; // The underlying map (the mesh seen as a 2-map)
std::vector<Dart_const_handle> m_path; /// The sequence of darts std::vector<Dart_const_handle> m_path; /// The sequence of darts
bool m_is_closed; /// True iff the path is a cycle bool m_is_closed; /// True iff the path is a cycle
std::vector<bool> m_flip; std::vector<bool> m_flip; /// The sequence of flips
}; };
} // namespace Surface_mesh_topology } // namespace Surface_mesh_topology