make_maximal_planar.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. //=======================================================================
  2. // Copyright 2007 Aaron Windsor
  3. //
  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__
  10. #include <boost/config.hpp>
  11. #include <boost/tuple/tuple.hpp> //for tie
  12. #include <boost/graph/biconnected_components.hpp>
  13. #include <boost/property_map/property_map.hpp>
  14. #include <vector>
  15. #include <iterator>
  16. #include <algorithm>
  17. #include <boost/graph/planar_face_traversal.hpp>
  18. #include <boost/graph/planar_detail/add_edge_visitors.hpp>
  19. namespace boost
  20. {
  21. template < typename Graph, typename VertexIndexMap, typename AddEdgeVisitor >
  22. struct triangulation_visitor : public planar_face_traversal_visitor
  23. {
  24. typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
  25. typedef typename graph_traits< Graph >::edge_descriptor edge_t;
  26. typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
  27. typedef typename graph_traits< Graph >::degree_size_type degree_size_t;
  28. typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
  29. typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
  30. typedef
  31. typename graph_traits< Graph >::adjacency_iterator adjacency_iterator_t;
  32. typedef typename std::vector< vertex_t > vertex_vector_t;
  33. typedef typename std::vector< v_size_t > v_size_vector_t;
  34. typedef typename std::vector< degree_size_t > degree_size_vector_t;
  35. typedef iterator_property_map< typename v_size_vector_t::iterator,
  36. VertexIndexMap >
  37. vertex_to_v_size_map_t;
  38. typedef iterator_property_map< typename degree_size_vector_t::iterator,
  39. VertexIndexMap >
  40. vertex_to_degree_size_map_t;
  41. typedef typename vertex_vector_t::iterator face_iterator;
  42. triangulation_visitor(Graph& arg_g, VertexIndexMap arg_vm,
  43. AddEdgeVisitor arg_add_edge_visitor)
  44. : g(arg_g)
  45. , vm(arg_vm)
  46. , add_edge_visitor(arg_add_edge_visitor)
  47. , timestamp(0)
  48. , marked_vector(num_vertices(g), timestamp)
  49. , degree_vector(num_vertices(g), 0)
  50. , marked(marked_vector.begin(), vm)
  51. , degree(degree_vector.begin(), vm)
  52. {
  53. vertex_iterator_t vi, vi_end;
  54. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  55. put(degree, *vi, out_degree(*vi, g));
  56. }
  57. template < typename Vertex > void next_vertex(Vertex v)
  58. {
  59. // Self-loops will appear as consecutive vertices in the list of
  60. // vertices on a face. We want to skip these.
  61. if (!vertices_on_face.empty()
  62. && (vertices_on_face.back() == v || vertices_on_face.front() == v))
  63. return;
  64. vertices_on_face.push_back(v);
  65. }
  66. void end_face()
  67. {
  68. ++timestamp;
  69. if (vertices_on_face.size() <= 3)
  70. {
  71. // At most three vertices on this face - don't need to triangulate
  72. vertices_on_face.clear();
  73. return;
  74. }
  75. // Find vertex on face of minimum degree
  76. degree_size_t min_degree = num_vertices(g);
  77. typename vertex_vector_t::iterator min_degree_vertex_itr;
  78. face_iterator fi_end = vertices_on_face.end();
  79. for (face_iterator fi = vertices_on_face.begin(); fi != fi_end; ++fi)
  80. {
  81. degree_size_t deg = get(degree, *fi);
  82. if (deg < min_degree)
  83. {
  84. min_degree_vertex_itr = fi;
  85. min_degree = deg;
  86. }
  87. }
  88. // To simplify some of the manipulations, we'll re-arrange
  89. // vertices_on_face so that it still contains the same
  90. // (counter-clockwise) order of the vertices on this face, but now the
  91. // min_degree_vertex is the first element in vertices_on_face.
  92. vertex_vector_t temp_vector;
  93. std::copy(min_degree_vertex_itr, vertices_on_face.end(),
  94. std::back_inserter(temp_vector));
  95. std::copy(vertices_on_face.begin(), min_degree_vertex_itr,
  96. std::back_inserter(temp_vector));
  97. vertices_on_face.swap(temp_vector);
  98. // Mark all of the min degree vertex's neighbors
  99. adjacency_iterator_t ai, ai_end;
  100. for (boost::tie(ai, ai_end)
  101. = adjacent_vertices(vertices_on_face.front(), g);
  102. ai != ai_end; ++ai)
  103. {
  104. put(marked, *ai, timestamp);
  105. }
  106. typename vertex_vector_t::iterator marked_neighbor
  107. = vertices_on_face.end();
  108. // The iterator manipulations on the next two lines are safe because
  109. // vertices_on_face.size() > 3 (from the first test in this function)
  110. fi_end = prior(vertices_on_face.end());
  111. for (face_iterator fi
  112. = boost::next(boost::next(vertices_on_face.begin()));
  113. fi != fi_end; ++fi)
  114. {
  115. if (get(marked, *fi) == timestamp)
  116. {
  117. marked_neighbor = fi;
  118. break;
  119. }
  120. }
  121. if (marked_neighbor == vertices_on_face.end())
  122. {
  123. add_edge_range(vertices_on_face[0],
  124. boost::next(boost::next(vertices_on_face.begin())),
  125. prior(vertices_on_face.end()));
  126. }
  127. else
  128. {
  129. add_edge_range(vertices_on_face[1], boost::next(marked_neighbor),
  130. vertices_on_face.end());
  131. add_edge_range(*boost::next(marked_neighbor),
  132. boost::next(boost::next(vertices_on_face.begin())),
  133. marked_neighbor);
  134. }
  135. // reset for the next face
  136. vertices_on_face.clear();
  137. }
  138. private:
  139. void add_edge_range(vertex_t anchor, face_iterator fi, face_iterator fi_end)
  140. {
  141. for (; fi != fi_end; ++fi)
  142. {
  143. vertex_t v(*fi);
  144. add_edge_visitor.visit_vertex_pair(anchor, v, g);
  145. put(degree, anchor, get(degree, anchor) + 1);
  146. put(degree, v, get(degree, v) + 1);
  147. }
  148. }
  149. Graph& g;
  150. VertexIndexMap vm;
  151. AddEdgeVisitor add_edge_visitor;
  152. v_size_t timestamp;
  153. vertex_vector_t vertices_on_face;
  154. v_size_vector_t marked_vector;
  155. degree_size_vector_t degree_vector;
  156. vertex_to_v_size_map_t marked;
  157. vertex_to_degree_size_map_t degree;
  158. };
  159. template < typename Graph, typename PlanarEmbedding, typename VertexIndexMap,
  160. typename EdgeIndexMap, typename AddEdgeVisitor >
  161. void make_maximal_planar(Graph& g, PlanarEmbedding embedding, VertexIndexMap vm,
  162. EdgeIndexMap em, AddEdgeVisitor& vis)
  163. {
  164. triangulation_visitor< Graph, VertexIndexMap, AddEdgeVisitor > visitor(
  165. g, vm, vis);
  166. planar_face_traversal(g, embedding, visitor, em);
  167. }
  168. template < typename Graph, typename PlanarEmbedding, typename VertexIndexMap,
  169. typename EdgeIndexMap >
  170. void make_maximal_planar(
  171. Graph& g, PlanarEmbedding embedding, VertexIndexMap vm, EdgeIndexMap em)
  172. {
  173. default_add_edge_visitor vis;
  174. make_maximal_planar(g, embedding, vm, em, vis);
  175. }
  176. template < typename Graph, typename PlanarEmbedding, typename VertexIndexMap >
  177. void make_maximal_planar(Graph& g, PlanarEmbedding embedding, VertexIndexMap vm)
  178. {
  179. make_maximal_planar(g, embedding, vm, get(edge_index, g));
  180. }
  181. template < typename Graph, typename PlanarEmbedding >
  182. void make_maximal_planar(Graph& g, PlanarEmbedding embedding)
  183. {
  184. make_maximal_planar(g, embedding, get(vertex_index, g));
  185. }
  186. } // namespace boost
  187. #endif //__MAKE_MAXIMAL_PLANAR_HPP__