mirror of https://github.com/CGAL/cgal
Fixed TDS graph traits implementation and factorized some parts with other T2 GT
This commit is contained in:
parent
64d7747f8b
commit
9cba48acfe
|
|
@ -54,6 +54,7 @@
|
||||||
#include <CGAL/internal/Exact_type_selector.h>
|
#include <CGAL/internal/Exact_type_selector.h>
|
||||||
#include <CGAL/boost/graph/copy_face_graph.h>
|
#include <CGAL/boost/graph/copy_face_graph.h>
|
||||||
#include <CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h>
|
#include <CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h>
|
||||||
|
#include <CGAL/boost/graph/properties_Triangulation_data_structure_2.h>
|
||||||
#include <CGAL/Polyhedron_3_fwd.h>
|
#include <CGAL/Polyhedron_3_fwd.h>
|
||||||
#include <CGAL/boost/graph/Euler_operations.h>
|
#include <CGAL/boost/graph/Euler_operations.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,271 +25,21 @@
|
||||||
|
|
||||||
// include this to avoid a VC15 warning
|
// include this to avoid a VC15 warning
|
||||||
#include <CGAL/boost/graph/named_function_params.h>
|
#include <CGAL/boost/graph/named_function_params.h>
|
||||||
|
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h>
|
||||||
|
|
||||||
|
#include <CGAL/Triangulation_data_structure_2.h>
|
||||||
|
#include <CGAL/Iterator_range.h>
|
||||||
|
#include <CGAL/iterator.h>
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/iterator_adaptors.hpp>
|
#include <boost/iterator_adaptors.hpp>
|
||||||
#include <boost/graph/graph_traits.hpp>
|
#include <boost/graph/graph_traits.hpp>
|
||||||
#include <boost/graph/properties.hpp>
|
#include <boost/graph/properties.hpp>
|
||||||
|
|
||||||
#include <CGAL/Triangulation_data_structure_2.h>
|
|
||||||
#include <CGAL/Iterator_range.h>
|
|
||||||
#include <CGAL/iterator.h>
|
|
||||||
|
|
||||||
// The functions and classes in this file allows the user to
|
// The functions and classes in this file allows the user to
|
||||||
// treat a CGAL Triangulation_data_structure_2 object as a boost graph "as is". No
|
// treat a CGAL Triangulation_data_structure_2 object as a boost graph "as is". No
|
||||||
// wrapper is needed for the Triangulation_data_structure_2 object.
|
// wrapper is needed for the Triangulation_data_structure_2 object.
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
// A TDS edge is a face handle + an int, and is thus actually a halfedge...
|
|
||||||
template <class TDS>
|
|
||||||
struct TDS2_halfedge_descriptor
|
|
||||||
: public TDS::Edge
|
|
||||||
{
|
|
||||||
typedef typename TDS::Edge Base;
|
|
||||||
typedef typename TDS::Face_handle Face_handle;
|
|
||||||
|
|
||||||
TDS2_halfedge_descriptor() {}
|
|
||||||
TDS2_halfedge_descriptor(Face_handle fh, int i) : Base(fh, i) { }
|
|
||||||
explicit TDS2_halfedge_descriptor(const Base& e) : Base(e) { }
|
|
||||||
TDS2_halfedge_descriptor(const TDS2_halfedge_descriptor& h) : Base(h) { }
|
|
||||||
|
|
||||||
const Base& base() const { return static_cast<const Base&>(*this); }
|
|
||||||
|
|
||||||
TDS2_halfedge_descriptor& operator=(const TDS2_halfedge_descriptor& h)
|
|
||||||
{
|
|
||||||
this->first = h.first;
|
|
||||||
this->second = h.second;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend std::size_t hash_value(const TDS2_halfedge_descriptor& e) {
|
|
||||||
return hash_value(e.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const TDS2_halfedge_descriptor& other) const {
|
|
||||||
return (this->first == other.first) && (this->second == other.second);
|
|
||||||
}
|
|
||||||
bool operator!=(const TDS2_halfedge_descriptor& other) const {
|
|
||||||
return (this->first != other.first) || (this->second != other.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator<(const TDS2_halfedge_descriptor& other) const
|
|
||||||
{
|
|
||||||
if(this->first < other.first) return true;
|
|
||||||
if(this->first > other.first) return false;
|
|
||||||
return this->second < other.second;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// An edge is just a halfedge, but we give it a complete structure to distinguish it from TDS::Edge
|
|
||||||
template <typename TDS>
|
|
||||||
struct TDS2_edge_descriptor
|
|
||||||
{
|
|
||||||
typedef typename TDS::Face_handle Face_handle;
|
|
||||||
|
|
||||||
TDS2_edge_descriptor() : first(), second(0) { }
|
|
||||||
explicit TDS2_edge_descriptor(const typename TDS::Edge& e) : first(e.first), second(e.second) { }
|
|
||||||
TDS2_edge_descriptor(Face_handle fd, int i) : first(fd), second(i) { }
|
|
||||||
|
|
||||||
// so that we can still do stuff like tr.is_finite(edge_descriptor) without any hassle
|
|
||||||
operator std::pair<Face_handle, int>() { return std::make_pair(first, second); }
|
|
||||||
|
|
||||||
friend std::size_t hash_value(const TDS2_edge_descriptor& h)
|
|
||||||
{
|
|
||||||
if(h.first == Face_handle())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return hash_value(h.first < h.first->neighbor(h.second) ? h.first
|
|
||||||
: h.first->neighbor(h.second));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const TDS2_edge_descriptor& other) const
|
|
||||||
{
|
|
||||||
if((first == other.first) && (second == other.second))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
Face_handle fh = first->neighbor(second);
|
|
||||||
if(other.first != fh)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int i = fh->index(first);
|
|
||||||
return (other.second == i);
|
|
||||||
}
|
|
||||||
bool operator!=(TDS2_edge_descriptor& other) const { return ! (*this == other); }
|
|
||||||
|
|
||||||
Face_handle first;
|
|
||||||
int second;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A halfedge iterator is just an edge iterator that duplicates everything twice,
|
|
||||||
// to see the edge from either side.
|
|
||||||
// Could probably be factorized with T2_edge_iterator, but it's clearer this way.
|
|
||||||
template <typename TDS>
|
|
||||||
struct TDS2_halfedge_iterator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef TDS2_halfedge_iterator<TDS> Self;
|
|
||||||
typedef typename TDS::Edge_iterator Edge_iterator;
|
|
||||||
typedef TDS2_halfedge_descriptor<TDS> Descriptor;
|
|
||||||
typedef typename TDS::Face_handle Face_handle;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef Descriptor value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef std::bidirectional_iterator_tag iterator_category;
|
|
||||||
|
|
||||||
TDS2_halfedge_iterator() { }
|
|
||||||
TDS2_halfedge_iterator(const Edge_iterator& feit) : it(feit), on_adjacent_face(false) { }
|
|
||||||
|
|
||||||
Self& operator++()
|
|
||||||
{
|
|
||||||
// If we are on the first face, move to the opposite face. If we are already on the opposite face,
|
|
||||||
// then it's time to move on the next edge
|
|
||||||
if(on_adjacent_face) {
|
|
||||||
++it;
|
|
||||||
on_adjacent_face = false;
|
|
||||||
} else {
|
|
||||||
on_adjacent_face = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Self& operator--()
|
|
||||||
{
|
|
||||||
// Note that while decreasing, we start from the opposite face
|
|
||||||
if(on_adjacent_face) {
|
|
||||||
on_adjacent_face = false;
|
|
||||||
} else {
|
|
||||||
--it;
|
|
||||||
on_adjacent_face = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Self operator++(int) { Self tmp = *this; operator++(); return tmp; }
|
|
||||||
Self operator--(int) { Self tmp = *this; operator--(); return tmp; }
|
|
||||||
|
|
||||||
bool operator==(const Self& other) const { return it == other.it; }
|
|
||||||
bool operator!=(const Self& other) const { return !(*this == other); }
|
|
||||||
|
|
||||||
value_type operator*() const
|
|
||||||
{
|
|
||||||
if(on_adjacent_face) {
|
|
||||||
Face_handle neigh_f = it->first->neighbor(it->second);
|
|
||||||
return value_type(neigh_f, neigh_f->index(it->first));
|
|
||||||
} else {
|
|
||||||
return value_type(*it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Edge_iterator it;
|
|
||||||
bool on_adjacent_face;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TDS>
|
|
||||||
struct TDS2_edge_iterator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef TDS2_edge_iterator<TDS> Self;
|
|
||||||
typedef typename TDS::Edge_iterator Edge_iterator;
|
|
||||||
typedef TDS2_edge_descriptor<TDS> Descriptor;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef Descriptor value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef std::bidirectional_iterator_tag iterator_category;
|
|
||||||
|
|
||||||
TDS2_edge_iterator() { }
|
|
||||||
TDS2_edge_iterator(const Edge_iterator& feit) : it(feit) { }
|
|
||||||
|
|
||||||
bool operator==(const Self& other) const { return it == other.it; }
|
|
||||||
bool operator!=(const Self& other) const { return !(*this == other); }
|
|
||||||
Self& operator++() { ++it; return *this; }
|
|
||||||
Self& operator--() { --it; return *this; }
|
|
||||||
Self operator++(int) { Self tmp = *this; operator++(); return tmp; }
|
|
||||||
Self operator--(int) { Self tmp = *this; operator--(); return tmp; }
|
|
||||||
value_type operator*() const { return value_type(*it); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Edge_iterator it;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Circ, class E>
|
|
||||||
class TDS2_Out_edge_circulator
|
|
||||||
: public Circ
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
mutable E e;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef E value_type;
|
|
||||||
typedef E* pointer;
|
|
||||||
typedef E& reference;
|
|
||||||
|
|
||||||
TDS2_Out_edge_circulator() : Circ() {}
|
|
||||||
TDS2_Out_edge_circulator(Circ c) : Circ(c) {}
|
|
||||||
|
|
||||||
const E& operator*() const
|
|
||||||
{
|
|
||||||
E ed = static_cast<const Circ*>(this)->operator*();
|
|
||||||
e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first));
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Circ, class E>
|
|
||||||
class TDS2_In_edge_circulator
|
|
||||||
: public Circ
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
mutable E e;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef E value_type;
|
|
||||||
typedef E* pointer;
|
|
||||||
typedef E& reference;
|
|
||||||
|
|
||||||
TDS2_In_edge_circulator() : Circ() {}
|
|
||||||
TDS2_In_edge_circulator(Circ c) : Circ(c) {}
|
|
||||||
|
|
||||||
const E& operator*() const
|
|
||||||
{
|
|
||||||
typename Circ::value_type ed = static_cast<const Circ*>(this)->operator*();
|
|
||||||
e = E(ed);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
} // namespace CGAL
|
|
||||||
|
|
||||||
namespace std{
|
|
||||||
|
|
||||||
// workaround a bug detected on at least g++ 4.4 where boost::next(Iterator)
|
|
||||||
// is picked as a candidate for next(h,g)
|
|
||||||
template <typename TDS>
|
|
||||||
struct iterator_traits< CGAL::detail::TDS2_halfedge_descriptor<TDS> >
|
|
||||||
{
|
|
||||||
typedef void* iterator_category;
|
|
||||||
typedef void* difference_type;
|
|
||||||
typedef void* value_type;
|
|
||||||
typedef void* reference;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end of namespace std
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template <class VB, class FB>
|
template <class VB, class FB>
|
||||||
|
|
@ -304,17 +54,19 @@ struct graph_traits<CGAL::Triangulation_data_structure_2<VB, FB> >
|
||||||
typedef CGAL::Triangulation_data_structure_2<VB,FB> Triangulation_data_structure;
|
typedef CGAL::Triangulation_data_structure_2<VB,FB> Triangulation_data_structure;
|
||||||
|
|
||||||
typedef typename Triangulation_data_structure::Vertex_handle vertex_descriptor;
|
typedef typename Triangulation_data_structure::Vertex_handle vertex_descriptor;
|
||||||
typedef CGAL::detail::TDS2_halfedge_descriptor<Triangulation_data_structure> halfedge_descriptor;
|
typedef CGAL::internal::T2_halfedge_descriptor<Triangulation_data_structure> halfedge_descriptor;
|
||||||
typedef CGAL::detail::TDS2_edge_descriptor<Triangulation_data_structure> edge_descriptor;
|
typedef CGAL::internal::T2_edge_descriptor<Triangulation_data_structure> edge_descriptor;
|
||||||
typedef typename Triangulation_data_structure::Face_handle face_descriptor;
|
typedef typename Triangulation_data_structure::Face_handle face_descriptor;
|
||||||
|
|
||||||
typedef CGAL::Prevent_deref<typename Triangulation_data_structure::Vertex_iterator> vertex_iterator;
|
typedef CGAL::Prevent_deref<typename Triangulation_data_structure::Vertex_iterator> vertex_iterator;
|
||||||
typedef CGAL::detail::TDS2_halfedge_iterator<Triangulation_data_structure> halfedge_iterator;
|
typedef CGAL::internal::T2_halfedge_iterator<Triangulation_data_structure,
|
||||||
typedef CGAL::detail::TDS2_edge_iterator<Triangulation_data_structure> edge_iterator;
|
typename Triangulation_data_structure::Edge_iterator> halfedge_iterator;
|
||||||
|
typedef CGAL::internal::T2_edge_iterator<Triangulation_data_structure,
|
||||||
|
typename Triangulation_data_structure::Edge_iterator> edge_iterator;
|
||||||
typedef CGAL::Prevent_deref<typename Triangulation_data_structure::Face_iterator> face_iterator;
|
typedef CGAL::Prevent_deref<typename Triangulation_data_structure::Face_iterator> face_iterator;
|
||||||
|
|
||||||
typedef CGAL::Counting_iterator<CGAL::detail::TDS2_Out_edge_circulator<typename Triangulation_data_structure::Edge_circulator, edge_descriptor>, edge_descriptor > out_edge_iterator;
|
typedef CGAL::Counting_iterator<CGAL::internal::TDS2_Out_edge_circulator<typename Triangulation_data_structure::Edge_circulator, edge_descriptor>, edge_descriptor > out_edge_iterator;
|
||||||
typedef CGAL::Counting_iterator<CGAL::detail::TDS2_In_edge_circulator<typename Triangulation_data_structure::Edge_circulator, edge_descriptor>, edge_descriptor > in_edge_iterator;
|
typedef CGAL::Counting_iterator<CGAL::internal::TDS2_In_edge_circulator<typename Triangulation_data_structure::Edge_circulator, edge_descriptor>, edge_descriptor > in_edge_iterator;
|
||||||
typedef CGAL::Counting_iterator<typename Triangulation_data_structure::Vertex_circulator> Incident_vertices_iterator;
|
typedef CGAL::Counting_iterator<typename Triangulation_data_structure::Vertex_circulator> Incident_vertices_iterator;
|
||||||
typedef Incident_vertices_iterator adjacency_iterator;
|
typedef Incident_vertices_iterator adjacency_iterator;
|
||||||
|
|
||||||
|
|
@ -335,6 +87,11 @@ struct graph_traits<CGAL::Triangulation_data_structure_2<VB, FB> >
|
||||||
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
|
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
struct graph_traits<const CGAL::Triangulation_data_structure_2<VB, FB> >
|
||||||
|
: public graph_traits< CGAL::Triangulation_data_structure_2<VB, FB> >
|
||||||
|
{ };
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -585,238 +342,6 @@ degree(typename boost::graph_traits< Triangulation_data_structure_2<VB,FB> >::ve
|
||||||
return deg;
|
return deg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// property maps
|
|
||||||
template <class VB, class FB>
|
|
||||||
class TDS2_vertex_id_map
|
|
||||||
: public boost::put_get_helper<int, TDS2_vertex_id_map<VB,FB> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef boost::readable_property_map_tag category;
|
|
||||||
typedef int value_type;
|
|
||||||
typedef int reference;
|
|
||||||
typedef typename CGAL::Triangulation_data_structure_2<VB,FB>::Vertex_handle key_type;
|
|
||||||
|
|
||||||
TDS2_vertex_id_map() {}
|
|
||||||
|
|
||||||
long operator[](key_type vh) const { return vh->id(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class VB, class FB>
|
|
||||||
class TDS2_vertex_point_map
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef boost::lvalue_property_map_tag category;
|
|
||||||
typedef typename VB::Point value_type;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef typename CGAL::Triangulation_data_structure_2<VB,FB>::Vertex_handle key_type;
|
|
||||||
|
|
||||||
friend reference get(TDS2_vertex_point_map<VB,FB>, key_type vh) { return vh->point(); }
|
|
||||||
friend void put(TDS2_vertex_point_map<VB,FB>, key_type vh, reference v) { vh->point() = v; }
|
|
||||||
reference operator[](key_type vh) const { return vh->point(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class VB, class FB>
|
|
||||||
class TDS2_edge_id_map
|
|
||||||
: public boost::put_get_helper<int, TDS2_edge_id_map<VB,FB> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef boost::readable_property_map_tag category;
|
|
||||||
typedef int value_type;
|
|
||||||
typedef int reference;
|
|
||||||
typedef typename CGAL::Triangulation_data_structure_2<VB,FB>::Edge key_type;
|
|
||||||
|
|
||||||
TDS2_edge_id_map() {}
|
|
||||||
|
|
||||||
long operator[](key_type e) const { return (3 * e.first.id()) + e.second; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class VB, class FB>
|
|
||||||
class TDS2_edge_weight_map
|
|
||||||
: public boost::put_get_helper<typename VB::FT, TDS2_edge_weight_map<VB, FB> >
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
const CGAL::Triangulation_data_structure_2<VB,FB>& tr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef boost::readable_property_map_tag category;
|
|
||||||
typedef typename VB::FT value_type;
|
|
||||||
typedef value_type reference;
|
|
||||||
typedef typename CGAL::Triangulation_data_structure_2<VB,FB>::Edge key_type;
|
|
||||||
|
|
||||||
TDS2_edge_weight_map(const CGAL::Triangulation_data_structure_2<VB,FB>& tr_) : tr(tr_) { }
|
|
||||||
|
|
||||||
value_type operator[](key_type e) const { return approximate_sqrt(tr.segment(e).squared_length()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class VB, class FB>
|
|
||||||
inline TDS2_vertex_id_map<VB,FB>
|
|
||||||
get(boost::vertex_index_t, const Triangulation_data_structure_2<VB,FB>&)
|
|
||||||
{
|
|
||||||
TDS2_vertex_id_map<VB,FB> m;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class VB, class FB>
|
|
||||||
inline TDS2_vertex_point_map<VB,FB>
|
|
||||||
get(boost::vertex_point_t, const Triangulation_data_structure_2<VB,FB>&)
|
|
||||||
{
|
|
||||||
TDS2_vertex_point_map<VB,FB> m;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class VB, class FB>
|
|
||||||
inline TDS2_edge_id_map<VB,FB>
|
|
||||||
get(boost::edge_index_t, const Triangulation_data_structure_2<VB,FB>&)
|
|
||||||
{
|
|
||||||
TDS2_edge_id_map<VB,FB> m;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class VB, class FB>
|
|
||||||
inline TDS2_edge_weight_map<VB,FB>
|
|
||||||
get(boost::edge_weight_t, const Triangulation_data_structure_2<VB,FB>& g)
|
|
||||||
{
|
|
||||||
TDS2_edge_weight_map<VB,FB> m(g);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Tag>
|
|
||||||
struct TDS2_property_map { };
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TDS2_property_map<boost::vertex_index_t>
|
|
||||||
{
|
|
||||||
template <class VB, class FB>
|
|
||||||
struct bind_ {
|
|
||||||
typedef TDS2_vertex_id_map<VB,FB> type;
|
|
||||||
typedef TDS2_vertex_id_map<VB,FB> const_type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TDS2_property_map<boost::vertex_point_t>
|
|
||||||
{
|
|
||||||
template <class VB, class FB>
|
|
||||||
struct bind_ {
|
|
||||||
typedef TDS2_vertex_point_map<VB,FB> type;
|
|
||||||
typedef TDS2_vertex_point_map<VB,FB> const_type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TDS2_property_map<boost::edge_index_t>
|
|
||||||
{
|
|
||||||
template <class VB, class FB>
|
|
||||||
struct bind_ {
|
|
||||||
typedef TDS2_edge_id_map<VB,FB> type;
|
|
||||||
typedef TDS2_edge_id_map<VB,FB> const_type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct TDS2_property_map<boost::edge_weight_t>
|
|
||||||
{
|
|
||||||
template <class VB, class FB>
|
|
||||||
struct bind_ {
|
|
||||||
typedef TDS2_edge_weight_map<VB,FB> type;
|
|
||||||
typedef TDS2_edge_weight_map<VB,FB> const_type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
// g++ 'enumeral_type' in template unification not implemented workaround
|
|
||||||
template <class VB, class FB, class Tag>
|
|
||||||
struct property_map<CGAL::Triangulation_data_structure_2<VB,FB>, Tag>
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
CGAL::TDS2_property_map<Tag>::template bind_<VB,FB> map_gen;
|
|
||||||
typedef typename map_gen::type type;
|
|
||||||
typedef typename map_gen::const_type const_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// see struct property_map in Polyehdron for an explanation
|
|
||||||
template <class VB, class FB, class Tag>
|
|
||||||
struct property_map<const CGAL::Triangulation_data_structure_2<VB,FB>, Tag>
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
CGAL::TDS2_property_map<Tag>::template bind_<VB,FB> map_gen;
|
|
||||||
typedef typename map_gen::type type;
|
|
||||||
typedef typename map_gen::const_type const_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
template <class VB, class FB, class PropertyTag, class Key>
|
|
||||||
inline
|
|
||||||
typename boost::property_traits<
|
|
||||||
typename boost::property_map<Triangulation_data_structure_2<VB,FB>,PropertyTag>::const_type>::value_type
|
|
||||||
get(PropertyTag p, const Triangulation_data_structure_2<VB,FB>& g, const Key& key)
|
|
||||||
{
|
|
||||||
return get(get(p, g), key);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class VB, class FB, class PropertyTag, class Key,class Value>
|
|
||||||
inline void
|
|
||||||
put(PropertyTag p, Triangulation_data_structure_2<VB,FB>& g,
|
|
||||||
const Key& key, const Value& value)
|
|
||||||
{
|
|
||||||
typedef typename boost::property_map<Triangulation_data_structure_2<VB,FB>, PropertyTag>::type Map;
|
|
||||||
Map pmap = get(p, g);
|
|
||||||
put(pmap, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace CGAL
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
// What are those needed for ???
|
|
||||||
template <typename VB, typename FB>
|
|
||||||
struct edge_property_type<CGAL::Triangulation_data_structure_2<VB,FB> > {
|
|
||||||
typedef void type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename VB, typename FB>
|
|
||||||
struct vertex_property_type<CGAL::Triangulation_data_structure_2<VB,FB> > {
|
|
||||||
typedef void type;
|
|
||||||
};
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
# pragma warning(push)
|
|
||||||
# pragma warning(disable:4099) // For VC10 it is class hash
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CGAL_CFG_NO_STD_HASH
|
|
||||||
|
|
||||||
template <typename TDS>
|
|
||||||
struct hash<CGAL::detail::TDS2_edge_descriptor<TDS> >
|
|
||||||
{
|
|
||||||
std::size_t operator()(const CGAL::detail::TDS2_edge_descriptor<TDS>& e) const { return hash_value(e); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TDS>
|
|
||||||
struct hash<CGAL::detail::TDS2_halfedge_descriptor<TDS> >
|
|
||||||
{
|
|
||||||
std::size_t operator()(const CGAL::detail::TDS2_halfedge_descriptor<TDS>& e) const { return hash_value(e); }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CGAL_CFG_NO_STD_HASH
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
# pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
#endif // CGAL_GRAPH_TRAITS_TRIANGULATION_DATA_STRUCTURE_2_H
|
#endif // CGAL_GRAPH_TRAITS_TRIANGULATION_DATA_STRUCTURE_2_H
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@
|
||||||
#error CGAL_2D_TRIANGULATION_TEMPLATES is not defined
|
#error CGAL_2D_TRIANGULATION_TEMPLATES is not defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h>
|
||||||
|
|
||||||
#include <CGAL/Iterator_range.h>
|
#include <CGAL/Iterator_range.h>
|
||||||
#include <CGAL/iterator.h>
|
#include <CGAL/iterator.h>
|
||||||
#include <CGAL/use.h>
|
#include <CGAL/use.h>
|
||||||
|
|
@ -41,367 +43,6 @@
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
// Small include guard for helper classes
|
|
||||||
#ifndef CGAL_GRAPH_TRAITS_2D_TRIANGULATION
|
|
||||||
#define CGAL_GRAPH_TRAITS_2D_TRIANGULATION
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
// A triangulation edge is a face handle + an int, and is thus actually a halfedge...
|
|
||||||
template <class Tr>
|
|
||||||
struct T2_halfedge_descriptor
|
|
||||||
: public Tr::Edge
|
|
||||||
{
|
|
||||||
typedef typename Tr::Edge Base;
|
|
||||||
typedef typename Tr::Face_handle Face_handle;
|
|
||||||
|
|
||||||
T2_halfedge_descriptor() {}
|
|
||||||
T2_halfedge_descriptor(Face_handle fh, int i) : Base(fh, i) { }
|
|
||||||
explicit T2_halfedge_descriptor(const Base& e) : Base(e) { }
|
|
||||||
T2_halfedge_descriptor(const T2_halfedge_descriptor& h) : Base(h) { }
|
|
||||||
|
|
||||||
const Base& base() const { return static_cast<const Base&>(*this); }
|
|
||||||
|
|
||||||
T2_halfedge_descriptor& operator=(const T2_halfedge_descriptor& h)
|
|
||||||
{
|
|
||||||
this->first = h.first;
|
|
||||||
this->second = h.second;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend std::size_t hash_value(const T2_halfedge_descriptor& e) {
|
|
||||||
return hash_value(e.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const T2_halfedge_descriptor& other) const {
|
|
||||||
return (this->first == other.first) && (this->second == other.second);
|
|
||||||
}
|
|
||||||
bool operator!=(const T2_halfedge_descriptor& other) const {
|
|
||||||
return (this->first != other.first) || (this->second != other.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator<(const T2_halfedge_descriptor& other) const
|
|
||||||
{
|
|
||||||
if(this->first < other.first) return true;
|
|
||||||
if(this->first > other.first) return false;
|
|
||||||
return this->second < other.second;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// An edge is just a halfedge, but we give it a complete structure to distinguish it from Tr::Edge
|
|
||||||
template <typename Tr>
|
|
||||||
struct T2_edge_descriptor
|
|
||||||
{
|
|
||||||
typedef typename Tr::Face_handle Face_handle;
|
|
||||||
|
|
||||||
T2_edge_descriptor() : first(), second(0) { }
|
|
||||||
explicit T2_edge_descriptor(const typename Tr::Edge& e) : first(e.first), second(e.second) { }
|
|
||||||
T2_edge_descriptor(Face_handle fd, int i) : first(fd), second(i) { }
|
|
||||||
|
|
||||||
// so that we can still do stuff like tr.is_finite(edge_descriptor) without any hassle
|
|
||||||
operator std::pair<Face_handle, int>() { return std::make_pair(first, second); }
|
|
||||||
|
|
||||||
friend std::size_t hash_value(const T2_edge_descriptor& h)
|
|
||||||
{
|
|
||||||
if(h.first == Face_handle())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return hash_value(h.first < h.first->neighbor(h.second) ? h.first
|
|
||||||
: h.first->neighbor(h.second));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const T2_edge_descriptor& other) const
|
|
||||||
{
|
|
||||||
if((first == other.first) && (second == other.second))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
Face_handle fh = first->neighbor(second);
|
|
||||||
if(other.first != fh)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int i = fh->index(first);
|
|
||||||
return (other.second == i);
|
|
||||||
}
|
|
||||||
bool operator!=(T2_edge_descriptor& other) const { return ! (*this == other); }
|
|
||||||
|
|
||||||
Face_handle first;
|
|
||||||
int second;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A halfedge iterator is just an edge iterator that duplicates everything twice,
|
|
||||||
// to see the edge from either side.
|
|
||||||
// Could probably be factorized with T2_edge_iterator, but it's clearer this way.
|
|
||||||
template <typename Tr>
|
|
||||||
struct T2_halfedge_iterator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef T2_halfedge_iterator<Tr> Self;
|
|
||||||
typedef typename Tr::Finite_edges_iterator Finite_edges_iterator;
|
|
||||||
typedef T2_halfedge_descriptor<Tr> Descriptor;
|
|
||||||
typedef typename Tr::Face_handle Face_handle;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef Descriptor value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef std::bidirectional_iterator_tag iterator_category;
|
|
||||||
|
|
||||||
T2_halfedge_iterator() { }
|
|
||||||
T2_halfedge_iterator(const Finite_edges_iterator& feit) : it(feit), on_adjacent_face(false) { }
|
|
||||||
|
|
||||||
Self& operator++()
|
|
||||||
{
|
|
||||||
// If we are on the first face, move to the opposite face. If we are already on the opposite face,
|
|
||||||
// then it's time to move on the next edge
|
|
||||||
if(on_adjacent_face) {
|
|
||||||
++it;
|
|
||||||
on_adjacent_face = false;
|
|
||||||
} else {
|
|
||||||
on_adjacent_face = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Self& operator--()
|
|
||||||
{
|
|
||||||
// Note that while decreasing, we start from the opposite face
|
|
||||||
if(on_adjacent_face) {
|
|
||||||
on_adjacent_face = false;
|
|
||||||
} else {
|
|
||||||
--it;
|
|
||||||
on_adjacent_face = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Self operator++(int) { Self tmp = *this; operator++(); return tmp; }
|
|
||||||
Self operator--(int) { Self tmp = *this; operator--(); return tmp; }
|
|
||||||
|
|
||||||
bool operator==(const Self& other) const { return it == other.it; }
|
|
||||||
bool operator!=(const Self& other) const { return !(*this == other); }
|
|
||||||
|
|
||||||
value_type operator*() const
|
|
||||||
{
|
|
||||||
if(on_adjacent_face) {
|
|
||||||
Face_handle neigh_f = it->first->neighbor(it->second);
|
|
||||||
return value_type(neigh_f, neigh_f->index(it->first));
|
|
||||||
} else {
|
|
||||||
return value_type(*it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Finite_edges_iterator it;
|
|
||||||
bool on_adjacent_face;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Tr>
|
|
||||||
struct T2_edge_iterator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef T2_edge_iterator<Tr> Self;
|
|
||||||
typedef typename Tr::Finite_edges_iterator Finite_edges_iterator;
|
|
||||||
typedef T2_edge_descriptor<Tr> Descriptor;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef Descriptor value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef std::bidirectional_iterator_tag iterator_category;
|
|
||||||
|
|
||||||
T2_edge_iterator() { }
|
|
||||||
T2_edge_iterator(const Finite_edges_iterator& feit) : it(feit) { }
|
|
||||||
|
|
||||||
bool operator==(const Self& other) const { return it == other.it; }
|
|
||||||
bool operator!=(const Self& other) const { return !(*this == other); }
|
|
||||||
Self& operator++() { ++it; return *this; }
|
|
||||||
Self& operator--() { --it; return *this; }
|
|
||||||
Self operator++(int) { Self tmp = *this; operator++(); return tmp; }
|
|
||||||
Self operator--(int) { Self tmp = *this; operator--(); return tmp; }
|
|
||||||
value_type operator*() const { return value_type(*it); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Finite_edges_iterator it;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Tr>
|
|
||||||
struct T2_edge_circulator
|
|
||||||
: public Tr::Edge_circulator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef T2_edge_circulator<Tr> Self;
|
|
||||||
typedef typename Tr::Edge Edge;
|
|
||||||
typedef typename Tr::Edge_circulator Base;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef T2_edge_descriptor<Tr> value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
|
|
||||||
T2_edge_circulator() : Base() { }
|
|
||||||
T2_edge_circulator(const Base& c, const Tr& tr) : Base(c), tr(&tr), e() { }
|
|
||||||
|
|
||||||
// Note that the inf check is on the edge in the circulator, not on 'e', which isn't built yet
|
|
||||||
Self& operator++() {
|
|
||||||
do { this->Base::operator++(); } while(tr->is_infinite(this->Base::operator*()));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Self& operator--() {
|
|
||||||
do { this->Base::operator--(); } while(tr->is_infinite(this->Base::operator*()));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
|
|
||||||
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const Tr* tr;
|
|
||||||
mutable value_type e;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Tr>
|
|
||||||
struct In_edge_circulator
|
|
||||||
: public T2_edge_circulator<Tr>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef T2_edge_circulator<Tr> Base;
|
|
||||||
typedef typename Tr::Edge Edge;
|
|
||||||
typedef typename Tr::Edge_circulator Edge_circulator;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef T2_edge_descriptor<Tr> value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
|
|
||||||
In_edge_circulator() : Base() { }
|
|
||||||
In_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { }
|
|
||||||
|
|
||||||
const value_type& operator*() const
|
|
||||||
{
|
|
||||||
this->e = value_type(this->Base::operator*());
|
|
||||||
return this->e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Tr>
|
|
||||||
struct Out_edge_circulator
|
|
||||||
: public T2_edge_circulator<Tr>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef T2_edge_circulator<Tr> Base;
|
|
||||||
typedef typename Tr::Edge Edge;
|
|
||||||
typedef typename Tr::Edge_circulator Edge_circulator;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef T2_edge_descriptor<Tr> value_type;
|
|
||||||
typedef value_type* pointer;
|
|
||||||
typedef value_type& reference;
|
|
||||||
|
|
||||||
Out_edge_circulator() : Base() { }
|
|
||||||
Out_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { }
|
|
||||||
|
|
||||||
const value_type& operator*() const
|
|
||||||
{
|
|
||||||
Edge ed(this->Base::operator*());
|
|
||||||
this->e = value_type(ed.first->neighbor(ed.second),
|
|
||||||
ed.first->neighbor(ed.second)->index(ed.first));
|
|
||||||
return this->e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Tr>
|
|
||||||
struct T2_vertex_circulator
|
|
||||||
: public In_edge_circulator<Tr>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef In_edge_circulator<Tr> Base;
|
|
||||||
typedef T2_edge_descriptor<Tr> edge_descriptor;
|
|
||||||
typedef typename Tr::Edge_circulator Edge_circulator;
|
|
||||||
typedef typename Tr::Vertex_handle Vertex_handle;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef Vertex_handle value_type;
|
|
||||||
typedef value_type& reference;
|
|
||||||
|
|
||||||
T2_vertex_circulator() : Base() { }
|
|
||||||
T2_vertex_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { }
|
|
||||||
|
|
||||||
const value_type& operator*() const
|
|
||||||
{
|
|
||||||
const edge_descriptor& edge = this->Base::operator*();
|
|
||||||
v = edge.first->vertex(this->tr->ccw(edge.second));
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Because we wrap the iterator with a Counting_iterator, which returns a ref in its operator*()
|
|
||||||
mutable Vertex_handle v;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Tr, typename Iterator, typename Handle>
|
|
||||||
struct Dereference_to_handle_enforcer
|
|
||||||
: public boost::iterator_adaptor<
|
|
||||||
Dereference_to_handle_enforcer<Tr, Iterator, Handle>,
|
|
||||||
Iterator /*base*/,
|
|
||||||
Handle /*value*/,
|
|
||||||
boost::use_default,
|
|
||||||
Handle /*reference*/
|
|
||||||
>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef Handle value_type;
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef Dereference_to_handle_enforcer<Tr, Iterator, Handle> Self;
|
|
||||||
typedef Iterator I;
|
|
||||||
typedef boost::iterator_adaptor<Self, I, value_type, boost::use_default, value_type> Base;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Dereference_to_handle_enforcer() { }
|
|
||||||
explicit Dereference_to_handle_enforcer(const I& i) : Base(i) { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class boost::iterator_core_access;
|
|
||||||
value_type dereference() const { return value_type(this->base()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
} // namespace CGAL
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
# pragma warning(push)
|
|
||||||
# pragma warning(disable:4099) // For VC10 it is class hash
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CGAL_CFG_NO_STD_HASH
|
|
||||||
|
|
||||||
template < class Tr>
|
|
||||||
struct hash<CGAL::detail::T2_halfedge_descriptor<Tr> >
|
|
||||||
{
|
|
||||||
std::size_t operator()(const CGAL::detail::T2_halfedge_descriptor<Tr>& e) const
|
|
||||||
{
|
|
||||||
return hash_value(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CGAL_CFG_NO_STD_HASH
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
# pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
#endif // CGAL_GRAPH_TRAITS_2D_TRIANGULATION
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
||||||
|
|
@ -417,28 +58,30 @@ struct graph_traits< CGAL_2D_TRIANGULATION >
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
typedef typename Triangulation::Vertex_handle vertex_descriptor;
|
typedef typename Triangulation::Vertex_handle vertex_descriptor;
|
||||||
typedef CGAL::detail::T2_halfedge_descriptor<Triangulation> halfedge_descriptor;
|
typedef CGAL::internal::T2_halfedge_descriptor<Triangulation> halfedge_descriptor;
|
||||||
typedef CGAL::detail::T2_edge_descriptor<Triangulation> edge_descriptor;
|
typedef CGAL::internal::T2_edge_descriptor<Triangulation> edge_descriptor;
|
||||||
typedef typename Triangulation::Face_handle face_descriptor;
|
typedef typename Triangulation::Face_handle face_descriptor;
|
||||||
|
|
||||||
// We need to go from 'Finite_vertex_iterator' to 'Vertex_handle' (and even more
|
// We need to go from 'Finite_vertex_iterator' to 'Vertex_handle' (and even more
|
||||||
// in the case of RT2, since it has also a hidden filter)
|
// in the case of RT2, since it has also a hidden filter)
|
||||||
typedef CGAL::detail::Dereference_to_handle_enforcer<
|
typedef CGAL::internal::Dereference_to_handle_enforcer<
|
||||||
Triangulation,
|
Triangulation,
|
||||||
typename Triangulation::Finite_vertices_iterator,
|
typename Triangulation::Finite_vertices_iterator,
|
||||||
vertex_descriptor> vertex_iterator;
|
vertex_descriptor> vertex_iterator;
|
||||||
typedef CGAL::detail::Dereference_to_handle_enforcer<
|
typedef CGAL::internal::Dereference_to_handle_enforcer<
|
||||||
Triangulation,
|
Triangulation,
|
||||||
typename Triangulation::Finite_faces_iterator,
|
typename Triangulation::Finite_faces_iterator,
|
||||||
face_descriptor> face_iterator;
|
face_descriptor> face_iterator;
|
||||||
typedef CGAL::detail::T2_halfedge_iterator<Triangulation> halfedge_iterator;
|
typedef CGAL::internal::T2_halfedge_iterator<Triangulation,
|
||||||
typedef CGAL::detail::T2_edge_iterator<Triangulation> edge_iterator;
|
typename Triangulation::Finite_edges_iterator> halfedge_iterator;
|
||||||
|
typedef CGAL::internal::T2_edge_iterator<Triangulation,
|
||||||
|
typename Triangulation::Finite_edges_iterator> edge_iterator;
|
||||||
|
|
||||||
typedef CGAL::detail::T2_vertex_circulator<Triangulation> Vertex_circulator;
|
typedef CGAL::internal::T2_vertex_circulator<Triangulation> Vertex_circulator;
|
||||||
typedef CGAL::Counting_iterator<Vertex_circulator> adjacency_iterator;
|
typedef CGAL::Counting_iterator<Vertex_circulator> adjacency_iterator;
|
||||||
typedef CGAL::detail::In_edge_circulator<Triangulation> In_edge_circ;
|
typedef CGAL::internal::In_edge_circulator<Triangulation> In_edge_circ;
|
||||||
typedef CGAL::Counting_iterator<In_edge_circ> in_edge_iterator;
|
typedef CGAL::Counting_iterator<In_edge_circ> in_edge_iterator;
|
||||||
typedef CGAL::detail::Out_edge_circulator<Triangulation> Out_edge_circ;
|
typedef CGAL::internal::Out_edge_circulator<Triangulation> Out_edge_circ;
|
||||||
typedef CGAL::Counting_iterator<Out_edge_circ> out_edge_iterator;
|
typedef CGAL::Counting_iterator<Out_edge_circ> out_edge_iterator;
|
||||||
|
|
||||||
typedef undirected_tag directed_category;
|
typedef undirected_tag directed_category;
|
||||||
|
|
@ -757,7 +400,7 @@ inline Iterator_range<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::in_
|
||||||
in_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
|
in_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
|
||||||
const CGAL_2D_TRIANGULATION& g)
|
const CGAL_2D_TRIANGULATION& g)
|
||||||
{
|
{
|
||||||
typedef CGAL::detail::In_edge_circulator< CGAL_2D_TRIANGULATION > Circ;
|
typedef CGAL::internal::In_edge_circulator< CGAL_2D_TRIANGULATION > Circ;
|
||||||
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::in_edge_iterator Iter;
|
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::in_edge_iterator Iter;
|
||||||
|
|
||||||
typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face());
|
typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face());
|
||||||
|
|
@ -771,7 +414,7 @@ inline Iterator_range<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::out
|
||||||
out_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
|
out_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
|
||||||
const CGAL_2D_TRIANGULATION& g)
|
const CGAL_2D_TRIANGULATION& g)
|
||||||
{
|
{
|
||||||
typedef CGAL::detail::Out_edge_circulator< CGAL_2D_TRIANGULATION > Circ;
|
typedef CGAL::internal::Out_edge_circulator< CGAL_2D_TRIANGULATION > Circ;
|
||||||
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::out_edge_iterator Iter;
|
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::out_edge_iterator Iter;
|
||||||
|
|
||||||
typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face());
|
typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face());
|
||||||
|
|
@ -785,7 +428,7 @@ inline Iterator_range<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::adj
|
||||||
adjacent_vertices(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
|
adjacent_vertices(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
|
||||||
const CGAL_2D_TRIANGULATION& g)
|
const CGAL_2D_TRIANGULATION& g)
|
||||||
{
|
{
|
||||||
typedef CGAL::detail::T2_vertex_circulator< CGAL_2D_TRIANGULATION > Circ;
|
typedef CGAL::internal::T2_vertex_circulator< CGAL_2D_TRIANGULATION > Circ;
|
||||||
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::adjacency_iterator Iter;
|
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::adjacency_iterator Iter;
|
||||||
|
|
||||||
typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face());
|
typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,445 @@
|
||||||
|
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 3 of the License,
|
||||||
|
// or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0+
|
||||||
|
//
|
||||||
|
// Author(s) : Mael Rouxel-Labbé
|
||||||
|
|
||||||
|
#include <CGAL/Iterator_range.h>
|
||||||
|
#include <CGAL/iterator.h>
|
||||||
|
#include <CGAL/use.h>
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/iterator_adaptors.hpp>
|
||||||
|
#include <boost/graph/graph_traits.hpp>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#ifndef CGAL_GRAPH_TRAITS_2D_TRIANGULATION_HELPERS
|
||||||
|
#define CGAL_GRAPH_TRAITS_2D_TRIANGULATION_HELPERS
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// A triangulation edge is a face handle + an int, and is thus actually a halfedge...
|
||||||
|
template <class Tr>
|
||||||
|
struct T2_halfedge_descriptor
|
||||||
|
: public Tr::Edge
|
||||||
|
{
|
||||||
|
typedef typename Tr::Edge Base;
|
||||||
|
typedef typename Tr::Face_handle Face_handle;
|
||||||
|
|
||||||
|
T2_halfedge_descriptor() {}
|
||||||
|
T2_halfedge_descriptor(Face_handle fh, int i) : Base(fh, i) { }
|
||||||
|
explicit T2_halfedge_descriptor(const Base& e) : Base(e) { }
|
||||||
|
T2_halfedge_descriptor(const T2_halfedge_descriptor& h) : Base(h) { }
|
||||||
|
|
||||||
|
const Base& base() const { return static_cast<const Base&>(*this); }
|
||||||
|
|
||||||
|
T2_halfedge_descriptor& operator=(const T2_halfedge_descriptor& h)
|
||||||
|
{
|
||||||
|
this->first = h.first;
|
||||||
|
this->second = h.second;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::size_t hash_value(const T2_halfedge_descriptor& e) {
|
||||||
|
return hash_value(e.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const T2_halfedge_descriptor& other) const {
|
||||||
|
return (this->first == other.first) && (this->second == other.second);
|
||||||
|
}
|
||||||
|
bool operator!=(const T2_halfedge_descriptor& other) const {
|
||||||
|
return (this->first != other.first) || (this->second != other.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const T2_halfedge_descriptor& other) const
|
||||||
|
{
|
||||||
|
if(this->first < other.first) return true;
|
||||||
|
if(this->first > other.first) return false;
|
||||||
|
return this->second < other.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// An edge is just a halfedge, but we give it a complete structure to distinguish it from Tr::Edge
|
||||||
|
template <typename Tr>
|
||||||
|
struct T2_edge_descriptor
|
||||||
|
{
|
||||||
|
typedef typename Tr::Face_handle Face_handle;
|
||||||
|
|
||||||
|
T2_edge_descriptor() : first(), second(0) { }
|
||||||
|
explicit T2_edge_descriptor(const typename Tr::Edge& e) : first(e.first), second(e.second) { }
|
||||||
|
T2_edge_descriptor(Face_handle fd, int i) : first(fd), second(i) { }
|
||||||
|
|
||||||
|
// so that we can still do stuff like tr.is_finite(edge_descriptor) without any hassle
|
||||||
|
operator std::pair<Face_handle, int>() { return std::make_pair(first, second); }
|
||||||
|
|
||||||
|
friend std::size_t hash_value(const T2_edge_descriptor& h)
|
||||||
|
{
|
||||||
|
if(h.first == Face_handle())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return hash_value(h.first < h.first->neighbor(h.second) ? h.first
|
||||||
|
: h.first->neighbor(h.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const T2_edge_descriptor& other) const
|
||||||
|
{
|
||||||
|
if((first == other.first) && (second == other.second))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Face_handle fh = first->neighbor(second);
|
||||||
|
if(other.first != fh)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int i = fh->index(first);
|
||||||
|
return (other.second == i);
|
||||||
|
}
|
||||||
|
bool operator!=(T2_edge_descriptor& other) const { return ! (*this == other); }
|
||||||
|
|
||||||
|
Face_handle first;
|
||||||
|
int second;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A halfedge iterator is just an edge iterator that duplicates everything twice,
|
||||||
|
// to see the edge from either side.
|
||||||
|
// Could probably be factorized with T2_edge_iterator, but it's clearer this way.
|
||||||
|
template <typename Tr, typename EdgeIterator>
|
||||||
|
struct T2_halfedge_iterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef T2_halfedge_iterator<Tr, EdgeIterator> Self;
|
||||||
|
typedef EdgeIterator Edge_iterator;
|
||||||
|
typedef T2_halfedge_descriptor<Tr> Descriptor;
|
||||||
|
typedef typename Tr::Face_handle Face_handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef Descriptor value_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef value_type& reference;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
typedef std::bidirectional_iterator_tag iterator_category;
|
||||||
|
|
||||||
|
T2_halfedge_iterator() { }
|
||||||
|
T2_halfedge_iterator(const Edge_iterator& feit) : it(feit), on_adjacent_face(false) { }
|
||||||
|
|
||||||
|
Self& operator++()
|
||||||
|
{
|
||||||
|
// If we are on the first face, move to the opposite face. If we are already on the opposite face,
|
||||||
|
// then it's time to move on the next edge
|
||||||
|
if(on_adjacent_face) {
|
||||||
|
++it;
|
||||||
|
on_adjacent_face = false;
|
||||||
|
} else {
|
||||||
|
on_adjacent_face = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Self& operator--()
|
||||||
|
{
|
||||||
|
// Note that while decreasing, we start from the opposite face
|
||||||
|
if(on_adjacent_face) {
|
||||||
|
on_adjacent_face = false;
|
||||||
|
} else {
|
||||||
|
--it;
|
||||||
|
on_adjacent_face = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Self operator++(int) { Self tmp = *this; operator++(); return tmp; }
|
||||||
|
Self operator--(int) { Self tmp = *this; operator--(); return tmp; }
|
||||||
|
|
||||||
|
bool operator==(const Self& other) const { return it == other.it; }
|
||||||
|
bool operator!=(const Self& other) const { return !(*this == other); }
|
||||||
|
|
||||||
|
value_type operator*() const
|
||||||
|
{
|
||||||
|
if(on_adjacent_face) {
|
||||||
|
Face_handle neigh_f = it->first->neighbor(it->second);
|
||||||
|
return value_type(neigh_f, neigh_f->index(it->first));
|
||||||
|
} else {
|
||||||
|
return value_type(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Edge_iterator it;
|
||||||
|
bool on_adjacent_face;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Tr, typename EdgeIterator>
|
||||||
|
struct T2_edge_iterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef T2_edge_iterator<Tr, EdgeIterator> Self;
|
||||||
|
typedef EdgeIterator Edge_iterator;
|
||||||
|
typedef T2_edge_descriptor<Tr> Descriptor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef Descriptor value_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef value_type& reference;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
typedef std::bidirectional_iterator_tag iterator_category;
|
||||||
|
|
||||||
|
T2_edge_iterator() { }
|
||||||
|
T2_edge_iterator(const Edge_iterator& feit) : it(feit) { }
|
||||||
|
|
||||||
|
bool operator==(const Self& other) const { return it == other.it; }
|
||||||
|
bool operator!=(const Self& other) const { return !(*this == other); }
|
||||||
|
Self& operator++() { ++it; return *this; }
|
||||||
|
Self& operator--() { --it; return *this; }
|
||||||
|
Self operator++(int) { Self tmp = *this; operator++(); return tmp; }
|
||||||
|
Self operator--(int) { Self tmp = *this; operator--(); return tmp; }
|
||||||
|
value_type operator*() const { return value_type(*it); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Edge_iterator it;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Must distinguish TDS and triangulations circulators (later are filtered)
|
||||||
|
template <class Circ, class E>
|
||||||
|
class TDS2_Out_edge_circulator
|
||||||
|
: public Circ
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
mutable E e;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef E value_type;
|
||||||
|
typedef E* pointer;
|
||||||
|
typedef E& reference;
|
||||||
|
|
||||||
|
TDS2_Out_edge_circulator() : Circ() {}
|
||||||
|
TDS2_Out_edge_circulator(Circ c) : Circ(c) {}
|
||||||
|
|
||||||
|
const E& operator*() const
|
||||||
|
{
|
||||||
|
E ed = static_cast<const Circ*>(this)->operator*();
|
||||||
|
e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Circ, class E>
|
||||||
|
class TDS2_In_edge_circulator
|
||||||
|
: public Circ
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
mutable E e;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef E value_type;
|
||||||
|
typedef E* pointer;
|
||||||
|
typedef E& reference;
|
||||||
|
|
||||||
|
TDS2_In_edge_circulator() : Circ() {}
|
||||||
|
TDS2_In_edge_circulator(Circ c) : Circ(c) {}
|
||||||
|
|
||||||
|
const E& operator*() const
|
||||||
|
{
|
||||||
|
typename Circ::value_type ed = static_cast<const Circ*>(this)->operator*();
|
||||||
|
e = E(ed);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Tr>
|
||||||
|
struct T2_edge_circulator
|
||||||
|
: public Tr::Edge_circulator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef T2_edge_circulator<Tr> Self;
|
||||||
|
typedef typename Tr::Edge Edge;
|
||||||
|
typedef typename Tr::Edge_circulator Base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef T2_edge_descriptor<Tr> value_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef value_type& reference;
|
||||||
|
|
||||||
|
T2_edge_circulator() : Base() { }
|
||||||
|
T2_edge_circulator(const Base& c, const Tr& tr) : Base(c), tr(&tr), e() { }
|
||||||
|
|
||||||
|
// Note that the inf check is on the edge in the circulator, not on 'e', which isn't built yet
|
||||||
|
Self& operator++() {
|
||||||
|
do { this->Base::operator++(); } while(tr->is_infinite(this->Base::operator*()));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Self& operator--() {
|
||||||
|
do { this->Base::operator--(); } while(tr->is_infinite(this->Base::operator*()));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
|
||||||
|
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const Tr* tr;
|
||||||
|
mutable value_type e;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Tr>
|
||||||
|
struct In_edge_circulator
|
||||||
|
: public T2_edge_circulator<Tr>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef T2_edge_circulator<Tr> Base;
|
||||||
|
typedef typename Tr::Edge Edge;
|
||||||
|
typedef typename Tr::Edge_circulator Edge_circulator;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef T2_edge_descriptor<Tr> value_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef value_type& reference;
|
||||||
|
|
||||||
|
In_edge_circulator() : Base() { }
|
||||||
|
In_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { }
|
||||||
|
|
||||||
|
const value_type& operator*() const
|
||||||
|
{
|
||||||
|
this->e = value_type(this->Base::operator*());
|
||||||
|
return this->e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Tr>
|
||||||
|
struct Out_edge_circulator
|
||||||
|
: public T2_edge_circulator<Tr>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef T2_edge_circulator<Tr> Base;
|
||||||
|
typedef typename Tr::Edge Edge;
|
||||||
|
typedef typename Tr::Edge_circulator Edge_circulator;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef T2_edge_descriptor<Tr> value_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef value_type& reference;
|
||||||
|
|
||||||
|
Out_edge_circulator() : Base() { }
|
||||||
|
Out_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { }
|
||||||
|
|
||||||
|
const value_type& operator*() const
|
||||||
|
{
|
||||||
|
Edge ed(this->Base::operator*());
|
||||||
|
this->e = value_type(ed.first->neighbor(ed.second),
|
||||||
|
ed.first->neighbor(ed.second)->index(ed.first));
|
||||||
|
return this->e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Tr>
|
||||||
|
struct T2_vertex_circulator
|
||||||
|
: public In_edge_circulator<Tr>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef In_edge_circulator<Tr> Base;
|
||||||
|
typedef T2_edge_descriptor<Tr> edge_descriptor;
|
||||||
|
typedef typename Tr::Edge_circulator Edge_circulator;
|
||||||
|
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef Vertex_handle value_type;
|
||||||
|
typedef value_type& reference;
|
||||||
|
|
||||||
|
T2_vertex_circulator() : Base() { }
|
||||||
|
T2_vertex_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { }
|
||||||
|
|
||||||
|
const value_type& operator*() const
|
||||||
|
{
|
||||||
|
const edge_descriptor& edge = this->Base::operator*();
|
||||||
|
v = edge.first->vertex(this->tr->ccw(edge.second));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Because we wrap the iterator with a Counting_iterator, which returns a ref in its operator*()
|
||||||
|
mutable Vertex_handle v;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Tr, typename Iterator, typename Handle>
|
||||||
|
struct Dereference_to_handle_enforcer
|
||||||
|
: public boost::iterator_adaptor<
|
||||||
|
Dereference_to_handle_enforcer<Tr, Iterator, Handle>,
|
||||||
|
Iterator /*base*/,
|
||||||
|
Handle /*value*/,
|
||||||
|
boost::use_default,
|
||||||
|
Handle /*reference*/
|
||||||
|
>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef Handle value_type;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef Dereference_to_handle_enforcer<Tr, Iterator, Handle> Self;
|
||||||
|
typedef Iterator I;
|
||||||
|
typedef boost::iterator_adaptor<Self, I, value_type, boost::use_default, value_type> Base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Dereference_to_handle_enforcer() { }
|
||||||
|
explicit Dereference_to_handle_enforcer(const I& i) : Base(i) { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class boost::iterator_core_access;
|
||||||
|
value_type dereference() const { return value_type(this->base()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
// workaround a bug detected on at least g++ 4.4 where boost::next(Iterator)
|
||||||
|
// is picked as a candidate for next(h,g)
|
||||||
|
template <typename Tr>
|
||||||
|
struct iterator_traits< CGAL::internal::T2_halfedge_descriptor<Tr> >
|
||||||
|
{
|
||||||
|
typedef void* iterator_category;
|
||||||
|
typedef void* difference_type;
|
||||||
|
typedef void* value_type;
|
||||||
|
typedef void* reference;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable:4099) // For VC10 it is class hash
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CGAL_CFG_NO_STD_HASH
|
||||||
|
|
||||||
|
template < class Tr>
|
||||||
|
struct hash<CGAL::internal::T2_halfedge_descriptor<Tr> >
|
||||||
|
{
|
||||||
|
std::size_t operator()(const CGAL::internal::T2_halfedge_descriptor<Tr>& e) const {
|
||||||
|
return hash_value(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CGAL_CFG_NO_STD_HASH
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#endif // CGAL_GRAPH_TRAITS_2D_TRIANGULATION_HELPERS
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
#define CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H
|
#define CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace detail {
|
namespace internal {
|
||||||
|
|
||||||
template <class Tr>
|
template <class Tr>
|
||||||
struct T2_halfedge_descriptor;
|
struct T2_halfedge_descriptor;
|
||||||
|
|
@ -113,9 +113,9 @@ public:
|
||||||
typedef boost::readable_property_map_tag category;
|
typedef boost::readable_property_map_tag category;
|
||||||
typedef int value_type;
|
typedef int value_type;
|
||||||
typedef int reference;
|
typedef int reference;
|
||||||
typedef CGAL::detail::T2_halfedge_descriptor<Tr> key_type;
|
typedef CGAL::internal::T2_halfedge_descriptor<Tr> key_type;
|
||||||
|
|
||||||
typedef typename Tr::Face_handle face_descriptor;
|
typedef typename Tr::Face_handle Face_handle;
|
||||||
|
|
||||||
T2_halfedge_id_map(const Tr& tr) : tr(tr) { }
|
T2_halfedge_id_map(const Tr& tr) : tr(tr) { }
|
||||||
|
|
||||||
|
|
@ -123,8 +123,8 @@ public:
|
||||||
// h.first is such that h.first < opposite(h).first --> different ids
|
// h.first is such that h.first < opposite(h).first --> different ids
|
||||||
value_type operator[](key_type h) const
|
value_type operator[](key_type h) const
|
||||||
{
|
{
|
||||||
const face_descriptor f1 = h.first;
|
const Face_handle f1 = h.first;
|
||||||
const face_descriptor f2 = f1->neighbor(h.second);
|
const Face_handle f2 = f1->neighbor(h.second);
|
||||||
CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2));
|
CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2));
|
||||||
|
|
||||||
if(tr.is_infinite(f1))
|
if(tr.is_infinite(f1))
|
||||||
|
|
@ -149,15 +149,15 @@ public:
|
||||||
typedef boost::readable_property_map_tag category;
|
typedef boost::readable_property_map_tag category;
|
||||||
typedef int value_type;
|
typedef int value_type;
|
||||||
typedef int reference;
|
typedef int reference;
|
||||||
typedef CGAL::detail::T2_edge_descriptor<Tr> key_type;
|
typedef CGAL::internal::T2_edge_descriptor<Tr> key_type;
|
||||||
typedef typename Tr::Face_handle face_descriptor;
|
typedef typename Tr::Face_handle Face_handle;
|
||||||
|
|
||||||
T2_edge_id_map(const Tr& tr) : tr(tr) { }
|
T2_edge_id_map(const Tr& tr) : tr(tr) { }
|
||||||
|
|
||||||
value_type operator[](key_type e) const
|
value_type operator[](key_type e) const
|
||||||
{
|
{
|
||||||
const face_descriptor f1 = e.first;
|
const Face_handle f1 = e.first;
|
||||||
const face_descriptor f2 = f1->neighbor(e.second);
|
const Face_handle f2 = f1->neighbor(e.second);
|
||||||
CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2));
|
CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2));
|
||||||
|
|
||||||
if(tr.is_infinite(f1))
|
if(tr.is_infinite(f1))
|
||||||
|
|
@ -201,47 +201,46 @@ struct T2_property_map { };
|
||||||
template <typename Tr>
|
template <typename Tr>
|
||||||
struct T2_property_map<Tr, boost::vertex_point_t>
|
struct T2_property_map<Tr, boost::vertex_point_t>
|
||||||
{
|
{
|
||||||
typedef detail::T2_vertex_point_map<Tr> type;
|
typedef internal::T2_vertex_point_map<Tr> type;
|
||||||
typedef detail::T2_vertex_point_map<Tr> const_type;
|
typedef internal::T2_vertex_point_map<Tr> const_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Tr>
|
template <typename Tr>
|
||||||
struct T2_property_map<Tr, boost::edge_weight_t>
|
struct T2_property_map<Tr, boost::edge_weight_t>
|
||||||
{
|
{
|
||||||
typedef detail::T2_edge_weight_map<Tr> type;
|
typedef internal::T2_edge_weight_map<Tr> type;
|
||||||
typedef detail::T2_edge_weight_map<Tr> const_type;
|
typedef internal::T2_edge_weight_map<Tr> const_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Tr>
|
template <typename Tr>
|
||||||
struct T2_property_map<Tr, boost::vertex_index_t>
|
struct T2_property_map<Tr, boost::vertex_index_t>
|
||||||
{
|
{
|
||||||
typedef detail::T2_vertex_id_map<Tr> type;
|
typedef internal::T2_vertex_id_map<Tr> type;
|
||||||
typedef detail::T2_vertex_id_map<Tr> const_type;
|
typedef internal::T2_vertex_id_map<Tr> const_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Tr>
|
template <typename Tr>
|
||||||
struct T2_property_map<Tr, boost::halfedge_index_t>
|
struct T2_property_map<Tr, boost::halfedge_index_t>
|
||||||
{
|
{
|
||||||
typedef detail::T2_halfedge_id_map<Tr> type;
|
typedef internal::T2_halfedge_id_map<Tr> type;
|
||||||
typedef detail::T2_halfedge_id_map<Tr> const_type;
|
typedef internal::T2_halfedge_id_map<Tr> const_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Tr>
|
template <typename Tr>
|
||||||
struct T2_property_map<Tr, boost::edge_index_t>
|
struct T2_property_map<Tr, boost::edge_index_t>
|
||||||
{
|
{
|
||||||
typedef detail::T2_edge_id_map<Tr> type;
|
typedef internal::T2_edge_id_map<Tr> type;
|
||||||
typedef detail::T2_edge_id_map<Tr> const_type;
|
typedef internal::T2_edge_id_map<Tr> const_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Tr>
|
template <typename Tr>
|
||||||
struct T2_property_map<Tr, boost::face_index_t>
|
struct T2_property_map<Tr, boost::face_index_t>
|
||||||
{
|
{
|
||||||
typedef detail::T2_face_id_map<Tr> type;
|
typedef internal::T2_face_id_map<Tr> type;
|
||||||
typedef detail::T2_face_id_map<Tr> const_type;
|
typedef internal::T2_face_id_map<Tr> const_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace detail
|
} // end namespace internal
|
||||||
|
|
||||||
} // CGAL
|
} // CGAL
|
||||||
|
|
||||||
#endif // CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H
|
#endif // CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H
|
||||||
|
|
@ -253,7 +252,7 @@ namespace boost {
|
||||||
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag>
|
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag>
|
||||||
struct property_map<CGAL_2D_TRIANGULATION, Tag>
|
struct property_map<CGAL_2D_TRIANGULATION, Tag>
|
||||||
{
|
{
|
||||||
typedef typename CGAL::detail::T2_property_map<CGAL_2D_TRIANGULATION, Tag> map_gen;
|
typedef typename CGAL::internal::T2_property_map<CGAL_2D_TRIANGULATION, Tag> map_gen;
|
||||||
typedef typename map_gen::type type;
|
typedef typename map_gen::type type;
|
||||||
typedef typename map_gen::const_type const_type;
|
typedef typename map_gen::const_type const_type;
|
||||||
};
|
};
|
||||||
|
|
@ -262,7 +261,7 @@ struct property_map<CGAL_2D_TRIANGULATION, Tag>
|
||||||
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag>
|
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag>
|
||||||
struct property_map<const CGAL_2D_TRIANGULATION, Tag>
|
struct property_map<const CGAL_2D_TRIANGULATION, Tag>
|
||||||
{
|
{
|
||||||
typedef typename CGAL::detail::T2_property_map<CGAL_2D_TRIANGULATION, Tag> map_gen;
|
typedef typename CGAL::internal::T2_property_map<CGAL_2D_TRIANGULATION, Tag> map_gen;
|
||||||
typedef typename map_gen::type type;
|
typedef typename map_gen::type type;
|
||||||
typedef typename map_gen::const_type const_type;
|
typedef typename map_gen::const_type const_type;
|
||||||
};
|
};
|
||||||
|
|
@ -313,50 +312,50 @@ struct graph_has_property<CGAL_2D_TRIANGULATION, boost::face_index_t>
|
||||||
|
|
||||||
// property maps
|
// property maps
|
||||||
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
||||||
inline detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION >
|
inline internal::T2_vertex_point_map< CGAL_2D_TRIANGULATION >
|
||||||
get(boost::vertex_point_t, const CGAL_2D_TRIANGULATION&)
|
get(boost::vertex_point_t, const CGAL_2D_TRIANGULATION&)
|
||||||
{
|
{
|
||||||
detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION > m;
|
internal::T2_vertex_point_map< CGAL_2D_TRIANGULATION > m;
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
||||||
inline detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION >
|
inline internal::T2_edge_weight_map< CGAL_2D_TRIANGULATION >
|
||||||
get(boost::edge_weight_t, const CGAL_2D_TRIANGULATION& g)
|
get(boost::edge_weight_t, const CGAL_2D_TRIANGULATION& g)
|
||||||
{
|
{
|
||||||
detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION > m(g);
|
internal::T2_edge_weight_map< CGAL_2D_TRIANGULATION > m(g);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
||||||
inline detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION >
|
inline internal::T2_vertex_id_map< CGAL_2D_TRIANGULATION >
|
||||||
get(boost::vertex_index_t, const CGAL_2D_TRIANGULATION& g)
|
get(boost::vertex_index_t, const CGAL_2D_TRIANGULATION& g)
|
||||||
{
|
{
|
||||||
detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m(g);
|
internal::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m(g);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
||||||
inline detail::T2_halfedge_id_map< CGAL_2D_TRIANGULATION >
|
inline internal::T2_halfedge_id_map< CGAL_2D_TRIANGULATION >
|
||||||
get(boost::halfedge_index_t, const CGAL_2D_TRIANGULATION& g)
|
get(boost::halfedge_index_t, const CGAL_2D_TRIANGULATION& g)
|
||||||
{
|
{
|
||||||
detail::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > m(g);
|
internal::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > m(g);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
||||||
inline detail::T2_edge_id_map< CGAL_2D_TRIANGULATION >
|
inline internal::T2_edge_id_map< CGAL_2D_TRIANGULATION >
|
||||||
get(boost::edge_index_t, const CGAL_2D_TRIANGULATION& g)
|
get(boost::edge_index_t, const CGAL_2D_TRIANGULATION& g)
|
||||||
{
|
{
|
||||||
detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > m(g);
|
internal::T2_edge_id_map< CGAL_2D_TRIANGULATION > m(g);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
|
||||||
inline detail::T2_face_id_map< CGAL_2D_TRIANGULATION >
|
inline internal::T2_face_id_map< CGAL_2D_TRIANGULATION >
|
||||||
get(boost::face_index_t, const CGAL_2D_TRIANGULATION& g)
|
get(boost::face_index_t, const CGAL_2D_TRIANGULATION& g)
|
||||||
{
|
{
|
||||||
detail::T2_face_id_map< CGAL_2D_TRIANGULATION > m(g);
|
internal::T2_face_id_map< CGAL_2D_TRIANGULATION > m(g);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,354 @@
|
||||||
|
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 3 of the License,
|
||||||
|
// or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0+
|
||||||
|
//
|
||||||
|
// Author(s) : Mael Rouxel-Labbé
|
||||||
|
|
||||||
|
#ifndef CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H
|
||||||
|
#define CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Triangulation_data_structure_2.h>
|
||||||
|
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h>
|
||||||
|
#include <CGAL/boost/graph/internal/Has_member_id.h>
|
||||||
|
|
||||||
|
#include <CGAL/boost/graph/named_function_params.h>
|
||||||
|
|
||||||
|
#include <boost/graph/properties.hpp>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// property maps
|
||||||
|
template <class VB, class FB>
|
||||||
|
class TDS2_vertex_point_map
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::lvalue_property_map_tag category;
|
||||||
|
typedef typename VB::Point value_type;
|
||||||
|
typedef value_type& reference;
|
||||||
|
typedef typename CGAL::Triangulation_data_structure_2<VB,FB>::Vertex_handle key_type;
|
||||||
|
|
||||||
|
friend reference get(TDS2_vertex_point_map<VB,FB>, key_type vh) { return vh->point(); }
|
||||||
|
friend void put(TDS2_vertex_point_map<VB,FB>, key_type vh, reference v) { vh->point() = v; }
|
||||||
|
reference operator[](key_type vh) const { return vh->point(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
class TDS2_edge_weight_map
|
||||||
|
: public boost::put_get_helper<typename VB::FT, TDS2_edge_weight_map<VB, FB> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::readable_property_map_tag category;
|
||||||
|
typedef typename VB::FT value_type;
|
||||||
|
typedef value_type reference;
|
||||||
|
typedef typename CGAL::Triangulation_data_structure_2<VB,FB>::Edge key_type;
|
||||||
|
|
||||||
|
TDS2_edge_weight_map(const CGAL::Triangulation_data_structure_2<VB,FB>& tds_) : tds(tds_) { }
|
||||||
|
|
||||||
|
value_type operator[](key_type e) const { return approximate_sqrt(tds.segment(e).squared_length()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const CGAL::Triangulation_data_structure_2<VB,FB>& tds;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
class TDS2_vertex_id_map
|
||||||
|
: public boost::put_get_helper<int, TDS2_vertex_id_map<VB, FB> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::readable_property_map_tag category;
|
||||||
|
typedef int value_type;
|
||||||
|
typedef int reference;
|
||||||
|
typedef typename CGAL::Triangulation_data_structure_2<VB,FB>::Vertex_handle key_type;
|
||||||
|
|
||||||
|
TDS2_vertex_id_map() {}
|
||||||
|
|
||||||
|
long operator[](key_type vh) const { return vh->id(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
class TDS2_halfedge_id_map
|
||||||
|
: public boost::put_get_helper<int, TDS2_halfedge_id_map<VB, FB> >
|
||||||
|
{
|
||||||
|
typedef typename CGAL::Triangulation_data_structure_2<VB,FB> TDS;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef boost::readable_property_map_tag category;
|
||||||
|
typedef int value_type;
|
||||||
|
typedef int reference;
|
||||||
|
typedef CGAL::internal::T2_halfedge_descriptor<TDS> key_type;
|
||||||
|
|
||||||
|
typedef typename TDS::Face_handle face_descriptor;
|
||||||
|
|
||||||
|
TDS2_halfedge_id_map() { }
|
||||||
|
|
||||||
|
// Halfedge id is twice the edge id, and +0/+1 depending whether
|
||||||
|
// h.first is such that h.first < opposite(h).first --> different ids
|
||||||
|
value_type operator[](key_type h) const
|
||||||
|
{
|
||||||
|
const face_descriptor f1 = h.first;
|
||||||
|
const face_descriptor f2 = f1->neighbor(h.second);
|
||||||
|
|
||||||
|
if(f1->id() < f2->id())
|
||||||
|
return 2*(3 * f1->id() + h.second);
|
||||||
|
else
|
||||||
|
return 2*(3 * f2->id() + f2->index(f1)) + 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
class TDS2_edge_id_map
|
||||||
|
: public boost::put_get_helper<int, TDS2_edge_id_map<VB, FB> >
|
||||||
|
{
|
||||||
|
typedef typename CGAL::Triangulation_data_structure_2<VB,FB> TDS;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef boost::readable_property_map_tag category;
|
||||||
|
typedef int value_type;
|
||||||
|
typedef int reference;
|
||||||
|
typedef CGAL::internal::T2_edge_descriptor<TDS> key_type;
|
||||||
|
|
||||||
|
typedef typename TDS::Face_handle Face_handle;
|
||||||
|
|
||||||
|
TDS2_edge_id_map() {}
|
||||||
|
|
||||||
|
value_type operator[](key_type h) const
|
||||||
|
{
|
||||||
|
const Face_handle f1 = h.first;
|
||||||
|
const Face_handle f2 = f1->neighbor(h.second);
|
||||||
|
|
||||||
|
if(f1->id() < f2->id())
|
||||||
|
return 3 * f1->id() + h.second;
|
||||||
|
else
|
||||||
|
return 3 * f2->id() + f2->index(f1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
class TDS2_face_id_map
|
||||||
|
: public boost::put_get_helper<int, TDS2_face_id_map<VB, FB> >
|
||||||
|
{
|
||||||
|
typedef typename CGAL::Triangulation_data_structure_2<VB,FB> TDS;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef boost::readable_property_map_tag category;
|
||||||
|
typedef int value_type;
|
||||||
|
typedef int reference;
|
||||||
|
typedef typename TDS::Face_handle key_type;
|
||||||
|
|
||||||
|
TDS2_face_id_map() { }
|
||||||
|
|
||||||
|
value_type operator[](key_type f) const { return f->id(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB, class Tag>
|
||||||
|
struct TDS2_property_map { };
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
struct TDS2_property_map<VB, FB, boost::vertex_point_t>
|
||||||
|
{
|
||||||
|
typedef internal::TDS2_vertex_point_map<VB,FB> type;
|
||||||
|
typedef internal::TDS2_vertex_point_map<VB,FB> const_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
struct TDS2_property_map<VB, FB, boost::edge_weight_t>
|
||||||
|
{
|
||||||
|
typedef internal::TDS2_edge_weight_map<VB,FB> type;
|
||||||
|
typedef internal::TDS2_edge_weight_map<VB,FB> const_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
struct TDS2_property_map<VB, FB, boost::vertex_index_t>
|
||||||
|
{
|
||||||
|
typedef internal::TDS2_vertex_id_map<VB,FB> type;
|
||||||
|
typedef internal::TDS2_vertex_id_map<VB,FB> const_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
struct TDS2_property_map<VB, FB, boost::halfedge_index_t>
|
||||||
|
{
|
||||||
|
typedef internal::TDS2_vertex_id_map<VB,FB> type;
|
||||||
|
typedef internal::TDS2_vertex_id_map<VB,FB> const_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
struct TDS2_property_map<VB, FB, boost::edge_index_t>
|
||||||
|
{
|
||||||
|
typedef internal::TDS2_edge_id_map<VB,FB> type;
|
||||||
|
typedef internal::TDS2_edge_id_map<VB,FB> const_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
struct TDS2_property_map<VB, FB, boost::face_index_t>
|
||||||
|
{
|
||||||
|
typedef internal::TDS2_vertex_id_map<VB,FB> type;
|
||||||
|
typedef internal::TDS2_vertex_id_map<VB,FB> const_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
template <class VB, class FB >
|
||||||
|
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::vertex_point_t>
|
||||||
|
: CGAL::Tag_true{};
|
||||||
|
template<class VB, class FB >
|
||||||
|
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::edge_weight_t>
|
||||||
|
: CGAL::Tag_true{};
|
||||||
|
|
||||||
|
template<class VB, class FB >
|
||||||
|
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::vertex_index_t>
|
||||||
|
: CGAL::Boolean_tag<
|
||||||
|
CGAL::internal::Has_member_id<
|
||||||
|
typename CGAL::Triangulation_data_structure_2<VB, FB>::Vertex
|
||||||
|
>::value
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
template<class VB, class FB >
|
||||||
|
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::halfedge_index_t>
|
||||||
|
: CGAL::Boolean_tag<
|
||||||
|
CGAL::internal::Has_member_id<
|
||||||
|
typename CGAL::Triangulation_data_structure_2<VB, FB>::Face
|
||||||
|
>::value
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
template<class VB, class FB >
|
||||||
|
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::edge_index_t>
|
||||||
|
: CGAL::Boolean_tag<
|
||||||
|
CGAL::internal::Has_member_id<
|
||||||
|
typename CGAL::Triangulation_data_structure_2<VB, FB>::Face
|
||||||
|
>::value
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
template<class VB, class FB >
|
||||||
|
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::face_index_t>
|
||||||
|
: CGAL::Boolean_tag<
|
||||||
|
CGAL::internal::Has_member_id<
|
||||||
|
typename CGAL::Triangulation_data_structure_2<VB, FB>::Face
|
||||||
|
>::value
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
inline internal::TDS2_vertex_point_map<VB,FB>
|
||||||
|
get(boost::vertex_point_t, const Triangulation_data_structure_2<VB,FB>&)
|
||||||
|
{
|
||||||
|
internal::TDS2_vertex_point_map<VB,FB> m;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
inline internal::TDS2_edge_weight_map<VB,FB>
|
||||||
|
get(boost::edge_weight_t, const Triangulation_data_structure_2<VB,FB>& g)
|
||||||
|
{
|
||||||
|
internal::TDS2_edge_weight_map<VB,FB> m(g);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
inline internal::TDS2_vertex_id_map<VB,FB>
|
||||||
|
get(boost::vertex_index_t, const Triangulation_data_structure_2<VB,FB>&)
|
||||||
|
{
|
||||||
|
internal::TDS2_vertex_id_map<VB,FB> m;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
inline internal::TDS2_halfedge_id_map<VB,FB>
|
||||||
|
get(boost::halfedge_index_t, const Triangulation_data_structure_2<VB,FB>&)
|
||||||
|
{
|
||||||
|
internal::TDS2_halfedge_id_map<VB,FB> m;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
inline internal::TDS2_edge_id_map<VB,FB>
|
||||||
|
get(boost::edge_index_t, const Triangulation_data_structure_2<VB,FB>&)
|
||||||
|
{
|
||||||
|
internal::TDS2_edge_id_map<VB,FB> m;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class VB, class FB>
|
||||||
|
inline internal::TDS2_face_id_map<VB,FB>
|
||||||
|
get(boost::face_index_t, const Triangulation_data_structure_2<VB,FB>&)
|
||||||
|
{
|
||||||
|
internal::TDS2_face_id_map<VB,FB> m;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
// g++ 'enumeral_type' in template unification not implemented workaround
|
||||||
|
template <class VB, class FB, class Tag>
|
||||||
|
struct property_map<CGAL::Triangulation_data_structure_2<VB,FB>, Tag>
|
||||||
|
{
|
||||||
|
typedef typename CGAL::internal::TDS2_property_map<VB, FB, Tag> map_gen;
|
||||||
|
typedef typename map_gen::type type;
|
||||||
|
typedef typename map_gen::const_type const_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// see struct property_map in Polyehdron for an explanation
|
||||||
|
template <class VB, class FB, class Tag>
|
||||||
|
struct property_map<const CGAL::Triangulation_data_structure_2<VB,FB>, Tag>
|
||||||
|
{
|
||||||
|
typedef typename CGAL::internal::TDS2_property_map<VB, FB, Tag> map_gen;
|
||||||
|
typedef typename map_gen::type type;
|
||||||
|
typedef typename map_gen::const_type const_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
template <class VB, class FB, class PropertyTag, class Key>
|
||||||
|
inline
|
||||||
|
typename boost::property_traits<
|
||||||
|
typename boost::property_map<Triangulation_data_structure_2<VB,FB>,PropertyTag>::const_type>::value_type
|
||||||
|
get(PropertyTag p, const Triangulation_data_structure_2<VB,FB>& g, const Key& key)
|
||||||
|
{
|
||||||
|
return get(get(p, g), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class VB, class FB, class PropertyTag, class Key,class Value>
|
||||||
|
inline void
|
||||||
|
put(PropertyTag p, Triangulation_data_structure_2<VB,FB>& g,
|
||||||
|
const Key& key, const Value& value)
|
||||||
|
{
|
||||||
|
typedef typename boost::property_map<Triangulation_data_structure_2<VB,FB>, PropertyTag>::type Map;
|
||||||
|
Map pmap = get(p, g);
|
||||||
|
put(pmap, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
// What are those needed for ???
|
||||||
|
template <typename VB, typename FB>
|
||||||
|
struct edge_property_type<CGAL::Triangulation_data_structure_2<VB,FB> > {
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename VB, typename FB>
|
||||||
|
struct vertex_property_type<CGAL::Triangulation_data_structure_2<VB,FB> > {
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif /* CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H */
|
||||||
Loading…
Reference in New Issue