mirror of https://github.com/CGAL/cgal
VC8 STL Fixes
This commit is contained in:
parent
24e6b1a4f3
commit
e6ddc1f499
|
|
@ -23,40 +23,106 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <CGAL/circulator.h>
|
#include <CGAL/circulator.h>
|
||||||
#include <CGAL/Partition_2/Indirect_less_xy_2.h>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
const int PARTITION_VMAP_UNSHARED_EDGE = -1;
|
const int PARTITION_VMAP_UNSHARED_EDGE = -1;
|
||||||
|
|
||||||
|
template<class Traits_>
|
||||||
|
class Vertex_info
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef Traits_ Traits;
|
||||||
|
typedef typename Traits::Polygon_2 Polygon_2 ;
|
||||||
|
typedef typename Traits::Polygon_2::Vertex_iterator Vertex_iterator;
|
||||||
|
typedef typename Traits::Less_xy_2 Less_xy_2;
|
||||||
|
|
||||||
|
Vertex_info ( Vertex_iterator const& vx_it, Polygon_2 const* poly_ptr )
|
||||||
|
:
|
||||||
|
m_vx_it(vx_it)
|
||||||
|
,m_poly_ptr(poly_ptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Vertex_iterator vertex_it() const { return m_vx_it ; }
|
||||||
|
Polygon_2 const* poly_ptr () const { return m_poly_ptr ; }
|
||||||
|
|
||||||
|
friend bool operator == ( Vertex_info const& a, Vertex_info const& b )
|
||||||
|
{
|
||||||
|
return a.poly_ptr() == b.poly_ptr() && a.vertex_it() == b.vertex_it() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator != ( Vertex_info const& a, Vertex_info const& b ) { return !(a==b); }
|
||||||
|
|
||||||
|
friend bool operator < ( Vertex_info const& a, Vertex_info const& b )
|
||||||
|
{
|
||||||
|
return Traits().less_xy_2_object()(*a.vertex_it(), *b.vertex_it());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Vertex_iterator m_vx_it ;
|
||||||
|
Polygon_2 const* m_poly_ptr ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
template <class Traits_>
|
||||||
|
class Edge_info
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef Traits_ Traits;
|
||||||
|
typedef Vertex_info<Traits> Vertex_info ;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Edge_info(Vertex_info e_ref, int p_num1) : _endpoint_ref(e_ref),
|
||||||
|
_poly_num1(p_num1), _poly_num2(PARTITION_VMAP_UNSHARED_EDGE)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void set_poly_num2(int p_num)
|
||||||
|
{
|
||||||
|
_poly_num2 = p_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vertex_info endpoint() const { return _endpoint_ref; }
|
||||||
|
int poly_num1() const { return _poly_num1; }
|
||||||
|
int poly_num2() const { return _poly_num2; }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vertex_info _endpoint_ref;
|
||||||
|
int _poly_num1;
|
||||||
|
int _poly_num2;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Traits>
|
template <class Traits>
|
||||||
class Partition_vertex_map;
|
|
||||||
|
|
||||||
template <class Iterator>
|
|
||||||
class Edge_info;
|
|
||||||
|
|
||||||
template <class Iterator, class Traits>
|
|
||||||
class CW_indirect_edge_info_compare
|
class CW_indirect_edge_info_compare
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename Traits::Left_turn_2 Left_turn_2;
|
|
||||||
typedef typename Traits::Less_xy_2 Less_xy_2;
|
|
||||||
typedef typename Traits::Point_2 Point_2;
|
|
||||||
typedef CGAL::Edge_info<Iterator> Edge_info;
|
|
||||||
|
|
||||||
CW_indirect_edge_info_compare(){}
|
typedef Vertex_info<Traits> Vertex_info ;
|
||||||
CW_indirect_edge_info_compare (Iterator v_it) : vertex_it(v_it),
|
typedef Edge_info<Traits> Edge_info;
|
||||||
|
|
||||||
|
typedef typename Vertex_info::Vertex_iterator Vertex_iterator ;
|
||||||
|
|
||||||
|
typedef typename Traits::Left_turn_2 Left_turn_2;
|
||||||
|
typedef typename Traits::Less_xy_2 Less_xy_2;
|
||||||
|
typedef typename Traits::Point_2 Point_2;
|
||||||
|
|
||||||
|
CW_indirect_edge_info_compare (Vertex_iterator v_info) : vertex_it(v_info),
|
||||||
left_turn(Traits().left_turn_2_object()),
|
left_turn(Traits().left_turn_2_object()),
|
||||||
less_xy(Traits().less_xy_2_object())
|
less_xy(Traits().less_xy_2_object())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool operator()(Edge_info e1, Edge_info e2)
|
bool operator()(Edge_info e1, Edge_info e2)
|
||||||
{
|
{
|
||||||
bool e1_less = less_xy((*e1.endpoint()), *vertex_it);
|
bool e1_less = less_xy((*e1.endpoint().vertex_it()), *vertex_it);
|
||||||
bool e2_less = less_xy((*e2.endpoint()), *vertex_it);
|
bool e2_less = less_xy((*e2.endpoint().vertex_it()), *vertex_it);
|
||||||
bool e1_to_e2_left_turn = left_turn((*e1.endpoint()), *vertex_it,
|
bool e1_to_e2_left_turn = left_turn((*e1.endpoint().vertex_it()), *vertex_it,
|
||||||
(*e2.endpoint()));
|
(*e2.endpoint().vertex_it()));
|
||||||
|
|
||||||
// if both edges are on the same side of the vertical line through
|
// if both edges are on the same side of the vertical line through
|
||||||
// _vertex then e1 comes before e2 (in CW order from the vertical line)
|
// _vertex then e1 comes before e2 (in CW order from the vertical line)
|
||||||
|
|
@ -68,249 +134,238 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Iterator vertex_it;
|
Vertex_iterator vertex_it;
|
||||||
Left_turn_2 left_turn;
|
Left_turn_2 left_turn;
|
||||||
Less_xy_2 less_xy;
|
Less_xy_2 less_xy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class Iterator>
|
|
||||||
class Edge_info
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Edge_info() {}
|
|
||||||
Edge_info(Iterator e_ref, int p_num1, int p_num2) : _endpoint_ref(e_ref),
|
|
||||||
_poly_num1(p_num1), _poly_num2(p_num2)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Edge_info(Iterator e_ref, int p_num1) : _endpoint_ref(e_ref),
|
|
||||||
_poly_num1(p_num1), _poly_num2(PARTITION_VMAP_UNSHARED_EDGE)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void set_poly_num1(int p_num)
|
|
||||||
{
|
|
||||||
_poly_num1 = p_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_poly_num2(int p_num)
|
|
||||||
{
|
|
||||||
_poly_num2 = p_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_endpoint(Iterator e_ref)
|
|
||||||
{
|
|
||||||
_endpoint_ref = e_ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool same_edge(Iterator e_ref)
|
|
||||||
{
|
|
||||||
return e_ref == endpoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator endpoint() const { return _endpoint_ref; }
|
|
||||||
int poly_num1() const { return _poly_num1; }
|
|
||||||
int poly_num2() const { return _poly_num2; }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
Iterator _endpoint_ref;
|
|
||||||
int _poly_num1;
|
|
||||||
int _poly_num2;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class Traits_>
|
template <class Traits_>
|
||||||
class Pvm_edge_list : public std::list<
|
class Edge_list
|
||||||
Edge_info<typename Traits_::Polygon_2::Vertex_iterator> >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Traits_ Traits;
|
|
||||||
typedef Pvm_edge_list<Traits> Self;
|
|
||||||
typedef typename Traits::Point_2 Point_2;
|
|
||||||
typedef typename Traits::Orientation_2 Orientation_pred;
|
|
||||||
typedef typename Traits::Polygon_2::Vertex_iterator Vertex_iterator;
|
|
||||||
typedef Edge_info<Vertex_iterator> Edge;
|
|
||||||
typedef typename std::list<Edge>::iterator Self_iterator;
|
|
||||||
typedef typename std::list<Edge>::const_iterator Self_const_iterator;
|
|
||||||
typedef Circulator_from_iterator<Self_const_iterator>
|
|
||||||
Self_const_circulator;
|
|
||||||
|
|
||||||
|
typedef Traits_ Traits;
|
||||||
|
typedef Edge_list<Traits> Self;
|
||||||
|
typedef typename Traits::Point_2 Point_2;
|
||||||
|
typedef typename Traits::Orientation_2 Orientation_pred;
|
||||||
|
typedef typename Traits::Polygon_2 Polygon_2 ;
|
||||||
|
typedef typename Traits::Polygon_2::Vertex_iterator Vertex_iterator;
|
||||||
|
|
||||||
|
typedef Vertex_info<Traits> Vertex_info;
|
||||||
|
typedef Edge_info<Traits> Edge_info;
|
||||||
|
|
||||||
|
typedef std::list<Edge_info> List ;
|
||||||
|
|
||||||
|
typedef typename List::iterator Self_iterator;
|
||||||
|
typedef typename List::const_iterator Self_const_iterator;
|
||||||
|
typedef typename List::size_type size_type ;
|
||||||
|
|
||||||
|
typedef Circulator_from_iterator<Self_const_iterator> Self_const_circulator;
|
||||||
|
|
||||||
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
||||||
static CW_indirect_edge_info_compare<Vertex_iterator, Traits>
|
static CW_indirect_edge_info_compare<Traits> cw_indirect_edge_info_compare;
|
||||||
cw_indirect_edge_info_compare;
|
|
||||||
|
|
||||||
static bool compare(const Edge& e1, const Edge& e2)
|
static bool compare(const Edge_info& e1, const Edge_info& e2)
|
||||||
{
|
{
|
||||||
return cw_indirect_edge_info_compare(e1,e2);
|
return cw_indirect_edge_info_compare(e1,e2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void insert_next(Vertex_iterator endpoint_ref, int num)
|
Self_const_iterator begin() const { return m_list.begin() ; }
|
||||||
{
|
Self_iterator begin() { return m_list.begin() ; }
|
||||||
Self_iterator e_it;
|
Self_const_iterator end () const { return m_list.end () ; }
|
||||||
|
Self_iterator end () { return m_list.end () ; }
|
||||||
|
|
||||||
for (e_it = this->begin();
|
size_type size() const { return m_list.size() ; }
|
||||||
e_it != this->end() && (*e_it).endpoint() != endpoint_ref;
|
|
||||||
e_it++)
|
|
||||||
{}
|
|
||||||
|
|
||||||
if (e_it != this->end())
|
Edge_info const& front() const { return m_list.front() ; }
|
||||||
(*e_it).set_poly_num2(num);
|
Edge_info & front() { return m_list.front() ; }
|
||||||
else
|
|
||||||
push_back(Edge(endpoint_ref, num));
|
|
||||||
}
|
|
||||||
|
|
||||||
void insert_prev(Vertex_iterator endpoint_ref, int num)
|
Edge_info const& back() const { return m_list.back() ; }
|
||||||
{
|
Edge_info & back() { return m_list.back() ; }
|
||||||
Self_iterator e_it;
|
|
||||||
|
|
||||||
for (e_it = this->begin();
|
template<class Compare> void sort ( Compare c ) { m_list.sort(c); }
|
||||||
e_it != this->end() && (*e_it).endpoint() != endpoint_ref;
|
|
||||||
e_it++)
|
|
||||||
{}
|
|
||||||
|
|
||||||
if (e_it != this->end())
|
void insert_next(Vertex_info endpoint_ref, int num)
|
||||||
(*e_it).set_poly_num2(num);
|
{
|
||||||
else
|
|
||||||
push_front(Edge(endpoint_ref, num));
|
|
||||||
}
|
|
||||||
|
|
||||||
// PRE: polygons must be simple
|
Self_iterator e_it;
|
||||||
bool edges_overlap(Vertex_iterator vertex_it)
|
|
||||||
{
|
for (e_it = m_list.begin(); e_it != m_list.end() && e_it->endpoint() != endpoint_ref ; e_it++)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e_it != m_list.end())
|
||||||
|
{
|
||||||
|
(*e_it).set_poly_num2(num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_list.push_back(Edge_info(endpoint_ref, num));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_prev(Vertex_info endpoint_ref, int num)
|
||||||
|
{
|
||||||
|
|
||||||
|
Self_iterator e_it;
|
||||||
|
|
||||||
|
for (e_it = m_list.begin(); e_it != m_list.end() && e_it->endpoint() != endpoint_ref ; e_it++)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e_it != m_list.end())
|
||||||
|
{
|
||||||
|
(*e_it).set_poly_num2(num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_list.push_front(Edge_info(endpoint_ref, num));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PRE: polygons must be simple
|
||||||
|
bool edges_overlap(Vertex_iterator vertex_it)
|
||||||
|
{
|
||||||
|
|
||||||
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
||||||
std::cout << "before sort: edges for " << *vertex_it << std::endl;
|
std::cout << "before sort: edges for " << *vertex_it << std::endl;
|
||||||
std::cout << *this << std::endl;
|
std::cout << *this << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int num_unshared = 0;
|
int num_unshared = 0;
|
||||||
|
|
||||||
// Don't want to sort the edges for vertices of degree 2 because they
|
// Don't want to sort the edges for vertices of degree 2 because they
|
||||||
// are already in CCW order (since the partition polygons were in CCW
|
// are already in CCW order (since the partition polygons were in CCW
|
||||||
// order), and this is what you need when you construct the union
|
// order), and this is what you need when you construct the union
|
||||||
// polygon.
|
// polygon.
|
||||||
if (this->size() > 2){
|
if (m_list.size() > 2)
|
||||||
|
{
|
||||||
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
||||||
cw_indirect_edge_info_compare =
|
cw_indirect_edge_info_compare =
|
||||||
CW_indirect_edge_info_compare<Vertex_iterator,Traits>(vertex_it);
|
CW_indirect_edge_info_compare<Traits>(vertex_it);
|
||||||
this->sort(&Self::compare);
|
m_list.sort(&Self::compare);
|
||||||
#else
|
#else
|
||||||
this->sort
|
m_list.sort
|
||||||
(CW_indirect_edge_info_compare<Vertex_iterator,Traits>(vertex_it));
|
(CW_indirect_edge_info_compare<Traits>(vertex_it));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
||||||
std::cout << "after sort: edges for " << *vertex_it << std::endl;
|
std::cout << "after sort: edges for " << *vertex_it << std::endl;
|
||||||
std::cout << *this << std::endl;
|
std::cout << *this << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Self_const_iterator prev_e_it = this->begin();
|
Self_const_iterator prev_e_it = m_list.begin();
|
||||||
Self_const_iterator e_it;
|
Self_const_iterator e_it;
|
||||||
|
|
||||||
for (e_it = this->begin(); e_it != this->end(); e_it++)
|
for (e_it = m_list.begin(); e_it != m_list.end(); e_it++)
|
||||||
{
|
{
|
||||||
if ((*e_it).poly_num1() == PARTITION_VMAP_UNSHARED_EDGE)
|
if ((*e_it).poly_num1() == PARTITION_VMAP_UNSHARED_EDGE)
|
||||||
num_unshared++;
|
num_unshared++;
|
||||||
if ((*e_it).poly_num2() == PARTITION_VMAP_UNSHARED_EDGE)
|
if ((*e_it).poly_num2() == PARTITION_VMAP_UNSHARED_EDGE)
|
||||||
num_unshared++;
|
num_unshared++;
|
||||||
|
|
||||||
if ((*prev_e_it).poly_num1() != (*e_it).poly_num1() &&
|
if ((*prev_e_it).poly_num1() != (*e_it).poly_num1() &&
|
||||||
(*prev_e_it).poly_num1() != (*e_it).poly_num2() &&
|
(*prev_e_it).poly_num1() != (*e_it).poly_num2() &&
|
||||||
(*prev_e_it).poly_num2() != (*e_it).poly_num1() &&
|
(*prev_e_it).poly_num2() != (*e_it).poly_num1() &&
|
||||||
(*prev_e_it).poly_num2() != (*e_it).poly_num2())
|
(*prev_e_it).poly_num2() != (*e_it).poly_num2())
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
prev_e_it = e_it;
|
|
||||||
}
|
|
||||||
if ((*prev_e_it).poly_num1() != (*this->begin()).poly_num1() &&
|
|
||||||
(*prev_e_it).poly_num1() != (*this->begin()).poly_num2() &&
|
|
||||||
(*prev_e_it).poly_num2() != (*this->begin()).poly_num1() &&
|
|
||||||
(*prev_e_it).poly_num2() != (*this->begin()).poly_num2())
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
prev_e_it = e_it;
|
||||||
|
}
|
||||||
|
if ((*prev_e_it).poly_num1() != (*m_list.begin()).poly_num1() &&
|
||||||
|
(*prev_e_it).poly_num1() != (*m_list.begin()).poly_num2() &&
|
||||||
|
(*prev_e_it).poly_num2() != (*m_list.begin()).poly_num1() &&
|
||||||
|
(*prev_e_it).poly_num2() != (*m_list.begin()).poly_num2())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return (num_unshared > 2);
|
return (num_unshared > 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// NOTE: the edges here are sorted in CW order so the next CCW edge
|
// NOTE: the edges here are sorted in CW order so the next CCW edge
|
||||||
// comes BEFORE the edge with endpoint v_it in the sorted list
|
// comes BEFORE the edge with endpoint v_info in the sorted list
|
||||||
Edge next_ccw_edge_info(Vertex_iterator v_it) const
|
Edge_info next_ccw_edge_info(Vertex_info v_info) const
|
||||||
{
|
{
|
||||||
Self_const_circulator first_e(this->begin(), this->end(), this->begin());
|
Self_const_circulator first_e(m_list.begin(), m_list.end(), m_list.begin());
|
||||||
Self_const_circulator e_circ = first_e;
|
Self_const_circulator e_circ = first_e;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
{
|
||||||
|
if ((*e_circ).endpoint() == v_info)
|
||||||
{
|
{
|
||||||
if ((*e_circ).endpoint() == v_it)
|
e_circ--; // go to the previous endpoint
|
||||||
{
|
return *e_circ;
|
||||||
e_circ--; // go to the previous endpoint
|
|
||||||
return *e_circ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (++e_circ != first_e);
|
}
|
||||||
return *first_e; // shouldn't get here unless v_it is not in list
|
while (++e_circ != first_e);
|
||||||
}
|
return *first_e; // shouldn't get here unless v_info is not in list
|
||||||
|
}
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
List m_list ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
||||||
template <class Traits>
|
template <class Traits>
|
||||||
CW_indirect_edge_info_compare<typename Traits::Polygon_2::Vertex_iterator,
|
CW_indirect_edge_info_compare< Edge_info<Traits> >
|
||||||
Traits>
|
Edge_list<Traits>::cw_indirect_edge_info_compare;
|
||||||
Pvm_edge_list<Traits>::cw_indirect_edge_info_compare;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class Traits>
|
template <class Traits>
|
||||||
std::ostream& operator<<(std::ostream& os,
|
std::ostream& operator<<(std::ostream& os, const Edge_list<Traits>& edges)
|
||||||
const Pvm_edge_list<Traits>& edges)
|
|
||||||
{
|
{
|
||||||
typename Pvm_edge_list<Traits>::const_iterator e_it;
|
typename Edge_list<Traits>::const_iterator e_it;
|
||||||
|
|
||||||
for (e_it = edges.begin(); e_it != edges.end(); e_it++)
|
for (e_it = edges.begin(); e_it != edges.end(); e_it++)
|
||||||
{
|
{
|
||||||
os << " " << (*(*e_it).endpoint())
|
os << "edge with endpoint (" << (*(*e_it).endpoint().vertex_it())
|
||||||
<< " from poly #" << (*e_it).poly_num1()
|
<< ") from poly #" << (*e_it).poly_num1()
|
||||||
<< " and poly #" << (*e_it).poly_num2()
|
<< " and poly #" << (*e_it).poly_num2()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Traits>
|
template <class Traits_>
|
||||||
class Partition_vertex_map :
|
class Partition_vertex_map
|
||||||
public std::map<typename Traits::Polygon_2::Vertex_iterator,
|
|
||||||
Pvm_edge_list<Traits>,
|
|
||||||
Indirect_less_xy_2<Traits> >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Partition_vertex_map<Traits> Self;
|
|
||||||
typedef typename std::map<typename Traits::Polygon_2::Vertex_iterator,
|
|
||||||
Pvm_edge_list<Traits>,
|
|
||||||
Indirect_less_xy_2<Traits> >::iterator
|
|
||||||
Self_iterator;
|
|
||||||
typedef typename Traits::Point_2 Point_2;
|
|
||||||
typedef typename Traits::Polygon_2::Vertex_iterator Vertex_iterator;
|
|
||||||
|
|
||||||
|
typedef Traits_ Traits ;
|
||||||
|
typedef Vertex_info<Traits> Vertex_info ;
|
||||||
|
typedef Edge_info <Traits> Edge_info ;
|
||||||
|
typedef Edge_list <Traits> Edge_list ;
|
||||||
|
|
||||||
typedef Edge_info<Vertex_iterator> Edge;
|
typedef Partition_vertex_map<Traits> Self;
|
||||||
|
|
||||||
|
typedef std::map<Vertex_info, Edge_list> Map ;
|
||||||
|
|
||||||
|
typedef typename Map::const_iterator Self_const_iterator;
|
||||||
|
typedef typename Map::iterator Self_iterator;
|
||||||
|
|
||||||
|
typedef typename Traits::Point_2 Point_2;
|
||||||
|
typedef typename Traits::Polygon_2 Polygon_2 ;
|
||||||
|
|
||||||
|
typedef typename Polygon_2::Vertex_iterator Vertex_iterator;
|
||||||
|
|
||||||
Partition_vertex_map() {}
|
Partition_vertex_map() {}
|
||||||
|
|
||||||
|
|
||||||
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
||||||
static CW_indirect_edge_info_compare<Vertex_iterator,Traits>
|
static CW_indirect_edge_info_compare<Traits> cw_indirect_edge_info_compare;
|
||||||
cw_indirect_edge_info_compare;
|
static bool compare(const Edge_info & e1, const Edge_info& e2)
|
||||||
static bool compare(const Edge & e1, const Edge& e2)
|
|
||||||
{
|
{
|
||||||
return cw_indirect_edge_info_compare(e1, e2);
|
return cw_indirect_edge_info_compare(e1, e2);
|
||||||
}
|
}
|
||||||
|
|
@ -318,14 +373,121 @@ public:
|
||||||
|
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
Partition_vertex_map(InputIterator first_poly, InputIterator last_poly)
|
Partition_vertex_map(InputIterator first_poly, InputIterator last_poly)
|
||||||
{ build(first_poly, last_poly); }
|
{ _build(first_poly, last_poly); }
|
||||||
|
|
||||||
|
Self_const_iterator begin() const { return m_map.begin() ; }
|
||||||
|
Self_iterator begin() { return m_map.begin() ; }
|
||||||
|
Self_const_iterator end () const { return m_map.end () ; }
|
||||||
|
Self_iterator end () { return m_map.end () ; }
|
||||||
|
|
||||||
|
bool polygons_overlap()
|
||||||
|
{
|
||||||
|
Self_iterator v_info;
|
||||||
|
for (v_info = m_map.begin(); v_info != m_map.end(); v_info++)
|
||||||
|
{
|
||||||
|
if ((*v_info).second.edges_overlap((*v_info).first.vertex_it()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OutputIterator>
|
||||||
|
OutputIterator union_vertices(OutputIterator result)
|
||||||
|
{
|
||||||
|
if (m_map.empty())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
Self_iterator m_it = m_map.begin();
|
||||||
|
|
||||||
|
// find a vertex with degree 2 (there must be at least one)
|
||||||
|
while (m_it != m_map.end() && (*m_it).second.size() != 2)
|
||||||
|
m_it++;
|
||||||
|
CGAL_assertion (m_it != m_map.end());
|
||||||
|
|
||||||
|
// insert this vertex and the two around it
|
||||||
|
Vertex_info first_v_info = (*m_it).second.front().endpoint();
|
||||||
|
Vertex_info prev_v_info = first_v_info ;
|
||||||
|
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
||||||
|
std::cout << "union_vertices: inserting " << (*prev_v_info.vertex_it()) << std::endl;
|
||||||
|
#endif
|
||||||
|
*result = *prev_v_info.vertex_it();
|
||||||
|
result++;
|
||||||
|
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
||||||
|
std::cout << "union_vertices: inserting "<< *(*m_it).first.vertex_it() << std::endl;
|
||||||
|
#endif
|
||||||
|
*result = *(*m_it).first.vertex_it();
|
||||||
|
result++;
|
||||||
|
Vertex_info next_v_info = (*m_it).second.back().endpoint();
|
||||||
|
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
||||||
|
std::cout << "union_vertices: inserting " << *next_v_info.vertex_it() << std::endl;
|
||||||
|
#endif
|
||||||
|
*result = *next_v_info.vertex_it();
|
||||||
|
result++;
|
||||||
|
|
||||||
|
// find the map iterator corresponding to the next vertex
|
||||||
|
prev_v_info = (*m_it).first;
|
||||||
|
Vertex_info v_info = next_v_info;
|
||||||
|
m_it = m_map.find(v_info);
|
||||||
|
|
||||||
|
while (v_info != first_v_info && m_it != m_map.end())
|
||||||
|
{
|
||||||
|
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
||||||
|
std::cout << "union_vertices: prev_v_info " << (*prev_v_info.vertex_it())
|
||||||
|
<< " v_info " << (*v_info.vertex_it()) << " next_v_info "
|
||||||
|
<< (*next_v_info.vertex_it()) << std::endl;
|
||||||
|
#endif
|
||||||
|
// Don't want to sort the edges for vertices of degree 2 because they
|
||||||
|
// are already in CCW order (since the partition polygons were in CCW
|
||||||
|
// order), and this is what you need to begin the construction
|
||||||
|
// of the union polygon.
|
||||||
|
if ((*m_it).second.size() > 2)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
||||||
|
cw_indirect_edge_info_compare =
|
||||||
|
CW_indirect_edge_info_compare<Traits>((*m_it).first.vertex_it());
|
||||||
|
(*m_it).second.sort(&Self::compare);
|
||||||
|
#else
|
||||||
|
(*m_it).second.sort(
|
||||||
|
CW_indirect_edge_info_compare<Traits>((*m_it).first.vertex_it()));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the previous vertex in this vertex's list
|
||||||
|
next_v_info=(*m_it).second.next_ccw_edge_info(prev_v_info).endpoint();
|
||||||
|
if (next_v_info != first_v_info)
|
||||||
|
{
|
||||||
|
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
||||||
|
std::cout << "union_vertices: inserting "
|
||||||
|
<< *next_v_info.vertex_it() << std::endl;
|
||||||
|
#endif
|
||||||
|
*result = *next_v_info.vertex_it();
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
prev_v_info = v_info;
|
||||||
|
v_info = next_v_info;
|
||||||
|
m_it = m_map.find(v_info);
|
||||||
|
CGAL_assertion (m_it == m_map.end() || (*m_it).first == v_info);
|
||||||
|
}
|
||||||
|
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
||||||
|
if (v_info == first_v_info)
|
||||||
|
std::cout << "union_vertices: stopped because first was reached "
|
||||||
|
<< std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "union_vertices: stopped because end was reached "
|
||||||
|
<< std::endl;
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
void build(InputIterator poly_first, InputIterator poly_last)
|
void _build(InputIterator poly_first, InputIterator poly_last)
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef std::pair<Self_iterator, bool> Location_pair;
|
typedef std::pair<Self_iterator, bool> Location_pair;
|
||||||
typedef Pvm_edge_list<Traits> Pvm_edge_list;
|
typedef std::pair<Vertex_info, Edge_list> P_Vertex;
|
||||||
typedef std::pair<Vertex_iterator, Pvm_edge_list> P_Vertex;
|
|
||||||
|
|
||||||
Location_pair v_loc_pair;
|
Location_pair v_loc_pair;
|
||||||
Location_pair begin_v_loc_pair;
|
Location_pair begin_v_loc_pair;
|
||||||
|
|
@ -338,20 +500,25 @@ public:
|
||||||
int poly_num = 0;
|
int poly_num = 0;
|
||||||
for (; poly_first != poly_last; poly_first++, poly_num++)
|
for (; poly_first != poly_last; poly_first++, poly_num++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Polygon_2 const* poly_ptr = &(*poly_first);
|
||||||
|
|
||||||
vtx_begin = (*poly_first).vertices_begin();
|
vtx_begin = (*poly_first).vertices_begin();
|
||||||
vtx_end = (*poly_first).vertices_end();
|
vtx_end = (*poly_first).vertices_end();
|
||||||
begin_v_loc_pair = this->insert(P_Vertex(vtx_begin, Pvm_edge_list()));
|
begin_v_loc_pair = m_map.insert(P_Vertex( Vertex_info(vtx_begin,poly_ptr), Edge_list()));
|
||||||
|
|
||||||
prev_v_loc_pair = begin_v_loc_pair;
|
prev_v_loc_pair = begin_v_loc_pair;
|
||||||
v_it = vtx_begin;
|
v_it = vtx_begin;
|
||||||
|
|
||||||
for (v_it++; v_it != vtx_end; v_it++)
|
for (v_it++; v_it != vtx_end; v_it++)
|
||||||
{
|
{
|
||||||
v_loc_pair = this->insert(P_Vertex(v_it, Pvm_edge_list()));
|
|
||||||
insert_next_edge(prev_v_loc_pair.first,
|
v_loc_pair = m_map.insert(P_Vertex( Vertex_info(v_it,poly_ptr), Edge_list()));
|
||||||
v_loc_pair.first,
|
|
||||||
poly_num);
|
insert_next_edge(prev_v_loc_pair.first, v_loc_pair.first, poly_num);
|
||||||
insert_prev_edge(v_loc_pair.first,
|
|
||||||
prev_v_loc_pair.first,
|
insert_prev_edge(v_loc_pair.first, prev_v_loc_pair.first, poly_num);
|
||||||
poly_num);
|
|
||||||
prev_v_loc_pair = v_loc_pair;
|
prev_v_loc_pair = v_loc_pair;
|
||||||
}
|
}
|
||||||
insert_next_edge(prev_v_loc_pair.first, begin_v_loc_pair.first,
|
insert_next_edge(prev_v_loc_pair.first, begin_v_loc_pair.first,
|
||||||
|
|
@ -362,123 +529,24 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void insert_next_edge(Self_iterator& v1_ref, Self_iterator& v2_ref,
|
void insert_next_edge(Self_iterator& v1_ref, Self_iterator& v2_ref, int num)
|
||||||
int num)
|
|
||||||
{
|
{
|
||||||
(*v1_ref).second.insert_next((*v2_ref).first, num);
|
(*v1_ref).second.insert_next((*v2_ref).first, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert_prev_edge(Self_iterator& v1_ref, Self_iterator& v2_ref,
|
void insert_prev_edge(Self_iterator& v1_ref, Self_iterator& v2_ref, int num)
|
||||||
int num)
|
|
||||||
{
|
{
|
||||||
(*v1_ref).second.insert_prev((*v2_ref).first, num);
|
(*v1_ref).second.insert_prev((*v2_ref).first, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool polygons_overlap()
|
private :
|
||||||
{
|
|
||||||
Self_iterator v_it;
|
|
||||||
for (v_it = this->begin(); v_it != this->end(); v_it++)
|
|
||||||
{
|
|
||||||
if ((*v_it).second.edges_overlap((*v_it).first)) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class OutputIterator>
|
Map m_map ;
|
||||||
OutputIterator union_vertices(OutputIterator result)
|
|
||||||
{
|
|
||||||
if (this->empty()) return result;
|
|
||||||
|
|
||||||
Self_iterator m_it = this->begin();
|
|
||||||
Vertex_iterator v_it;
|
|
||||||
Vertex_iterator first_v_it;
|
|
||||||
Vertex_iterator prev_v_it;
|
|
||||||
Vertex_iterator next_v_it;
|
|
||||||
|
|
||||||
// find a vertex with degree 2 (there must be at least one)
|
|
||||||
while (m_it != this->end() && (*m_it).second.size() != 2)
|
|
||||||
m_it++;
|
|
||||||
CGAL_assertion (m_it != this->end());
|
|
||||||
|
|
||||||
// insert this vertex and the two around it
|
|
||||||
first_v_it = prev_v_it = (*(*m_it).second.begin()).endpoint();
|
|
||||||
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
|
||||||
std::cout << "union_vertices: inserting " << (*prev_v_it) << std::endl;
|
|
||||||
#endif
|
|
||||||
*result = *prev_v_it;
|
|
||||||
result++;
|
|
||||||
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
|
||||||
std::cout << "union_vertices: inserting "<< *(*m_it).first << std::endl;
|
|
||||||
#endif
|
|
||||||
*result = *(*m_it).first;
|
|
||||||
result++;
|
|
||||||
next_v_it = (*m_it).second.back().endpoint();
|
|
||||||
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
|
||||||
std::cout << "union_vertices: inserting " << *next_v_it << std::endl;
|
|
||||||
#endif
|
|
||||||
*result = *next_v_it;
|
|
||||||
result++;
|
|
||||||
|
|
||||||
// find the map iterator corresponding to the next vertex
|
|
||||||
prev_v_it = (*m_it).first;
|
|
||||||
v_it = next_v_it;
|
|
||||||
m_it = this->find(v_it);
|
|
||||||
|
|
||||||
while (v_it != first_v_it && m_it != this->end())
|
|
||||||
{
|
|
||||||
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
|
||||||
std::cout << "union_vertices: prev_v_it " << (*prev_v_it)
|
|
||||||
<< " v_it " << (*v_it) << " next_v_it "
|
|
||||||
<< (*next_v_it) << std::endl;
|
|
||||||
#endif
|
|
||||||
// Don't want to sort the edges for vertices of degree 2 because they
|
|
||||||
// are already in CCW order (since the partition polygons were in CCW
|
|
||||||
// order), and this is what you need to begin the construction
|
|
||||||
// of the union polygon.
|
|
||||||
if ((*m_it).second.size() > 2){
|
|
||||||
|
|
||||||
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
|
||||||
cw_indirect_edge_info_compare =
|
|
||||||
CW_indirect_edge_info_compare<Vertex_iterator,Traits>((*m_it).first);
|
|
||||||
(*m_it).second.sort(&Self::compare);
|
|
||||||
#else
|
|
||||||
(*m_it).second.sort(
|
|
||||||
CW_indirect_edge_info_compare<Vertex_iterator,Traits>((*m_it).first));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the previous vertex in this vertex's list
|
|
||||||
next_v_it=(*m_it).second.next_ccw_edge_info(prev_v_it).endpoint();
|
|
||||||
if (next_v_it != first_v_it)
|
|
||||||
{
|
|
||||||
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
|
||||||
std::cout << "union_vertices: inserting "
|
|
||||||
<< *next_v_it << std::endl;
|
|
||||||
#endif
|
|
||||||
*result = *next_v_it;
|
|
||||||
result++;
|
|
||||||
}
|
|
||||||
prev_v_it = v_it;
|
|
||||||
v_it = next_v_it;
|
|
||||||
m_it = this->find(v_it);
|
|
||||||
CGAL_assertion (m_it == this->end() || (*m_it).first == v_it);
|
|
||||||
}
|
|
||||||
#ifdef CGAL_PARTITION_CHECK_DEBUG
|
|
||||||
if (v_it == first_v_it)
|
|
||||||
std::cout << "union_vertices: stopped because first was reached "
|
|
||||||
<< std::endl;
|
|
||||||
else
|
|
||||||
std::cout << "union_vertices: stopped because end was reached "
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
#ifdef CGAL_CFG_RWSTD_NO_MEMBER_TEMPLATES
|
||||||
template <class Traits>
|
template <class Traits>
|
||||||
CW_indirect_edge_info_compare<typename Traits::Polygon_2::Vertex_iterator,
|
CW_indirect_edge_info_compare<Traits>
|
||||||
Traits>
|
|
||||||
Partition_vertex_map<Traits>::cw_indirect_edge_info_compare;
|
Partition_vertex_map<Traits>::cw_indirect_edge_info_compare;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue