Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/graph/make_maximal_planar.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/graph/make_maximal_planar.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,275 @@ +//======================================================================= +// Copyright 2007 Aaron Windsor +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= +#ifndef __MAKE_MAXIMAL_PLANAR_HPP__ +#define __MAKE_MAXIMAL_PLANAR_HPP__ + +#include <boost/config.hpp> +#include <boost/tuple/tuple.hpp> //for tie +#include <boost/graph/biconnected_components.hpp> +#include <boost/property_map/property_map.hpp> +#include <vector> +#include <iterator> +#include <algorithm> + +#include <boost/graph/planar_face_traversal.hpp> +#include <boost/graph/planar_detail/add_edge_visitors.hpp> + + +namespace boost +{ + + + template <typename Graph, typename VertexIndexMap, typename AddEdgeVisitor> + struct triangulation_visitor : public planar_face_traversal_visitor + { + + typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; + typedef typename graph_traits<Graph>::edge_descriptor edge_t; + typedef typename graph_traits<Graph>::vertices_size_type v_size_t; + typedef typename graph_traits<Graph>::degree_size_type degree_size_t; + typedef typename graph_traits<Graph>::edge_iterator edge_iterator_t; + typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t; + typedef typename graph_traits<Graph>::adjacency_iterator + adjacency_iterator_t; + typedef typename std::vector<vertex_t> vertex_vector_t; + typedef typename std::vector<v_size_t> v_size_vector_t; + typedef typename std::vector<degree_size_t> degree_size_vector_t; + typedef iterator_property_map + < typename v_size_vector_t::iterator, VertexIndexMap > + vertex_to_v_size_map_t; + typedef iterator_property_map + < typename degree_size_vector_t::iterator, VertexIndexMap > + vertex_to_degree_size_map_t; + typedef typename vertex_vector_t::iterator face_iterator; + + + triangulation_visitor(Graph& arg_g, + VertexIndexMap arg_vm, + AddEdgeVisitor arg_add_edge_visitor + ) : + g(arg_g), + vm(arg_vm), + add_edge_visitor(arg_add_edge_visitor), + timestamp(0), + marked_vector(num_vertices(g), timestamp), + degree_vector(num_vertices(g), 0), + marked(marked_vector.begin(), vm), + degree(degree_vector.begin(), vm) + { + vertex_iterator_t vi, vi_end; + for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) + put(degree, *vi, out_degree(*vi, g)); + } + + template <typename Vertex> + void next_vertex(Vertex v) + { + // Self-loops will appear as consecutive vertices in the list of + // vertices on a face. We want to skip these. + if (!vertices_on_face.empty() && + (vertices_on_face.back() == v || vertices_on_face.front() == v) + ) + return; + + vertices_on_face.push_back(v); + } + + void end_face() + { + ++timestamp; + + if (vertices_on_face.size() <= 3) + { + // At most three vertices on this face - don't need to triangulate + vertices_on_face.clear(); + return; + } + + // Find vertex on face of minimum degree + degree_size_t min_degree = num_vertices(g); + typename vertex_vector_t::iterator min_degree_vertex_itr; + face_iterator fi_end = vertices_on_face.end(); + for(face_iterator fi = vertices_on_face.begin(); fi != fi_end; ++fi) + { + degree_size_t deg = get(degree,*fi); + if (deg < min_degree) + { + min_degree_vertex_itr = fi; + min_degree = deg; + } + } + + // To simplify some of the manipulations, we'll re-arrange + // vertices_on_face so that it still contains the same + // (counter-clockwise) order of the vertices on this face, but now the + // min_degree_vertex is the first element in vertices_on_face. + vertex_vector_t temp_vector; + std::copy(min_degree_vertex_itr, vertices_on_face.end(), + std::back_inserter(temp_vector)); + std::copy(vertices_on_face.begin(), min_degree_vertex_itr, + std::back_inserter(temp_vector)); + vertices_on_face.swap(temp_vector); + + // Mark all of the min degree vertex's neighbors + adjacency_iterator_t ai, ai_end; + for(boost::tie(ai,ai_end) = adjacent_vertices(vertices_on_face.front(),g); + ai != ai_end; ++ai + ) + { + put(marked, *ai, timestamp); + } + + typename vertex_vector_t::iterator marked_neighbor + = vertices_on_face.end(); + + // The iterator manipulations on the next two lines are safe because + // vertices_on_face.size() > 3 (from the first test in this function) + fi_end = prior(vertices_on_face.end()); + for(face_iterator fi = boost::next(boost::next(vertices_on_face.begin())); + fi != fi_end; ++fi + ) + { + if (get(marked, *fi) == timestamp) + { + marked_neighbor = fi; + break; + } + } + + if (marked_neighbor == vertices_on_face.end()) + { + add_edge_range( + vertices_on_face[0], + boost::next(boost::next(vertices_on_face.begin())), + prior(vertices_on_face.end()) + ); + } + else + { + add_edge_range( + vertices_on_face[1], + boost::next(marked_neighbor), + vertices_on_face.end() + ); + + add_edge_range( + *boost::next(marked_neighbor), + boost::next(boost::next(vertices_on_face.begin())), + marked_neighbor + ); + } + + //reset for the next face + vertices_on_face.clear(); + + } + + private: + + + void add_edge_range(vertex_t anchor, + face_iterator fi, + face_iterator fi_end + ) + { + for (; fi != fi_end; ++fi) + { + vertex_t v(*fi); + add_edge_visitor.visit_vertex_pair(anchor, v, g); + put(degree, anchor, get(degree, anchor) + 1); + put(degree, v, get(degree, v) + 1); + } + } + + + Graph& g; + VertexIndexMap vm; + AddEdgeVisitor add_edge_visitor; + v_size_t timestamp; + vertex_vector_t vertices_on_face; + v_size_vector_t marked_vector; + degree_size_vector_t degree_vector; + vertex_to_v_size_map_t marked; + vertex_to_degree_size_map_t degree; + + }; + + + + + template <typename Graph, + typename PlanarEmbedding, + typename VertexIndexMap, + typename EdgeIndexMap, + typename AddEdgeVisitor + > + void make_maximal_planar(Graph& g, + PlanarEmbedding embedding, + VertexIndexMap vm, + EdgeIndexMap em, + AddEdgeVisitor& vis) + { + triangulation_visitor<Graph,VertexIndexMap,AddEdgeVisitor> + visitor(g, vm, vis); + planar_face_traversal(g, embedding, visitor, em); + } + + + + + template <typename Graph, + typename PlanarEmbedding, + typename VertexIndexMap, + typename EdgeIndexMap + > + void make_maximal_planar(Graph& g, + PlanarEmbedding embedding, + VertexIndexMap vm, + EdgeIndexMap em + ) + { + default_add_edge_visitor vis; + make_maximal_planar(g, embedding, vm, em, vis); + } + + + + + template <typename Graph, + typename PlanarEmbedding, + typename VertexIndexMap + > + void make_maximal_planar(Graph& g, + PlanarEmbedding embedding, + VertexIndexMap vm + ) + { + make_maximal_planar(g, embedding, vm, get(edge_index,g)); + } + + + + + template <typename Graph, + typename PlanarEmbedding + > + void make_maximal_planar(Graph& g, + PlanarEmbedding embedding + ) + { + make_maximal_planar(g, embedding, get(vertex_index,g)); + } + + + + +} // namespace boost + + + +#endif //__MAKE_MAXIMAL_PLANAR_HPP__