1 //=======================================================================
2 // Copyright 2007 Aaron Windsor
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //=======================================================================
8 #ifndef __MAKE_MAXIMAL_PLANAR_HPP__
9 #define __MAKE_MAXIMAL_PLANAR_HPP__
11 #include <boost/config.hpp>
12 #include <boost/tuple/tuple.hpp> //for tie
13 #include <boost/graph/biconnected_components.hpp>
14 #include <boost/property_map/property_map.hpp>
19 #include <boost/graph/planar_face_traversal.hpp>
20 #include <boost/graph/planar_detail/add_edge_visitors.hpp>
25 template < typename Graph, typename VertexIndexMap, typename AddEdgeVisitor >
26 struct triangulation_visitor : public planar_face_traversal_visitor
29 typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
30 typedef typename graph_traits< Graph >::edge_descriptor edge_t;
31 typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
32 typedef typename graph_traits< Graph >::degree_size_type degree_size_t;
33 typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
34 typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
36 typename graph_traits< Graph >::adjacency_iterator adjacency_iterator_t;
37 typedef typename std::vector< vertex_t > vertex_vector_t;
38 typedef typename std::vector< v_size_t > v_size_vector_t;
39 typedef typename std::vector< degree_size_t > degree_size_vector_t;
40 typedef iterator_property_map< typename v_size_vector_t::iterator,
42 vertex_to_v_size_map_t;
43 typedef iterator_property_map< typename degree_size_vector_t::iterator,
45 vertex_to_degree_size_map_t;
46 typedef typename vertex_vector_t::iterator face_iterator;
48 triangulation_visitor(Graph& arg_g, VertexIndexMap arg_vm,
49 AddEdgeVisitor arg_add_edge_visitor)
52 , add_edge_visitor(arg_add_edge_visitor)
54 , marked_vector(num_vertices(g), timestamp)
55 , degree_vector(num_vertices(g), 0)
56 , marked(marked_vector.begin(), vm)
57 , degree(degree_vector.begin(), vm)
59 vertex_iterator_t vi, vi_end;
60 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
61 put(degree, *vi, out_degree(*vi, g));
64 template < typename Vertex > void next_vertex(Vertex v)
66 // Self-loops will appear as consecutive vertices in the list of
67 // vertices on a face. We want to skip these.
68 if (!vertices_on_face.empty()
69 && (vertices_on_face.back() == v || vertices_on_face.front() == v))
72 vertices_on_face.push_back(v);
79 if (vertices_on_face.size() <= 3)
81 // At most three vertices on this face - don't need to triangulate
82 vertices_on_face.clear();
86 // Find vertex on face of minimum degree
87 degree_size_t min_degree = num_vertices(g);
88 typename vertex_vector_t::iterator min_degree_vertex_itr;
89 face_iterator fi_end = vertices_on_face.end();
90 for (face_iterator fi = vertices_on_face.begin(); fi != fi_end; ++fi)
92 degree_size_t deg = get(degree, *fi);
95 min_degree_vertex_itr = fi;
100 // To simplify some of the manipulations, we'll re-arrange
101 // vertices_on_face so that it still contains the same
102 // (counter-clockwise) order of the vertices on this face, but now the
103 // min_degree_vertex is the first element in vertices_on_face.
104 vertex_vector_t temp_vector;
105 std::copy(min_degree_vertex_itr, vertices_on_face.end(),
106 std::back_inserter(temp_vector));
107 std::copy(vertices_on_face.begin(), min_degree_vertex_itr,
108 std::back_inserter(temp_vector));
109 vertices_on_face.swap(temp_vector);
111 // Mark all of the min degree vertex's neighbors
112 adjacency_iterator_t ai, ai_end;
113 for (boost::tie(ai, ai_end)
114 = adjacent_vertices(vertices_on_face.front(), g);
117 put(marked, *ai, timestamp);
120 typename vertex_vector_t::iterator marked_neighbor
121 = vertices_on_face.end();
123 // The iterator manipulations on the next two lines are safe because
124 // vertices_on_face.size() > 3 (from the first test in this function)
125 fi_end = prior(vertices_on_face.end());
126 for (face_iterator fi
127 = boost::next(boost::next(vertices_on_face.begin()));
130 if (get(marked, *fi) == timestamp)
132 marked_neighbor = fi;
137 if (marked_neighbor == vertices_on_face.end())
139 add_edge_range(vertices_on_face[0],
140 boost::next(boost::next(vertices_on_face.begin())),
141 prior(vertices_on_face.end()));
145 add_edge_range(vertices_on_face[1], boost::next(marked_neighbor),
146 vertices_on_face.end());
148 add_edge_range(*boost::next(marked_neighbor),
149 boost::next(boost::next(vertices_on_face.begin())),
153 // reset for the next face
154 vertices_on_face.clear();
158 void add_edge_range(vertex_t anchor, face_iterator fi, face_iterator fi_end)
160 for (; fi != fi_end; ++fi)
163 add_edge_visitor.visit_vertex_pair(anchor, v, g);
164 put(degree, anchor, get(degree, anchor) + 1);
165 put(degree, v, get(degree, v) + 1);
171 AddEdgeVisitor add_edge_visitor;
173 vertex_vector_t vertices_on_face;
174 v_size_vector_t marked_vector;
175 degree_size_vector_t degree_vector;
176 vertex_to_v_size_map_t marked;
177 vertex_to_degree_size_map_t degree;
180 template < typename Graph, typename PlanarEmbedding, typename VertexIndexMap,
181 typename EdgeIndexMap, typename AddEdgeVisitor >
182 void make_maximal_planar(Graph& g, PlanarEmbedding embedding, VertexIndexMap vm,
183 EdgeIndexMap em, AddEdgeVisitor& vis)
185 triangulation_visitor< Graph, VertexIndexMap, AddEdgeVisitor > visitor(
187 planar_face_traversal(g, embedding, visitor, em);
190 template < typename Graph, typename PlanarEmbedding, typename VertexIndexMap,
191 typename EdgeIndexMap >
192 void make_maximal_planar(
193 Graph& g, PlanarEmbedding embedding, VertexIndexMap vm, EdgeIndexMap em)
195 default_add_edge_visitor vis;
196 make_maximal_planar(g, embedding, vm, em, vis);
199 template < typename Graph, typename PlanarEmbedding, typename VertexIndexMap >
200 void make_maximal_planar(Graph& g, PlanarEmbedding embedding, VertexIndexMap vm)
202 make_maximal_planar(g, embedding, vm, get(edge_index, g));
205 template < typename Graph, typename PlanarEmbedding >
206 void make_maximal_planar(Graph& g, PlanarEmbedding embedding)
208 make_maximal_planar(g, embedding, get(vertex_index, g));
213 #endif //__MAKE_MAXIMAL_PLANAR_HPP__