mirror of https://github.com/CGAL/cgal
Start to work on path with rle, spurs removal.
This commit is contained in:
parent
4145ddeb0e
commit
919d4714ac
|
|
@ -1080,11 +1080,34 @@ namespace CGAL {
|
|||
}
|
||||
|
||||
// Simplify the path by removing all spurs
|
||||
// @return true iff at least one spur was removed
|
||||
bool remove_spurs(Path_on_surface<Map>& path) const
|
||||
{
|
||||
/* TODO TEMPO POUR TEST */
|
||||
Path_on_surface_with_rle<Map> prle(path);
|
||||
prle.remove_spurs();
|
||||
/* TODO FIN TEMPO POUR TEST */
|
||||
|
||||
bool res=false;
|
||||
while(remove_spurs_one_step(path))
|
||||
{ res=true; }
|
||||
|
||||
/* TODO TEMPO POUR TEST */
|
||||
Path_on_surface<Map> p2(prle);
|
||||
if (p2!=path)
|
||||
{
|
||||
std::cout<<"Error: p2!=path: "<<std::endl
|
||||
<<"p2= "<<p2<<"; "<<std::endl
|
||||
<<"path="<<path<<"; "<<std::endl
|
||||
<<"prle="<<prle<<std::endl;
|
||||
prle.display_pos_and_neg_turns();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout<<"GOOD JOB for path "<<p2<<std::endl;
|
||||
}
|
||||
/* TODO FIN TEMPO POUR TEST */
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1341,7 +1364,7 @@ namespace CGAL {
|
|||
|
||||
bool modified=false;
|
||||
// std::cout<<"RS ";
|
||||
remove_spurs_one_step(path);
|
||||
remove_spurs(path); // TODO BEFORE remove_spurs_one_step(path);
|
||||
|
||||
/* display(); display_pos_and_neg_turns();
|
||||
std::cout<<std::endl; */
|
||||
|
|
@ -1355,7 +1378,8 @@ namespace CGAL {
|
|||
/* std::cout<<"BF "; display(); display_pos_and_neg_turns();
|
||||
std::cout<<std::endl; */
|
||||
|
||||
modified=modified || remove_spurs_one_step(path);
|
||||
modified=modified || remove_spurs(path); // TODO BEFORE remove_spurs_one_step(path);
|
||||
|
||||
|
||||
/* std::cout<<"RS "; display(); display_pos_and_neg_turns();
|
||||
std::cout<<std::endl; */
|
||||
|
|
|
|||
|
|
@ -355,9 +355,7 @@ public:
|
|||
{
|
||||
assert(is_valid());
|
||||
assert(i<m_path.size());
|
||||
|
||||
if (!is_closed() && i==length()-1)
|
||||
{ return 0; }
|
||||
assert (is_closed() || i<length()-1);
|
||||
|
||||
Dart_const_handle d1=get_ith_dart(i);
|
||||
Dart_const_handle d2=get_next_dart(i);
|
||||
|
|
@ -381,9 +379,7 @@ public:
|
|||
{
|
||||
assert(is_valid());
|
||||
assert(i<m_path.size());
|
||||
|
||||
if (!is_closed() && i==length()-1)
|
||||
{ return 0; }
|
||||
assert (is_closed() || i<length()-1);
|
||||
|
||||
Dart_const_handle d1=m_map.template beta<2>(get_ith_dart(i));
|
||||
Dart_const_handle d2=m_map.template beta<2>(get_next_dart(i));
|
||||
|
|
@ -402,7 +398,6 @@ public:
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::size_t> compute_positive_turns() const
|
||||
{
|
||||
std::vector<std::size_t> res;
|
||||
|
|
@ -410,17 +405,9 @@ public:
|
|||
|
||||
std::size_t i;
|
||||
for (i=0; i<m_path.size()-1; ++i)
|
||||
{
|
||||
if (m_path[i]==m_map.template beta<2>(m_path[i+1]))
|
||||
{ res.push_back(0); }
|
||||
else { res.push_back(next_positive_turn(i)); }
|
||||
}
|
||||
{ res.push_back(next_positive_turn(i)); }
|
||||
if (is_closed())
|
||||
{
|
||||
if (m_path[i]==m_map.template beta<2>(m_path[0]))
|
||||
{ res.push_back(0); }
|
||||
else { res.push_back(next_positive_turn(i)); }
|
||||
}
|
||||
{ res.push_back(next_positive_turn(i)); }
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -431,17 +418,9 @@ public:
|
|||
|
||||
std::size_t i;
|
||||
for (i=0; i<m_path.size()-1; ++i)
|
||||
{
|
||||
if (m_path[i]==m_map.template beta<2>(m_path[i+1]))
|
||||
{ res.push_back(0); }
|
||||
else { res.push_back(next_negative_turn(i)); }
|
||||
}
|
||||
{ res.push_back(next_negative_turn(i)); }
|
||||
if (is_closed())
|
||||
{
|
||||
if (m_path[i]==m_map.template beta<2>(m_path[0]))
|
||||
{ res.push_back(0); }
|
||||
else { res.push_back(next_negative_turn(i)); }
|
||||
}
|
||||
{ res.push_back(next_negative_turn(i)); }
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -40,6 +41,9 @@ public:
|
|||
typedef Map_ Map;
|
||||
typedef typename Map::Dart_handle Dart_handle;
|
||||
typedef typename Map::Dart_const_handle Dart_const_handle;
|
||||
typedef std::list<std::pair<Dart_const_handle, int> > List_of_dart_length;
|
||||
typedef typename List_of_dart_length::iterator List_iterator;
|
||||
typedef typename List_of_dart_length::const_iterator List_const_iterator;
|
||||
|
||||
typedef Path_on_surface_with_rle<Map> Self;
|
||||
|
||||
|
|
@ -52,6 +56,8 @@ public:
|
|||
m_is_closed(apath.is_closed()),
|
||||
m_length(apath.length())
|
||||
{
|
||||
if (apath.is_empty()) return;
|
||||
|
||||
std::size_t i=0, j=0, starti=0, length=0;
|
||||
bool positive_flat=false;
|
||||
bool negative_flat=false;
|
||||
|
|
@ -160,6 +166,276 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void advance_iterator(List_iterator& it)
|
||||
{
|
||||
assert(it!=m_path.end());
|
||||
it=std::next(it);
|
||||
if (is_closed() && it==m_path.end())
|
||||
{ it=m_path.begin(); } // Here the path is closed, and it is the last element of the list
|
||||
}
|
||||
|
||||
void advance_iterator(List_const_iterator& it) const
|
||||
{
|
||||
assert(it!=m_path.end());
|
||||
it=std::next(it);
|
||||
if (is_closed() && it==m_path.end())
|
||||
{ it=m_path.begin(); } // Here the path is closed, and it is the last element of the list
|
||||
}
|
||||
|
||||
void retreat_iterator(List_iterator& it)
|
||||
{
|
||||
assert(it!=m_path.end());
|
||||
assert(it!=m_path.begin() || is_closed());
|
||||
if (is_closed() && it==m_path.begin())
|
||||
{ it=m_path.end(); }
|
||||
it=std::prev(it);
|
||||
}
|
||||
|
||||
void retreat_iterator(List_const_iterator& it) const
|
||||
{
|
||||
assert(it!=m_path.end());
|
||||
assert(it!=m_path.begin() || is_closed());
|
||||
if (is_closed() && it==m_path.begin())
|
||||
{ it=m_path.end(); }
|
||||
it=std::prev(it);
|
||||
}
|
||||
|
||||
List_iterator next_iterator(const List_iterator& it)
|
||||
{
|
||||
List_iterator res=it;
|
||||
advance_iterator(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
List_const_iterator next_iterator(const List_const_iterator& it) const
|
||||
{
|
||||
List_const_iterator res=it;
|
||||
advance_iterator(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
List_iterator prev_iterator(const List_iterator& it) const
|
||||
{
|
||||
List_iterator res=it;
|
||||
retreat_iterator(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
List_const_iterator prev_iterator(const List_const_iterator& it) const
|
||||
{
|
||||
List_const_iterator res=it;
|
||||
retreat_iterator(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
// @return true iff there is a dart after it
|
||||
bool next_dart_exist(const List_const_iterator& it) const
|
||||
{
|
||||
assert(it!=m_path.end());
|
||||
return is_closed() || std::next(it)!=m_path.end();
|
||||
}
|
||||
|
||||
// Return true if it is the beginning of a spur.
|
||||
bool is_spur(const List_const_iterator& it) const
|
||||
{
|
||||
assert(it!=m_path.end());
|
||||
return it->second==0 &&
|
||||
next_dart_exist(it) &&
|
||||
m_map.template beta<2>(it->first)==next_iterator(it)->first;
|
||||
}
|
||||
|
||||
// Remove the spur given by it; move it to the element before it
|
||||
// (m_path.end() if the path becomes empty).
|
||||
void remove_spur(List_iterator& it)
|
||||
{
|
||||
assert(is_spur(it));
|
||||
it=m_path.erase(it); // Erase the first dart of the spur
|
||||
if (is_closed() && it==m_path.end())
|
||||
{ it=m_path.begin(); }
|
||||
|
||||
if (it->second==0) // a flat part having only one dart
|
||||
{
|
||||
it=m_path.erase(it); // Erase the second dart of the spur
|
||||
if (is_closed() && it==m_path.end())
|
||||
{ it=m_path.begin(); }
|
||||
}
|
||||
else
|
||||
{ // Here we need to reduce the length of the flat part
|
||||
if (it->second>0)
|
||||
{
|
||||
--(it->second);
|
||||
it->first=m_map.template beta<1, 2, 1>(it->first);
|
||||
}
|
||||
else
|
||||
{
|
||||
++(it->second);
|
||||
it->first=m_map.template beta<2, 0, 2, 0, 2>(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
// Now move it to the element before the removed spur
|
||||
// except if the path has become empty, or if it is not closed
|
||||
// and we are in its first element.
|
||||
if (m_path.empty())
|
||||
{
|
||||
assert(it==m_path.end());
|
||||
m_is_closed=false;
|
||||
}
|
||||
else if (is_closed() || it!=m_path.begin())
|
||||
{
|
||||
retreat_iterator(it); // go to the previous element
|
||||
// TODO we need to test if the previous flat part should be merged with the next one
|
||||
if (compute_positive_turns(it, next(it))==2 || compute_negative_turns(it, next(it))==2 )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move it to the next spur after it. Go to m_path.end() if there is no
|
||||
// spur in the path.
|
||||
void move_to_next_spur(List_iterator& it)
|
||||
{
|
||||
assert(it!=m_path.end());
|
||||
List_iterator itend=(is_closed()?it:m_path.end());
|
||||
do
|
||||
{
|
||||
advance_iterator(it);
|
||||
if (is_spur(it)) { return; }
|
||||
}
|
||||
while(it!=itend);
|
||||
it=m_path.end(); // Here there is no spur in the whole path
|
||||
}
|
||||
|
||||
// Simplify the path by removing all spurs
|
||||
// @return true iff at least one spur was removed
|
||||
bool remove_spurs()
|
||||
{
|
||||
bool res=false;
|
||||
List_iterator it=m_path.begin();
|
||||
while(it!=m_path.end())
|
||||
{
|
||||
if (is_spur(it)) { remove_spur(it); res=true; }
|
||||
else { move_to_next_spur(it); }
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// @return the turn between dart it and next dart.
|
||||
/// (turn is position of the second edge in the cyclic ordering of
|
||||
/// edges starting from the first edge around the second extremity
|
||||
/// of the first dart)
|
||||
std::size_t next_positive_turn(const List_const_iterator& it) const
|
||||
{
|
||||
assert(is_valid());
|
||||
assert(it!=m_path.end());
|
||||
assert(is_closed() || std::next(it)!=m_path.end());
|
||||
|
||||
Dart_const_handle d1=it->first;
|
||||
if (it->second!=0)
|
||||
{
|
||||
if (it->second<0) { return -(it->second); }
|
||||
else { return it->second; }
|
||||
}
|
||||
|
||||
Dart_const_handle d2=next_iterator(it)->first;
|
||||
assert(d1!=d2);
|
||||
|
||||
if (d2==m_map.template beta<2>(d1))
|
||||
{ return 0; }
|
||||
|
||||
std::size_t res=1;
|
||||
while (m_map.template beta<1>(d1)!=d2)
|
||||
{
|
||||
++res;
|
||||
d1=m_map.template beta<1, 2>(d1);
|
||||
}
|
||||
// std::cout<<"next_positive_turn="<<res<<std::endl;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Same than next_positive_turn but turning in reverse orientation around vertex.
|
||||
std::size_t next_negative_turn(const List_const_iterator& it) const
|
||||
{
|
||||
assert(is_valid());
|
||||
assert(it!=m_path.end());
|
||||
assert(is_closed() || std::next(it)!=m_path.end());
|
||||
|
||||
Dart_const_handle d1=m_map.template beta<2>(it->first);
|
||||
if (it->second!=0)
|
||||
{
|
||||
if (it->second<0) { return -(it->second); }
|
||||
else { return it->second; }
|
||||
}
|
||||
|
||||
Dart_const_handle d2=m_map.template beta<2>(next_iterator(it)->first);
|
||||
assert(d1!=d2);
|
||||
|
||||
if (d2==m_map.template beta<2>(d1))
|
||||
{ return 0; }
|
||||
|
||||
std::size_t res=1;
|
||||
while (m_map.template beta<0>(d1)!=d2)
|
||||
{
|
||||
++res;
|
||||
d1=m_map.template beta<0, 2>(d1);
|
||||
}
|
||||
// std::cout<<"next_negative_turn="<<res<<std::endl;
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::size_t> compute_positive_turns() const
|
||||
{
|
||||
std::vector<std::size_t> res;
|
||||
if (is_empty()) return res;
|
||||
for (auto it=m_path.begin(), itend=m_path.end(); it!=itend; ++it)
|
||||
{
|
||||
if (is_closed() || std::next(it)!=m_path.end())
|
||||
{ res.push_back(next_positive_turn(it)); }
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::size_t> compute_negative_turns() const
|
||||
{
|
||||
std::vector<std::size_t> res;
|
||||
if (is_empty()) return res;
|
||||
for (auto it=m_path.begin(), itend=m_path.end(); it!=itend; ++it)
|
||||
{
|
||||
if (is_closed() || std::next(it)!=m_path.end())
|
||||
{ res.push_back(next_negative_turn(it)); }
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::size_t> compute_turns(bool positive) const
|
||||
{ return (positive?compute_positive_turns():compute_negative_turns()); }
|
||||
|
||||
void display_positive_turns() const
|
||||
{
|
||||
std::cout<<"+(";
|
||||
std::vector<std::size_t> res=compute_positive_turns();
|
||||
for (std::size_t i=0; i<res.size(); ++i)
|
||||
{ std::cout<<res[i]<<(i<res.size()-1?" ":""); }
|
||||
std::cout<<")";
|
||||
}
|
||||
|
||||
void display_negative_turns() const
|
||||
{
|
||||
std::cout<<"-(";
|
||||
std::vector<std::size_t> res=compute_negative_turns();
|
||||
for (std::size_t i=0; i<res.size(); ++i)
|
||||
{ std::cout<<res[i]<<(i<res.size()-1?" ":""); }
|
||||
std::cout<<")";
|
||||
}
|
||||
|
||||
void display_pos_and_neg_turns() const
|
||||
{
|
||||
display_positive_turns();
|
||||
std::cout<<" ";
|
||||
display_negative_turns();
|
||||
}
|
||||
|
||||
void display() const
|
||||
{
|
||||
for (auto it=m_path.begin(), itend=m_path.end(); it!=itend; ++it)
|
||||
|
|
@ -179,7 +455,7 @@ public:
|
|||
|
||||
protected:
|
||||
const Map& m_map; // The underlying map
|
||||
std::list<std::pair<Dart_const_handle, int> > m_path; // The sequence of turning darts, plus the length of the flat part after the dart (a flat part is a sequence of dart with positive turn == 2). If negative value k, -k is the length of the flat part, for negative turns (-2).
|
||||
List_of_dart_length m_path; // The sequence of turning darts, plus the length of the flat part after the dart (a flat part is a sequence of dart with positive turn == 2). If negative value k, -k is the length of the flat part, for negative turns (-2).
|
||||
bool m_is_closed; // True iff the path is a cycle
|
||||
std::size_t m_length;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue