From 9cba48acfedbcc541720106f559fcedc9398fe8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 29 Apr 2019 13:22:45 +0200 Subject: [PATCH] Fixed TDS graph traits implementation and factorized some parts with other T2 GT --- Convex_hull_3/include/CGAL/convex_hull_3.h | 1 + ...ph_traits_Triangulation_data_structure_2.h | 523 +----------------- .../internal/graph_traits_2D_triangulation.h | 389 +------------ .../graph_traits_2D_triangulation_helper.h | 445 +++++++++++++++ .../internal/properties_2D_triangulation.h | 73 ++- ...roperties_Triangulation_data_structure_2.h | 354 ++++++++++++ 6 files changed, 876 insertions(+), 909 deletions(-) create mode 100644 Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h create mode 100644 Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h diff --git a/Convex_hull_3/include/CGAL/convex_hull_3.h b/Convex_hull_3/include/CGAL/convex_hull_3.h index 63dbb592b43..ac5999c37c7 100644 --- a/Convex_hull_3/include/CGAL/convex_hull_3.h +++ b/Convex_hull_3/include/CGAL/convex_hull_3.h @@ -54,6 +54,7 @@ #include #include #include +#include #include #include diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h index efadd3231e7..123d3502a6c 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h @@ -25,272 +25,22 @@ // include this to avoid a VC15 warning #include +#include + +#include +#include +#include #include #include #include #include -#include -#include -#include - // 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 // 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 -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(*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 -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() { 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 -struct TDS2_halfedge_iterator -{ -private: - typedef TDS2_halfedge_iterator Self; - typedef typename TDS::Edge_iterator Edge_iterator; - typedef TDS2_halfedge_descriptor 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 -struct TDS2_edge_iterator -{ -private: - typedef TDS2_edge_iterator Self; - typedef typename TDS::Edge_iterator Edge_iterator; - typedef TDS2_edge_descriptor 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 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(this)->operator*(); - e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first)); - return e; - } -}; - -template -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(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 -struct iterator_traits< CGAL::detail::TDS2_halfedge_descriptor > -{ - typedef void* iterator_category; - typedef void* difference_type; - typedef void* value_type; - typedef void* reference; -}; - -} // end of namespace std - -namespace boost { +namespace boost { template struct graph_traits > @@ -304,17 +54,19 @@ struct graph_traits > typedef CGAL::Triangulation_data_structure_2 Triangulation_data_structure; typedef typename Triangulation_data_structure::Vertex_handle vertex_descriptor; - typedef CGAL::detail::TDS2_halfedge_descriptor halfedge_descriptor; - typedef CGAL::detail::TDS2_edge_descriptor edge_descriptor; + typedef CGAL::internal::T2_halfedge_descriptor halfedge_descriptor; + typedef CGAL::internal::T2_edge_descriptor edge_descriptor; typedef typename Triangulation_data_structure::Face_handle face_descriptor; typedef CGAL::Prevent_deref vertex_iterator; - typedef CGAL::detail::TDS2_halfedge_iterator halfedge_iterator; - typedef CGAL::detail::TDS2_edge_iterator edge_iterator; + typedef CGAL::internal::T2_halfedge_iterator halfedge_iterator; + typedef CGAL::internal::T2_edge_iterator edge_iterator; typedef CGAL::Prevent_deref face_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; - typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; + typedef CGAL::Counting_iterator, edge_descriptor > out_edge_iterator; + typedef CGAL::Counting_iterator, edge_descriptor > in_edge_iterator; typedef CGAL::Counting_iterator Incident_vertices_iterator; typedef Incident_vertices_iterator adjacency_iterator; @@ -330,11 +82,16 @@ struct graph_traits > typedef size_type degree_size_type; // nulls - static vertex_descriptor null_vertex() { return vertex_descriptor(); } - static face_descriptor null_face() { return face_descriptor(); } - static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } + static vertex_descriptor null_vertex() { return vertex_descriptor(); } + static face_descriptor null_face() { return face_descriptor(); } + static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } }; +template +struct graph_traits > + : public graph_traits< CGAL::Triangulation_data_structure_2 > +{ }; + } // namespace boost namespace CGAL { @@ -502,7 +259,7 @@ out_edges(typename boost::graph_traits< Triangulation_data_structure_2 >: typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type out_deg = out_degree(u,g); typedef typename boost::graph_traits< Triangulation_data_structure_2 >::out_edge_iterator Iter; - return make_range( Iter(ec), Iter(ec,out_deg) ); + return make_range(Iter(ec), Iter(ec,out_deg)); } template @@ -513,7 +270,7 @@ in_edges(typename boost::graph_traits< Triangulation_data_structure_2 >:: typename Triangulation_data_structure_2::Edge_circulator ec(u,u->face()); typename boost::graph_traits< Triangulation_data_structure_2 >::degree_size_type out_deg = out_degree(u,g); typedef typename boost::graph_traits< Triangulation_data_structure_2 >::in_edge_iterator Iter; - return make_range( Iter(ec), Iter(ec,out_deg) ); + return make_range(Iter(ec), Iter(ec,out_deg)); } template @@ -585,238 +342,6 @@ degree(typename boost::graph_traits< Triangulation_data_structure_2 >::ve return deg; } -// property maps -template -class TDS2_vertex_id_map - : public boost::put_get_helper > -{ -public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle key_type; - - TDS2_vertex_id_map() {} - - long operator[](key_type vh) const { return vh->id(); } -}; - -template -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::Vertex_handle key_type; - - friend reference get(TDS2_vertex_point_map, key_type vh) { return vh->point(); } - friend void put(TDS2_vertex_point_map, key_type vh, reference v) { vh->point() = v; } - reference operator[](key_type vh) const { return vh->point(); } -}; - -template -class TDS2_edge_id_map - : public boost::put_get_helper > -{ -public: - typedef boost::readable_property_map_tag category; - typedef int value_type; - typedef int reference; - typedef typename CGAL::Triangulation_data_structure_2::Edge key_type; - - TDS2_edge_id_map() {} - - long operator[](key_type e) const { return (3 * e.first.id()) + e.second; } -}; - -template -class TDS2_edge_weight_map - : public boost::put_get_helper > -{ -private: - const CGAL::Triangulation_data_structure_2& 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::Edge key_type; - - TDS2_edge_weight_map(const CGAL::Triangulation_data_structure_2& tr_) : tr(tr_) { } - - value_type operator[](key_type e) const { return approximate_sqrt(tr.segment(e).squared_length()); } -}; - -template -inline TDS2_vertex_id_map -get(boost::vertex_index_t, const Triangulation_data_structure_2&) -{ - TDS2_vertex_id_map m; - return m; -} - -template -inline TDS2_vertex_point_map -get(boost::vertex_point_t, const Triangulation_data_structure_2&) -{ - TDS2_vertex_point_map m; - return m; -} - -template -inline TDS2_edge_id_map -get(boost::edge_index_t, const Triangulation_data_structure_2&) -{ - TDS2_edge_id_map m; - return m; -} - -template -inline TDS2_edge_weight_map -get(boost::edge_weight_t, const Triangulation_data_structure_2& g) -{ - TDS2_edge_weight_map m(g); - return m; -} - -template -struct TDS2_property_map { }; - -template <> -struct TDS2_property_map -{ - template - struct bind_ { - typedef TDS2_vertex_id_map type; - typedef TDS2_vertex_id_map const_type; - }; -}; - - - -template <> -struct TDS2_property_map -{ - template - struct bind_ { - typedef TDS2_vertex_point_map type; - typedef TDS2_vertex_point_map const_type; - }; -}; - - -template <> -struct TDS2_property_map -{ - template - struct bind_ { - typedef TDS2_edge_id_map type; - typedef TDS2_edge_id_map const_type; - }; -}; - - -template <> -struct TDS2_property_map -{ - template - struct bind_ { - typedef TDS2_edge_weight_map type; - typedef TDS2_edge_weight_map const_type; - }; -}; - } // namespace CGAL -namespace boost { -// g++ 'enumeral_type' in template unification not implemented workaround -template -struct property_map, Tag> -{ - typedef typename - CGAL::TDS2_property_map::template bind_ 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 -struct property_map, Tag> -{ - typedef typename - CGAL::TDS2_property_map::template bind_ map_gen; - typedef typename map_gen::type type; - typedef typename map_gen::const_type const_type; -}; - -} // namespace boost - - -namespace CGAL { - -template -inline -typename boost::property_traits< -typename boost::property_map,PropertyTag>::const_type>::value_type -get(PropertyTag p, const Triangulation_data_structure_2& g, const Key& key) -{ - return get(get(p, g), key); -} - -template -inline void -put(PropertyTag p, Triangulation_data_structure_2& g, - const Key& key, const Value& value) -{ - typedef typename boost::property_map, PropertyTag>::type Map; - Map pmap = get(p, g); - put(pmap, key, value); -} - -} // namespace CGAL - -namespace boost { - -// What are those needed for ??? -template -struct edge_property_type > { - typedef void type; -}; - -template -struct vertex_property_type > { - 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 -struct hash > -{ - std::size_t operator()(const CGAL::detail::TDS2_edge_descriptor& e) const { return hash_value(e); } -}; - -template -struct hash > -{ - std::size_t operator()(const CGAL::detail::TDS2_halfedge_descriptor& 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 diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation.h index a6065a2fa6f..1684327ec32 100644 --- a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation.h +++ b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation.h @@ -31,6 +31,8 @@ #error CGAL_2D_TRIANGULATION_TEMPLATES is not defined #endif +#include + #include #include #include @@ -41,367 +43,6 @@ #include -// 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 -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(*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 -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() { 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 -struct T2_halfedge_iterator -{ -private: - typedef T2_halfedge_iterator Self; - typedef typename Tr::Finite_edges_iterator Finite_edges_iterator; - typedef T2_halfedge_descriptor 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 -struct T2_edge_iterator -{ -private: - typedef T2_edge_iterator Self; - typedef typename Tr::Finite_edges_iterator Finite_edges_iterator; - typedef T2_edge_descriptor 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 -struct T2_edge_circulator - : public Tr::Edge_circulator -{ -private: - typedef T2_edge_circulator Self; - typedef typename Tr::Edge Edge; - typedef typename Tr::Edge_circulator Base; - -public: - typedef T2_edge_descriptor 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 -struct In_edge_circulator - : public T2_edge_circulator -{ -private: - typedef T2_edge_circulator Base; - typedef typename Tr::Edge Edge; - typedef typename Tr::Edge_circulator Edge_circulator; - -public: - typedef T2_edge_descriptor 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 -struct Out_edge_circulator - : public T2_edge_circulator -{ -private: - typedef T2_edge_circulator Base; - typedef typename Tr::Edge Edge; - typedef typename Tr::Edge_circulator Edge_circulator; - -public: - typedef T2_edge_descriptor 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 -struct T2_vertex_circulator - : public In_edge_circulator -{ -private: - typedef In_edge_circulator Base; - typedef T2_edge_descriptor 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 -struct Dereference_to_handle_enforcer - : public boost::iterator_adaptor< - Dereference_to_handle_enforcer, - Iterator /*base*/, - Handle /*value*/, - boost::use_default, - Handle /*reference*/ - > -{ -public: - typedef Handle value_type; - -private: - typedef Dereference_to_handle_enforcer Self; - typedef Iterator I; - typedef boost::iterator_adaptor 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 > -{ - std::size_t operator()(const CGAL::detail::T2_halfedge_descriptor& 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 { template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS > @@ -417,28 +58,30 @@ struct graph_traits< CGAL_2D_TRIANGULATION > { }; typedef typename Triangulation::Vertex_handle vertex_descriptor; - typedef CGAL::detail::T2_halfedge_descriptor halfedge_descriptor; - typedef CGAL::detail::T2_edge_descriptor edge_descriptor; + typedef CGAL::internal::T2_halfedge_descriptor halfedge_descriptor; + typedef CGAL::internal::T2_edge_descriptor edge_descriptor; typedef typename Triangulation::Face_handle face_descriptor; // 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) - typedef CGAL::detail::Dereference_to_handle_enforcer< + typedef CGAL::internal::Dereference_to_handle_enforcer< Triangulation, typename Triangulation::Finite_vertices_iterator, vertex_descriptor> vertex_iterator; - typedef CGAL::detail::Dereference_to_handle_enforcer< + typedef CGAL::internal::Dereference_to_handle_enforcer< Triangulation, typename Triangulation::Finite_faces_iterator, face_descriptor> face_iterator; - typedef CGAL::detail::T2_halfedge_iterator halfedge_iterator; - typedef CGAL::detail::T2_edge_iterator edge_iterator; + typedef CGAL::internal::T2_halfedge_iterator halfedge_iterator; + typedef CGAL::internal::T2_edge_iterator edge_iterator; - typedef CGAL::detail::T2_vertex_circulator Vertex_circulator; + typedef CGAL::internal::T2_vertex_circulator Vertex_circulator; typedef CGAL::Counting_iterator adjacency_iterator; - typedef CGAL::detail::In_edge_circulator In_edge_circ; + typedef CGAL::internal::In_edge_circulator In_edge_circ; typedef CGAL::Counting_iterator in_edge_iterator; - typedef CGAL::detail::Out_edge_circulator Out_edge_circ; + typedef CGAL::internal::Out_edge_circulator Out_edge_circ; typedef CGAL::Counting_iterator out_edge_iterator; typedef undirected_tag directed_category; @@ -757,7 +400,7 @@ inline Iterator_range::in_ in_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, 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; typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face()); @@ -771,7 +414,7 @@ inline Iterator_range::out out_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, 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; typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face()); @@ -785,7 +428,7 @@ inline Iterator_range::adj adjacent_vertices(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v, 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; typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face()); diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h new file mode 100644 index 00000000000..ec2c625735f --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h @@ -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 +#include +#include + +#include +#include +#include + +#include + +#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 +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(*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 +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() { 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 +struct T2_halfedge_iterator +{ +private: + typedef T2_halfedge_iterator Self; + typedef EdgeIterator Edge_iterator; + typedef T2_halfedge_descriptor 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 +struct T2_edge_iterator +{ +private: + typedef T2_edge_iterator Self; + typedef EdgeIterator Edge_iterator; + typedef T2_edge_descriptor 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 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(this)->operator*(); + e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first)); + return e; + } +}; + +template +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(this)->operator*(); + e = E(ed); + return e; + } +}; + +template +struct T2_edge_circulator + : public Tr::Edge_circulator +{ +private: + typedef T2_edge_circulator Self; + typedef typename Tr::Edge Edge; + typedef typename Tr::Edge_circulator Base; + +public: + typedef T2_edge_descriptor 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 +struct In_edge_circulator + : public T2_edge_circulator +{ +private: + typedef T2_edge_circulator Base; + typedef typename Tr::Edge Edge; + typedef typename Tr::Edge_circulator Edge_circulator; + +public: + typedef T2_edge_descriptor 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 +struct Out_edge_circulator + : public T2_edge_circulator +{ +private: + typedef T2_edge_circulator Base; + typedef typename Tr::Edge Edge; + typedef typename Tr::Edge_circulator Edge_circulator; + +public: + typedef T2_edge_descriptor 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 +struct T2_vertex_circulator + : public In_edge_circulator +{ +private: + typedef In_edge_circulator Base; + typedef T2_edge_descriptor 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 +struct Dereference_to_handle_enforcer + : public boost::iterator_adaptor< + Dereference_to_handle_enforcer, + Iterator /*base*/, + Handle /*value*/, + boost::use_default, + Handle /*reference*/ + > +{ +public: + typedef Handle value_type; + +private: + typedef Dereference_to_handle_enforcer Self; + typedef Iterator I; + typedef boost::iterator_adaptor 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 +struct iterator_traits< CGAL::internal::T2_halfedge_descriptor > +{ + 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 > +{ + std::size_t operator()(const CGAL::internal::T2_halfedge_descriptor& 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 diff --git a/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h b/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h index 945d56f157d..c81e606973f 100644 --- a/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h +++ b/Triangulation_2/include/CGAL/boost/graph/internal/properties_2D_triangulation.h @@ -35,7 +35,7 @@ #define CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H namespace CGAL { -namespace detail { +namespace internal { template struct T2_halfedge_descriptor; @@ -113,9 +113,9 @@ public: typedef boost::readable_property_map_tag category; typedef int value_type; typedef int reference; - typedef CGAL::detail::T2_halfedge_descriptor key_type; + typedef CGAL::internal::T2_halfedge_descriptor 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) { } @@ -123,8 +123,8 @@ public: // 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); + const Face_handle f1 = h.first; + const Face_handle f2 = f1->neighbor(h.second); CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2)); if(tr.is_infinite(f1)) @@ -149,15 +149,15 @@ public: typedef boost::readable_property_map_tag category; typedef int value_type; typedef int reference; - typedef CGAL::detail::T2_edge_descriptor key_type; - typedef typename Tr::Face_handle face_descriptor; + typedef CGAL::internal::T2_edge_descriptor key_type; + typedef typename Tr::Face_handle Face_handle; T2_edge_id_map(const Tr& tr) : tr(tr) { } value_type operator[](key_type e) const { - const face_descriptor f1 = e.first; - const face_descriptor f2 = f1->neighbor(e.second); + const Face_handle f1 = e.first; + const Face_handle f2 = f1->neighbor(e.second); CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2)); if(tr.is_infinite(f1)) @@ -201,47 +201,46 @@ struct T2_property_map { }; template struct T2_property_map { - typedef detail::T2_vertex_point_map type; - typedef detail::T2_vertex_point_map const_type; + typedef internal::T2_vertex_point_map type; + typedef internal::T2_vertex_point_map const_type; }; template struct T2_property_map { - typedef detail::T2_edge_weight_map type; - typedef detail::T2_edge_weight_map const_type; + typedef internal::T2_edge_weight_map type; + typedef internal::T2_edge_weight_map const_type; }; template struct T2_property_map { - typedef detail::T2_vertex_id_map type; - typedef detail::T2_vertex_id_map const_type; + typedef internal::T2_vertex_id_map type; + typedef internal::T2_vertex_id_map const_type; }; template struct T2_property_map { - typedef detail::T2_halfedge_id_map type; - typedef detail::T2_halfedge_id_map const_type; + typedef internal::T2_halfedge_id_map type; + typedef internal::T2_halfedge_id_map const_type; }; template struct T2_property_map { - typedef detail::T2_edge_id_map type; - typedef detail::T2_edge_id_map const_type; + typedef internal::T2_edge_id_map type; + typedef internal::T2_edge_id_map const_type; }; template struct T2_property_map { - typedef detail::T2_face_id_map type; - typedef detail::T2_face_id_map const_type; + typedef internal::T2_face_id_map type; + typedef internal::T2_face_id_map const_type; }; -} // end namespace detail - +} // end namespace internal } // CGAL #endif // CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H @@ -253,7 +252,7 @@ namespace boost { template struct property_map { - typedef typename CGAL::detail::T2_property_map map_gen; + typedef typename CGAL::internal::T2_property_map map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; @@ -262,7 +261,7 @@ struct property_map template struct property_map { - typedef typename CGAL::detail::T2_property_map map_gen; + typedef typename CGAL::internal::T2_property_map map_gen; typedef typename map_gen::type type; typedef typename map_gen::const_type const_type; }; @@ -313,50 +312,50 @@ struct graph_has_property // property maps 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&) { - detail::T2_vertex_point_map< CGAL_2D_TRIANGULATION > m; + internal::T2_vertex_point_map< CGAL_2D_TRIANGULATION > m; return m; } 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) { - detail::T2_edge_weight_map< CGAL_2D_TRIANGULATION > m(g); + internal::T2_edge_weight_map< CGAL_2D_TRIANGULATION > m(g); return m; } 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) { - detail::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m(g); + internal::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } 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) { - detail::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > m(g); + internal::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } 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) { - detail::T2_edge_id_map< CGAL_2D_TRIANGULATION > m(g); + internal::T2_edge_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } 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) { - detail::T2_face_id_map< CGAL_2D_TRIANGULATION > m(g); + internal::T2_face_id_map< CGAL_2D_TRIANGULATION > m(g); return m; } diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h new file mode 100644 index 00000000000..a2cb3d1411c --- /dev/null +++ b/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h @@ -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 +#include +#include + +#include + +#include + +namespace CGAL { +namespace internal { + +// property maps +template +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::Vertex_handle key_type; + + friend reference get(TDS2_vertex_point_map, key_type vh) { return vh->point(); } + friend void put(TDS2_vertex_point_map, key_type vh, reference v) { vh->point() = v; } + reference operator[](key_type vh) const { return vh->point(); } +}; + +template +class TDS2_edge_weight_map + : public boost::put_get_helper > +{ +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::Edge key_type; + + TDS2_edge_weight_map(const CGAL::Triangulation_data_structure_2& 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& tds; +}; + +template +class TDS2_vertex_id_map + : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef typename CGAL::Triangulation_data_structure_2::Vertex_handle key_type; + + TDS2_vertex_id_map() {} + + long operator[](key_type vh) const { return vh->id(); } +}; + +template +class TDS2_halfedge_id_map + : public boost::put_get_helper > +{ + typedef typename CGAL::Triangulation_data_structure_2 TDS; + +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef CGAL::internal::T2_halfedge_descriptor 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 TDS2_edge_id_map + : public boost::put_get_helper > +{ + typedef typename CGAL::Triangulation_data_structure_2 TDS; + +public: + typedef boost::readable_property_map_tag category; + typedef int value_type; + typedef int reference; + typedef CGAL::internal::T2_edge_descriptor 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 TDS2_face_id_map + : public boost::put_get_helper > +{ + typedef typename CGAL::Triangulation_data_structure_2 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 +struct TDS2_property_map { }; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_vertex_point_map type; + typedef internal::TDS2_vertex_point_map const_type; +}; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_edge_weight_map type; + typedef internal::TDS2_edge_weight_map const_type; +}; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_vertex_id_map type; + typedef internal::TDS2_vertex_id_map const_type; +}; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_vertex_id_map type; + typedef internal::TDS2_vertex_id_map const_type; +}; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_edge_id_map type; + typedef internal::TDS2_edge_id_map const_type; +}; + +template +struct TDS2_property_map +{ + typedef internal::TDS2_vertex_id_map type; + typedef internal::TDS2_vertex_id_map const_type; +}; + +} // end namespace internal + +template +struct graph_has_property, boost::vertex_point_t> + : CGAL::Tag_true{}; +template +struct graph_has_property, boost::edge_weight_t> + : CGAL::Tag_true{}; + +template +struct graph_has_property, boost::vertex_index_t> + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL::Triangulation_data_structure_2::Vertex + >::value + > +{}; +template +struct graph_has_property, boost::halfedge_index_t> + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL::Triangulation_data_structure_2::Face + >::value + > +{}; +template +struct graph_has_property, boost::edge_index_t> + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL::Triangulation_data_structure_2::Face + >::value + > +{}; +template +struct graph_has_property, boost::face_index_t> + : CGAL::Boolean_tag< + CGAL::internal::Has_member_id< + typename CGAL::Triangulation_data_structure_2::Face + >::value + > +{}; + +template +inline internal::TDS2_vertex_point_map +get(boost::vertex_point_t, const Triangulation_data_structure_2&) +{ + internal::TDS2_vertex_point_map m; + return m; +} + +template +inline internal::TDS2_edge_weight_map +get(boost::edge_weight_t, const Triangulation_data_structure_2& g) +{ + internal::TDS2_edge_weight_map m(g); + return m; +} + +template +inline internal::TDS2_vertex_id_map +get(boost::vertex_index_t, const Triangulation_data_structure_2&) +{ + internal::TDS2_vertex_id_map m; + return m; +} + +template +inline internal::TDS2_halfedge_id_map +get(boost::halfedge_index_t, const Triangulation_data_structure_2&) +{ + internal::TDS2_halfedge_id_map m; + return m; +} + +template +inline internal::TDS2_edge_id_map +get(boost::edge_index_t, const Triangulation_data_structure_2&) +{ + internal::TDS2_edge_id_map m; + return m; +} + +template +inline internal::TDS2_face_id_map +get(boost::face_index_t, const Triangulation_data_structure_2&) +{ + internal::TDS2_face_id_map m; + return m; +} + +} // namespace CGAL + +namespace boost { + +// g++ 'enumeral_type' in template unification not implemented workaround +template +struct property_map, Tag> +{ + typedef typename CGAL::internal::TDS2_property_map 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 +struct property_map, Tag> +{ + typedef typename CGAL::internal::TDS2_property_map map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; +}; + +} // namespace boost + +namespace CGAL { + +template +inline +typename boost::property_traits< +typename boost::property_map,PropertyTag>::const_type>::value_type +get(PropertyTag p, const Triangulation_data_structure_2& g, const Key& key) +{ + return get(get(p, g), key); +} + +template +inline void +put(PropertyTag p, Triangulation_data_structure_2& g, + const Key& key, const Value& value) +{ + typedef typename boost::property_map, PropertyTag>::type Map; + Map pmap = get(p, g); + put(pmap, key, value); +} + +} // namespace CGAL + +namespace boost { + +// What are those needed for ??? +template +struct edge_property_type > { + typedef void type; +}; + +template +struct vertex_property_type > { + typedef void type; +}; + +} // namespace boost + +#endif /* CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H */