1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
|
// Copyright (c) 2007 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL: https://github.com/CGAL/cgal/blob/v5.2/HalfedgeDS/include/CGAL/boost/graph/graph_traits_HalfedgeDS.h $
// $Id: graph_traits_HalfedgeDS.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Andreas Fabri, Fernando Cacciola
#ifndef CGAL_BOOST_GRAPH_GRAPH_TRAITS_HALFEDGEDS_H
#define CGAL_BOOST_GRAPH_GRAPH_TRAITS_HALFEDGEDS_H
#include <functional>
// include this to avoid a VC15 warning
#include <CGAL/boost/graph/Named_function_parameters.h>
#include <boost/config.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <CGAL/boost/iterator/transform_iterator.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/basic.h>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/Handle_hash_function.h>
#include <CGAL/iterator.h>
#ifndef CGAL_NO_DEPRECATED_CODE
#include <CGAL/boost/graph/halfedge_graph_traits.h>
#endif
namespace CGAL {
namespace internal {
// a HDS_halfedge pretending to be an Edge
template<typename Halfedge_handle>
struct HDS_edge {
HDS_edge() : halfedge_() { }
explicit HDS_edge(const Halfedge_handle& h) : halfedge_(h) {}
bool operator==(const HDS_edge& other) const {
// equality is tricky, we are equal when both halfedges are the
// same or when the opposite halfedge of this is the same as
// halfedge_.other but we need to be careful not to apply this
// should this be the invalid halfedge or opposite is going to
// blow up
if(halfedge_ == other.halfedge_) {
return true;
} else if(halfedge_ != Halfedge_handle()) { // not default constructed
return halfedge_->opposite() == other.halfedge_;
} else {
// this is the invalid halfedge, it can only be equal to the
// invalid halfedge and this is covered by the first case
return false;
}
}
bool operator!=(const HDS_edge& other) const {
return !(*this == other);
}
friend bool operator<(const HDS_edge& a,const HDS_edge& b)
{
if(a==b) return false;
return a.halfedge_ < b.halfedge_;
}
// forward some function to avoid boilerplate and typedefs inside
// the free functions
HDS_edge next() { return HDS_edge(halfedge_->next()); }
// this is potentially broken as it does not use the decorator to
// find prev, but we cannot instantiate the entire decorator
// without the full polyhedron type and taking all necessary
// template parameters seems overkill
HDS_edge prev() { return HDS_edge(halfedge_->prev()); }
HDS_edge opposite() { return HDS_edge(halfedge_->opposite()); }
// this is hacky, we don't know the actual type of the id and if we
// start adding decltype special cases we have to do it consistently
// up to the property map and maybe back down to Polyhedron.
std::size_t id() const { return halfedge_->id() / 2; }
Halfedge_handle halfedge() const { return halfedge_; }
// save us some work to do function chaining
HDS_edge
opposite_next() { return HDS_edge(halfedge_->opposite()->next()); }
HDS_edge
next_opposite() { return HDS_edge(halfedge_->next()->opposite()); }
HDS_edge
prev_opposite() { return HDS_edge(halfedge_->prev()->opposite()); }
HDS_edge
opposite_prev() { return HDS_edge(halfedge_->opposite()->prev()); }
friend std::size_t hash_value(const HDS_edge& i)
{
if (i.halfedge()==Halfedge_handle()) return 0;
return hash_value(i.halfedge()<i.halfedge()->opposite()?
i.halfedge():i.halfedge()->opposite());
}
private:
Halfedge_handle halfedge_;
};
// make edge_descriptor hashable by default in Unique_hash_map
namespace handle{
template<typename Halfedge_handle>
struct Hash_functor< HDS_edge<Halfedge_handle> >
{
std::size_t
operator()(const HDS_edge<Halfedge_handle>& edge)
{
Halfedge_handle he = edge.halfedge();
if (he==Halfedge_handle()) return 0;
if ( he < he->opposite() )
return Hash_functor<Halfedge_handle>()(he);
return Hash_functor<Halfedge_handle>()(he->opposite());
}
};
} //end of namespace handle
template<typename Halfedge_handle>
struct Construct_edge {
typedef HDS_edge<Halfedge_handle> result_type;
HDS_edge<Halfedge_handle> operator()(const Halfedge_handle& he) const
{ return HDS_edge<Halfedge_handle>(he); }
};
template<typename Halfedge_handle>
struct Construct_edge_opposite {
typedef HDS_edge<Halfedge_handle> result_type;
HDS_edge<Halfedge_handle> operator()(const Halfedge_handle& he) const
{ return HDS_edge<Halfedge_handle>(he->opposite()); }
};
} // internal
template <class HDS>
struct HDS_graph_traits
{
private:
struct HDS_graph_traversal_category : public virtual boost::bidirectional_graph_tag,
public virtual boost::vertex_list_graph_tag,
public virtual boost::edge_list_graph_tag
{};
public:
typedef typename HDS::Vertex_handle vertex_descriptor;
typedef typename internal::HDS_edge<typename HDS::Halfedge_handle> edge_descriptor;
typedef typename HDS::Face_handle face_descriptor;
typedef typename HDS::Halfedge_handle halfedge_descriptor;
typedef CGAL::Prevent_deref<typename HDS::Vertex_iterator> vertex_iterator;
typedef CGAL::Prevent_deref<typename HDS::Face_iterator> face_iterator;
typedef CGAL::Prevent_deref<typename HDS::Edge_iterator> edge_iterator_i;
typedef CGAL::Prevent_deref<typename HDS::Halfedge_iterator> halfedge_iterator;
typedef boost::transform_iterator<
internal::Construct_edge<typename HDS::Halfedge_handle>,
edge_iterator_i,
edge_descriptor> edge_iterator;
typedef Out_edge_iterator<HDS> out_edge_iterator;
typedef In_edge_iterator<HDS> in_edge_iterator;
typedef boost::undirected_tag directed_category;
typedef boost::disallow_parallel_edge_tag edge_parallel_category;
typedef HDS_graph_traversal_category traversal_category;
typedef typename HDS::size_type vertices_size_type;
typedef vertices_size_type edges_size_type;
typedef vertices_size_type halfedges_size_type;
typedef vertices_size_type degree_size_type;
typedef vertices_size_type faces_size_type;
static vertex_descriptor null_vertex() { return vertex_descriptor(); }
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
static face_descriptor null_face() { return face_descriptor(); }
};
} //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 <typename H>
struct hash<CGAL::internal::HDS_edge<H> > {
std::size_t operator()(const CGAL::internal::HDS_edge<H>& e) const
{
std::hash<H> fct;
if (e.halfedge()==H()) return 0;
return fct(e.halfedge()<e.halfedge()->opposite()?
e.halfedge():e.halfedge()->opposite());
}
};
#endif // CGAL_CFG_NO_STD_HASH
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
} // namespace std
#endif // CGAL_BOOST_GRAPH_GRAPH_TRAITS_HALFEDGEDS_H
|