cgal/Arrangement_2/include/CGAL/graph_traits_Dual_Arrangeme...

622 lines
19 KiB
C++

// Copyright (c) 2005 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Ron Wein <wein@post.tau.ac.il>
// Ophir Setter <ophirset@post.tau.ac.il>
#ifndef BOOST_GRAPH_TRAITS_DUAL_ARRANGEMENT_2_H
#define BOOST_GRAPH_TRAITS_DUAL_ARRANGEMENT_2_H
/*! \file
* Definition of the specialized Dual<Arrangement_2> class,
* and the specialized boost::graph_traits<Dual<Arrangement_2> >class.
*/
#include <CGAL/Arrangement_2.h>
CGAL_BEGIN_NAMESPACE
// Forward declaration.
template <class Type> class Dual;
/*! \class
* Specilaization of the Dual<> template for Arrangement_2.
*/
template <class Traits_, class Dcel_>
class Dual<Arrangement_2<Traits_, Dcel_> >
{
public:
typedef Traits_ Traits_2;
typedef Dcel_ Dcel;
typedef CGAL::Arrangement_2<Traits_2, Dcel> Arrangement_2;
typedef typename Arrangement_2::Size Size;
typedef typename Arrangement_2::Face_handle Vertex_handle;
typedef typename Arrangement_2::Halfedge_handle Edge_handle;
typedef typename Arrangement_2::Face_iterator Vertex_iterator;
typedef typename Arrangement_2::Halfedge_iterator Edge_iterator;
protected:
typedef typename Arrangement_2::Face_handle Face_handle;
typedef typename Arrangement_2::Ccb_halfedge_circulator
Ccb_halfedge_circulator;
typedef typename Arrangement_2::Hole_iterator Hole_iterator;
/*! \class
* Iterator over the neighbors of a dual vertex (a face in the primal
* arrangement).
* These neighbors are the adjacent faces along the outer boundary of the
* face (if it is bounded), and its holes.
*/
class Face_neighbor_iterator
{
typedef Face_neighbor_iterator Self;
public:
typedef std::forward_iterator_tag iterator_category;
typedef Edge_handle value_type;
typedef value_type reference;
typedef value_type* pointer;
typedef int difference_type;
private:
bool _has_outer_ccb;
bool _ccb_incremented;
Ccb_halfedge_circulator _outer_ccb_circ;
Hole_iterator _hole_iter;
Ccb_halfedge_circulator _curr_hole_circ;
bool _curr_hole_incremented;
Face_handle _face;
bool _out;
Edge_handle _hh;
public:
/*! Default constructor. */
Face_neighbor_iterator ()
{}
/*!
* Constructor.
* \param face The face (dual vertex).
* \param out_edges Do we need the outgoing or the ingoing halfedges.
* \param start Should we start traversing the edges.
* If false, we construct a past-the-end iterator.
*/
Face_neighbor_iterator (Face_handle face,
bool out_edges,
bool start) :
_face (face),
_out (out_edges)
{
_has_outer_ccb = !(face->is_unbounded());
_ccb_incremented = true;
if (_has_outer_ccb)
{
_outer_ccb_circ = face->outer_ccb();
_ccb_incremented = !start;
}
if (start)
{
_hole_iter = face->holes_begin();
_curr_hole_incremented = true;
if (_hole_iter != face->holes_end())
{
_curr_hole_circ = *_hole_iter;
_curr_hole_incremented = false;
}
_hh = this->_dereference();
}
else // end iterator.
{
_hole_iter = face->holes_end();
}
}
/*! Equality operators. */
bool operator== (const Self& it) const
{
return (this->_equal(it));
}
bool operator!= (const Self& it) const
{
return (! this->_equal(it));
}
/*! Dereference operators. */
reference operator* () const
{
return (_hh);
}
pointer operator-> () const
{
return (&_hh);
}
/* Increment operators. */
Self& operator++ ()
{
this->_increment();
_hh = this->_dereference();
return (*this);
}
Self operator++ (int )
{
Self tmp = *this;
this->_increment();
_hh = this->_dereference();
return (tmp);
}
private:
/*! Check two iterators for equality. */
bool _equal (const Self& it) const
{
return (_out == it._out &&
_has_outer_ccb == it._has_outer_ccb &&
_ccb_incremented == it._ccb_incremented &&
_outer_ccb_circ == it._outer_ccb_circ &&
_hole_iter == it._hole_iter &&
_face == it._face);
}
/*! Derefernce the current circulator. */
Edge_handle _dereference () const
{
if (_has_outer_ccb)
{
if (! _ccb_incremented ||
_outer_ccb_circ != _face->outer_ccb())
{
if (_out)
return (_outer_ccb_circ);
else
return (_outer_ccb_circ->twin());
}
}
if (_out)
return (_curr_hole_circ);
else
return (_curr_hole_circ->twin());
}
// Increments of the iterator.
void _increment ()
{
if (_has_outer_ccb)
{
if (! _ccb_incremented)
{
++_outer_ccb_circ;
_ccb_incremented = true;
return;
}
if (_outer_ccb_circ != _face->outer_ccb())
{
++_outer_ccb_circ;
return;
}
}
if (_hole_iter != _face->holes_end())
{
if (! _curr_hole_incremented)
{
++_curr_hole_circ;
_curr_hole_incremented = true;
return;
}
if (_curr_hole_circ != *_hole_iter)
{
++_curr_hole_circ;
return;
}
++_hole_iter;
if (_hole_iter != _face->holes_end())
{
_curr_hole_circ = *_hole_iter;
_curr_hole_incremented = false;
}
}
return;
}
};
// Data members:
mutable Arrangement_2 *p_arr; // The primal arrangement.
public:
typedef Face_neighbor_iterator Incident_edge_iterator;
/*! Default constructor. */
Dual () :
p_arr (NULL)
{}
/*! Constructor from an arrangement. */
Dual (const Arrangement_2& arr) :
p_arr (const_cast<Arrangement_2 *> (&arr))
{}
/*! Get the number of vertices (face of the primal arrangement). */
Size number_of_vertices () const
{
return (p_arr->number_of_faces());
}
/*! Traverse the vertices (faces of the primal arrangement). */
Vertex_iterator vertices_begin () const
{
return (p_arr->faces_begin());
}
Vertex_iterator vertices_end () const
{
return (p_arr->faces_end());
}
/*! Get the number of edges. */
Size number_of_edges () const
{
return (p_arr->number_of_halfedges());
}
/*! Traverse the edges. */
Edge_iterator edges_begin () const
{
return (p_arr->halfedges_begin());
}
Edge_iterator edges_end () const
{
return (p_arr->halfedges_end());
}
/*!
* Get the dual vertex-degree (number of edges forming the face boundary).
*/
Size degree (Vertex_handle v) const
{
Incident_edge_iterator begin = Incident_edge_iterator (v, true, true);
Incident_edge_iterator end = Incident_edge_iterator (v, false, true);
Size deg = 0;
while (begin != end)
{
deg++;
++begin;
}
return (deg);
}
/*! Traverse the outgoing edges of a given vertex. */
Incident_edge_iterator out_edges_begin (Vertex_handle v) const
{
return (Incident_edge_iterator (v, true, true));
}
Incident_edge_iterator out_edges_end (Vertex_handle v) const
{
return (Incident_edge_iterator (v, true, false));
}
/*! Traverse the ingoing edges of a given vertex. */
Incident_edge_iterator in_edges_begin (Vertex_handle v) const
{
return (Incident_edge_iterator (v, false, true));
}
Incident_edge_iterator in_edges_end (Vertex_handle v) const
{
return (Incident_edge_iterator (v, false, false));
}
};
CGAL_END_NAMESPACE
#include <boost/graph/graph_concepts.hpp>
#include <boost/iterator/counting_iterator.hpp>
namespace boost {
/*! \class
* Specialization of the BGL graph-traits template, which serve as a dual
* adapter for Arrangment_2, where the arrangement faces correspond to graph
* verices, and two graph vertices are connected if the two corrsponding
* faces are adjacent.
* We consider the graph as directed. We also allow parallel edges, as two
* faces may have more than one common edges.
*/
template <class Traits_, class Dcel_>
class graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >
{
public:
typedef Traits_ Traits_2;
typedef Dcel_ Dcel;
typedef CGAL::Arrangement_2<Traits_2, Dcel> Arrangement_2;
typedef CGAL::Dual<Arrangement_2> Dual_arr_2;
private:
typedef typename Dual_arr_2::Vertex_iterator Vertex_iterator;
typedef typename Dual_arr_2::Edge_iterator Edge_iterator;
typedef typename Dual_arr_2::Incident_edge_iterator Incident_edge_iterator;
/*! \struct
* Define the arrangement traversal category, which indicates the arrangement
* models the BidirectionalGraph concept and the VertexListGraph and
* EdgeListGraph concepts.
*/
struct Dual_arr_traversal_category :
public virtual boost::bidirectional_graph_tag, // This tag refines the
// incidence_graph_tag.
public virtual boost::vertex_list_graph_tag, // Can iterate over vertices.
public virtual boost::edge_list_graph_tag // Can iterate over edges.
{};
public:
// Types required of the Graph concept:
typedef typename Dual_arr_2::Vertex_handle vertex_descriptor;
typedef boost::directed_tag directed_category;
typedef boost::allow_parallel_edge_tag edge_parallel_category;
typedef Dual_arr_traversal_category traversal_category;
// Types required by the IncidenceGraph concept:
typedef typename Dual_arr_2::Edge_handle edge_descriptor;
typedef Incident_edge_iterator out_edge_iterator;
typedef typename Dual_arr_2::Size degree_size_type;
// Types required by the BidirectionalGraph concept:
typedef Incident_edge_iterator in_edge_iterator;
// Types required by the VertexListGraph concept:
typedef boost::counting_iterator<Vertex_iterator> vertex_iterator;
typedef typename Dual_arr_2::Size vertices_size_type;
// Types required by the EdgeListGraph concept:
typedef boost::counting_iterator<Edge_iterator> edge_iterator;
typedef typename Dual_arr_2::Size edges_size_type;
// Types not required by any of these concepts:
typedef void adjacency_iterator;
};
// Functions required by the IncidenceGraph concept:
// -------------------------------------------------
/*!
* Get the out-degree of a vertex in a given dual arrangement.
* \param v The vertex.
* \param darr The dual arrangement.
* \param Number of halfedges around the boundary of the primal face.
*/
template <class Traits_, class Dcel_>
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
degree_size_type out_degree
(typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
vertex_descriptor v,
const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& darr)
{
return (darr.degree (v));
}
/*!
* Return a range of the out-edges of a vertex given by its descriptor and the
* dual arrangement it belongs to.
* \param v The vertex.
* \param darr The dual arrangement.
* \return A pair of out-edges iterators.
*/
template <class Traits_, class Dcel_>
std::pair<
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
out_edge_iterator,
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
out_edge_iterator>
out_edges
(typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
vertex_descriptor v,
const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& darr)
{
return (std::make_pair (darr.out_edges_begin (v),
darr.out_edges_end (v)));
}
/*!
* Get the source vertex of a dual arrangement edge.
* \param e The edge.
* \param darr The dual arrangement.
* \return The incident face of e in the primal arrangement.
*/
template <class Traits_, class Dcel_>
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
vertex_descriptor source
(typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
edge_descriptor e,
const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& /* darr */)
{
return (e->face());
}
/*!
* Get the target vertex of a dual arrangement edge.
* \param e The edge.
* \param darr The dual arrangement.
* \return The incident face of e's twin in the primal arrangement.
*/
template <class Traits_, class Dcel_>
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
vertex_descriptor target
(typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
edge_descriptor e,
const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& /* darr */)
{
return (e->twin()->face());
}
// Functions required by the BidirectionalGraph concept:
// -----------------------------------------------------
/*!
* Get the in-degree of a vertex in a given dual arrangement.
* \param v The vertex.
* \param darr The dual arrangement.
* \param Number of halfedges around the boundary of the primal face.
*/
template <class Traits_, class Dcel_>
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
degree_size_type in_degree
(typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
vertex_descriptor v,
const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& darr)
{
return (darr.degree (v));
}
/*!
* Return a range of the in-edges of a vertex given by its descriptor and the
* dual arrangement it belongs to.
* \param v The vertex.
* \param darr The dual arrangement.
* \return A pair of in-edges iterators.
*/
template <class Traits_, class Dcel_>
std::pair<
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
in_edge_iterator,
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
in_edge_iterator>
in_edges
(typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
vertex_descriptor v,
const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& darr)
{
return (std::make_pair (darr.in_edges_begin (v),
darr.in_edges_end (v)));
}
/*!
* Get the degree of a vertex in a given dual arrangement.
* \param v The vertex.
* \param darr The dual arrangement.
* \param Number of ingoing and outgoing halfedges incident to v.
*/
template <class Traits_, class Dcel_>
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
degree_size_type degree
(typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
vertex_descriptor v,
const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& darr)
{
return (2 * darr.degree (v));
}
// Functions required by the VertexListGraph concept:
// --------------------------------------------------
/*!
* Get the number of vertices in the given dual arrangement.
* \param darr The dual arrangement.
* \return Number of faces in the primal arrangement.
*/
template <class Traits_, class Dcel_>
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
vertices_size_type num_vertices
(const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& darr)
{
return (darr.number_of_vertices());
}
/*!
* Get the range of vertices of the given dual arrangement.
* \param darr The dual arrangement.
* \return A pair of vertex iterators.
*/
template <class Traits_, class Dcel_>
std::pair<
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
vertex_iterator,
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
vertex_iterator>
vertices (const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& darr)
{
return (std::make_pair (darr.vertices_begin(),
darr.vertices_end()));
}
// Functions required by the EdgeListGraph concept:
// ------------------------------------------------
/*!
* Get the number of edges in the given dual arrangement.
* \param darr The dual arrangement.
* \return Number of halfedges in the primal arrangement.
*/
template <class Traits_, class Dcel_>
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
edges_size_type num_edges
(const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& darr)
{
return (darr.number_of_edges());
}
/*!
* Get the range of edges of the given dual arrangement.
* \param darr The dual arrangement.
* \return A pair of edge iterators.
*/
template <class Traits_, class Dcel_>
std::pair<
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
edge_iterator,
typename graph_traits<CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> > >::
edge_iterator>
edge (const CGAL::Dual<CGAL::Arrangement_2<Traits_, Dcel_> >& darr)
{
return (std::make_pair (darr.edges_begin(),
darr.edges_end()));
}
}; // namespace boost
#endif