cgal/BGL/include/CGAL/boost/graph/graph_traits_HalfedgeDS.h

198 lines
6.5 KiB
C++

// Copyright (c) 2007 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$
//
//
// Author(s) : Andreas Fabri, Fernando Cacciola
#ifndef CGAL_BOOST_GRAPH_GRAPH_TRAITS_HALFEDGEDS_H
#define CGAL_BOOST_GRAPH_GRAPH_TRAITS_HALFEDGEDS_H
#include <boost/config.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/basic.h>
#include <CGAL/boost/graph/iterator.h>
namespace CGAL {
namespace internal {
template<typename I>
class Prevent_deref
: public boost::iterator_adaptor<
Prevent_deref<I>
, I // base
, I // value
>
{
public:
typedef boost::iterator_adaptor<
Prevent_deref<I>
, I // base
, I // value
> Base;
// typedef typename Prevent_deref::iterator_adaptor_::reference reference;
typedef typename Base::reference reference;
Prevent_deref() : Base() {};
Prevent_deref(const I& i) : Base(i) {};
private:
friend class boost::iterator_core_access;
reference dereference() const { return const_cast<reference&>(this->base_reference()); }
};
// 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()); }
private:
Halfedge_handle halfedge_;
};
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 internal::Prevent_deref<typename HDS::Vertex_iterator> vertex_iterator;
typedef internal::Prevent_deref<typename HDS::Face_iterator> face_iterator;
typedef internal::Prevent_deref<typename HDS::Edge_iterator> edge_iterator_i;
typedef internal::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
#endif // CGAL_BOOST_GRAPH_GRAPH_TRAITS_HALFEDGEDS_H