From 129f427d93b9089d4cbc1cc7fec8abe9e8939f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 16 Dec 2021 13:48:01 +0100 Subject: [PATCH] Move TDS2's graph traits into the TDS2 package --- ...ph_traits_Triangulation_data_structure_2.h | 16 +- .../internal/graph_traits_2D_TDS_helper.h | 322 ++++++++++++++++++ ...roperties_Triangulation_data_structure_2.h | 6 +- .../graph_traits_2D_triangulation_helper.h | 298 +--------------- .../internal/properties_2D_triangulation.h | 9 +- 5 files changed, 344 insertions(+), 307 deletions(-) rename {Triangulation_2 => TDS_2}/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h (96%) create mode 100644 TDS_2/include/CGAL/boost/graph/internal/graph_traits_2D_TDS_helper.h rename {Triangulation_2 => TDS_2}/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h (98%) diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h b/TDS_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h similarity index 96% rename from Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h rename to TDS_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h index f52b8b2fb38..f4cebf72fff 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h +++ b/TDS_2/include/CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h @@ -12,11 +12,9 @@ #ifndef CGAL_GRAPH_TRAITS_TRIANGULATION_DATA_STRUCTURE_2_H #define CGAL_GRAPH_TRAITS_TRIANGULATION_DATA_STRUCTURE_2_H -#include - // include this to avoid a VC15 warning #include -#include +#include #include #include @@ -45,15 +43,15 @@ struct graph_traits > typedef CGAL::Triangulation_data_structure_2 Triangulation_data_structure; - typedef typename Triangulation_data_structure::Vertex_handle vertex_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 typename Triangulation_data_structure::Vertex_handle vertex_descriptor; + typedef CGAL::internal::TDS2_halfedge_descriptor halfedge_descriptor; + typedef CGAL::internal::TDS2_edge_descriptor edge_descriptor; + typedef typename Triangulation_data_structure::Face_handle face_descriptor; typedef CGAL::Prevent_deref vertex_iterator; - typedef CGAL::internal::T2_halfedge_iterator halfedge_iterator; - typedef CGAL::internal::T2_edge_iterator edge_iterator; typedef CGAL::Prevent_deref face_iterator; diff --git a/TDS_2/include/CGAL/boost/graph/internal/graph_traits_2D_TDS_helper.h b/TDS_2/include/CGAL/boost/graph/internal/graph_traits_2D_TDS_helper.h new file mode 100644 index 00000000000..d710a027cf2 --- /dev/null +++ b/TDS_2/include/CGAL/boost/graph/internal/graph_traits_2D_TDS_helper.h @@ -0,0 +1,322 @@ +// Copyright (c) 2019 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Mael Rouxel-Labbé + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#ifndef CGAL_GRAPH_TRAITS_2D_TDS_HELPERS +#define CGAL_GRAPH_TRAITS_2D_TDS_HELPERS + +namespace CGAL { +namespace internal { + +// A triangulation 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); + } +}; + +// An edge is just a halfedge, but we give it a complete structure to distinguish it from Tr::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() const { 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); } + + void get_canonical_edge_representation(Face_handle& fh, int& i) const + { + Face_handle neigh_fh = fh->neighbor(i); + Face_handle canonical_fh = (fh < neigh_fh) ? fh : neigh_fh; + + int canonical_i = (fh < neigh_fh) ? i : neigh_fh->index(fh); + + fh = canonical_fh; + i = canonical_i; + } + + bool operator<(const TDS2_edge_descriptor& other) const + { + if(*this == other) + return false; + + Face_handle tfh = first; + int ti = second; + get_canonical_edge_representation(tfh, ti); + + Face_handle ofh = other.first; + int oi = other.second; + get_canonical_edge_representation(ofh, oi); + + if(tfh < ofh) return true; + if(tfh > ofh) return false; + return ti < oi; + } + + 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 TDS2_edge_iterator, but it's clearer this way. +template +struct TDS2_halfedge_iterator +{ +private: + typedef TDS2_halfedge_iterator Self; + typedef EdgeIterator 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); } + + reference operator*() const + { + if(on_adjacent_face) + { + Face_handle neigh_f = it->first->neighbor(it->second); + hd = Descriptor(neigh_f, neigh_f->index(it->first)); + return hd; + } else { + hd = Descriptor(it->first, it->second); + return hd; + } + } + +private: + Edge_iterator it; + bool on_adjacent_face; + mutable Descriptor hd; +}; + +template +struct TDS2_edge_iterator +{ +private: + typedef TDS2_edge_iterator Self; + typedef EdgeIterator 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; } + + reference operator*() const + { + ed = Descriptor(*it); + return ed; + } + +private: + Edge_iterator it; + mutable Descriptor ed; +}; + +// 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; + } +}; + +} // 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::TDS2_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 +struct hash > +{ + std::size_t operator()(const CGAL::internal::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_2D_TDS_HELPERS diff --git a/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h b/TDS_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h similarity index 98% rename from Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h rename to TDS_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h index 6c3cb021bd6..86478a5c260 100644 --- a/Triangulation_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h +++ b/TDS_2/include/CGAL/boost/graph/properties_Triangulation_data_structure_2.h @@ -12,7 +12,7 @@ #define CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H #include -#include +#include #include #include @@ -81,7 +81,7 @@ public: typedef boost::readable_property_map_tag category; typedef int value_type; typedef int reference; - typedef CGAL::internal::T2_halfedge_descriptor key_type; + typedef CGAL::internal::TDS2_halfedge_descriptor key_type; typedef typename TDS::Face_handle face_descriptor; @@ -112,7 +112,7 @@ public: typedef boost::readable_property_map_tag category; typedef int value_type; typedef int reference; - typedef CGAL::internal::T2_edge_descriptor key_type; + typedef CGAL::internal::TDS2_edge_descriptor key_type; typedef typename TDS::Face_handle Face_handle; 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 index 5d94f0dc6b2..8585bc33db1 100644 --- 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 @@ -8,12 +8,11 @@ // // Author(s) : Mael Rouxel-Labbé +#include #include #include #include -#include -#include #include #include @@ -24,260 +23,19 @@ 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; +// just for clarity +template +using T2_halfedge_descriptor = TDS2_halfedge_descriptor; - 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) { } +template +using T2_halfedge_iterator = TDS2_halfedge_iterator; - const Base& base() const { return static_cast(*this); } +template +using T2_edge_descriptor = TDS2_edge_descriptor; - T2_halfedge_descriptor& operator=(const T2_halfedge_descriptor& h) - { - this->first = h.first; - this->second = h.second; - return *this; - } +template +using T2_edge_iterator = TDS2_edge_iterator; - friend std::size_t hash_value(const T2_halfedge_descriptor& e) { - return hash_value(e.first); - } -}; - -// 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() const { 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); } - - void get_canonical_edge_representation(Face_handle& fh, int& i) const - { - Face_handle neigh_fh = fh->neighbor(i); - Face_handle canonical_fh = (fh < neigh_fh) ? fh : neigh_fh; - - int canonical_i = (fh < neigh_fh) ? i : neigh_fh->index(fh); - - fh = canonical_fh; - i = canonical_i; - } - - bool operator<(const T2_edge_descriptor& other) const - { - if(*this == other) - return false; - - Face_handle tfh = first; - int ti = second; - get_canonical_edge_representation(tfh, ti); - - Face_handle ofh = other.first; - int oi = other.second; - get_canonical_edge_representation(ofh, oi); - - if(tfh < ofh) return true; - if(tfh > ofh) return false; - return ti < oi; - } - - 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); } - - reference operator*() const - { - if(on_adjacent_face) - { - Face_handle neigh_f = it->first->neighbor(it->second); - hd = Descriptor(neigh_f, neigh_f->index(it->first)); - return hd; - } else { - hd = Descriptor(it->first, it->second); - return hd; - } - } - -private: - Edge_iterator it; - bool on_adjacent_face; - mutable Descriptor hd; -}; - -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; } - - reference operator*() const - { - ed = Descriptor(*it); - return ed; - } - -private: - Edge_iterator it; - mutable Descriptor ed; -}; - -// 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 @@ -422,40 +180,4 @@ private: } // 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 5cdde7ec8f8..7111e237ef6 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 @@ -9,6 +9,7 @@ // Author(s) : Mael Rouxel-Labbé #include +#include #include #include @@ -20,7 +21,7 @@ #error CGAL_2D_TRIANGULATION is not defined #endif -// note only the properties below are protected by the macro, +// note that only the properties below are protected by the macro, // the rest of the file is the shared implementation of properties for all 2D triangulations #ifndef CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H #define CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H @@ -28,12 +29,6 @@ namespace CGAL { namespace internal { -template -struct T2_halfedge_descriptor; - -template -struct T2_edge_descriptor; - template class T2_vertex_point_map {