make_maximal_planar.hpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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 typename graph_traits<Graph>::adjacency_iterator
  31. 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
  36. < typename v_size_vector_t::iterator, VertexIndexMap >
  37. vertex_to_v_size_map_t;
  38. typedef iterator_property_map
  39. < typename degree_size_vector_t::iterator, VertexIndexMap >
  40. vertex_to_degree_size_map_t;
  41. typedef typename vertex_vector_t::iterator face_iterator;
  42. triangulation_visitor(Graph& arg_g,
  43. VertexIndexMap arg_vm,
  44. AddEdgeVisitor arg_add_edge_visitor
  45. ) :
  46. g(arg_g),
  47. vm(arg_vm),
  48. add_edge_visitor(arg_add_edge_visitor),
  49. timestamp(0),
  50. marked_vector(num_vertices(g), timestamp),
  51. degree_vector(num_vertices(g), 0),
  52. marked(marked_vector.begin(), vm),
  53. degree(degree_vector.begin(), vm)
  54. {
  55. vertex_iterator_t vi, vi_end;
  56. for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
  57. put(degree, *vi, out_degree(*vi, g));
  58. }
  59. template <typename Vertex>
  60. void next_vertex(Vertex v)
  61. {
  62. // Self-loops will appear as consecutive vertices in the list of
  63. // vertices on a face. We want to skip these.
  64. if (!vertices_on_face.empty() &&
  65. (vertices_on_face.back() == v || vertices_on_face.front() == v)
  66. )
  67. return;
  68. vertices_on_face.push_back(v);
  69. }
  70. void end_face()
  71. {
  72. ++timestamp;
  73. if (vertices_on_face.size() <= 3)
  74. {
  75. // At most three vertices on this face - don't need to triangulate
  76. vertices_on_face.clear();
  77. return;
  78. }
  79. // Find vertex on face of minimum degree
  80. degree_size_t min_degree = num_vertices(g);
  81. typename vertex_vector_t::iterator min_degree_vertex_itr;
  82. face_iterator fi_end = vertices_on_face.end();
  83. for(face_iterator fi = vertices_on_face.begin(); fi != fi_end; ++fi)
  84. {
  85. degree_size_t deg = get(degree,*fi);
  86. if (deg < min_degree)
  87. {
  88. min_degree_vertex_itr = fi;
  89. min_degree = deg;
  90. }
  91. }
  92. // To simplify some of the manipulations, we'll re-arrange
  93. // vertices_on_face so that it still contains the same
  94. // (counter-clockwise) order of the vertices on this face, but now the
  95. // min_degree_vertex is the first element in vertices_on_face.
  96. vertex_vector_t temp_vector;
  97. std::copy(min_degree_vertex_itr, vertices_on_face.end(),
  98. std::back_inserter(temp_vector));
  99. std::copy(vertices_on_face.begin(), min_degree_vertex_itr,
  100. std::back_inserter(temp_vector));
  101. vertices_on_face.swap(temp_vector);
  102. // Mark all of the min degree vertex's neighbors
  103. adjacency_iterator_t ai, ai_end;
  104. for(boost::tie(ai,ai_end) = adjacent_vertices(vertices_on_face.front(),g);
  105. ai != ai_end; ++ai
  106. )
  107. {
  108. put(marked, *ai, timestamp);
  109. }
  110. typename vertex_vector_t::iterator marked_neighbor
  111. = vertices_on_face.end();
  112. // The iterator manipulations on the next two lines are safe because
  113. // vertices_on_face.size() > 3 (from the first test in this function)
  114. fi_end = prior(vertices_on_face.end());
  115. for(face_iterator fi = boost::next(boost::next(vertices_on_face.begin()));
  116. fi != fi_end; ++fi
  117. )
  118. {
  119. if (get(marked, *fi) == timestamp)
  120. {
  121. marked_neighbor = fi;
  122. break;
  123. }
  124. }
  125. if (marked_neighbor == vertices_on_face.end())
  126. {
  127. add_edge_range(
  128. vertices_on_face[0],
  129. boost::next(boost::next(vertices_on_face.begin())),
  130. prior(vertices_on_face.end())
  131. );
  132. }
  133. else
  134. {
  135. add_edge_range(
  136. vertices_on_face[1],
  137. boost::next(marked_neighbor),
  138. vertices_on_face.end()
  139. );
  140. add_edge_range(
  141. *boost::next(marked_neighbor),
  142. boost::next(boost::next(vertices_on_face.begin())),
  143. marked_neighbor
  144. );
  145. }
  146. //reset for the next face
  147. vertices_on_face.clear();
  148. }
  149. private:
  150. void add_edge_range(vertex_t anchor,
  151. face_iterator fi,
  152. face_iterator fi_end
  153. )
  154. {
  155. for (; fi != fi_end; ++fi)
  156. {
  157. vertex_t v(*fi);
  158. add_edge_visitor.visit_vertex_pair(anchor, v, g);
  159. put(degree, anchor, get(degree, anchor) + 1);
  160. put(degree, v, get(degree, v) + 1);
  161. }
  162. }
  163. Graph& g;
  164. VertexIndexMap vm;
  165. AddEdgeVisitor add_edge_visitor;
  166. v_size_t timestamp;
  167. vertex_vector_t vertices_on_face;
  168. v_size_vector_t marked_vector;
  169. degree_size_vector_t degree_vector;
  170. vertex_to_v_size_map_t marked;
  171. vertex_to_degree_size_map_t degree;
  172. };
  173. template <typename Graph,
  174. typename PlanarEmbedding,
  175. typename VertexIndexMap,
  176. typename EdgeIndexMap,
  177. typename AddEdgeVisitor
  178. >
  179. void make_maximal_planar(Graph& g,
  180. PlanarEmbedding embedding,
  181. VertexIndexMap vm,
  182. EdgeIndexMap em,
  183. AddEdgeVisitor& vis)
  184. {
  185. triangulation_visitor<Graph,VertexIndexMap,AddEdgeVisitor>
  186. visitor(g, vm, vis);
  187. planar_face_traversal(g, embedding, visitor, em);
  188. }
  189. template <typename Graph,
  190. typename PlanarEmbedding,
  191. typename VertexIndexMap,
  192. typename EdgeIndexMap
  193. >
  194. void make_maximal_planar(Graph& g,
  195. PlanarEmbedding embedding,
  196. VertexIndexMap vm,
  197. EdgeIndexMap em
  198. )
  199. {
  200. default_add_edge_visitor vis;
  201. make_maximal_planar(g, embedding, vm, em, vis);
  202. }
  203. template <typename Graph,
  204. typename PlanarEmbedding,
  205. typename VertexIndexMap
  206. >
  207. void make_maximal_planar(Graph& g,
  208. PlanarEmbedding embedding,
  209. VertexIndexMap vm
  210. )
  211. {
  212. make_maximal_planar(g, embedding, vm, get(edge_index,g));
  213. }
  214. template <typename Graph,
  215. typename PlanarEmbedding
  216. >
  217. void make_maximal_planar(Graph& g,
  218. PlanarEmbedding embedding
  219. )
  220. {
  221. make_maximal_planar(g, embedding, get(vertex_index,g));
  222. }
  223. } // namespace boost
  224. #endif //__MAKE_MAXIMAL_PLANAR_HPP__