File indexing completed on 2025-01-18 09:37:20
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef __BOYER_MYRVOLD_IMPL_HPP__
0009 #define __BOYER_MYRVOLD_IMPL_HPP__
0010
0011 #include <vector>
0012 #include <list>
0013 #include <boost/next_prior.hpp>
0014 #include <boost/config.hpp> //for std::min macros
0015 #include <boost/shared_ptr.hpp>
0016 #include <boost/tuple/tuple.hpp>
0017 #include <boost/property_map/property_map.hpp>
0018 #include <boost/graph/graph_traits.hpp>
0019 #include <boost/graph/depth_first_search.hpp>
0020 #include <boost/graph/planar_detail/face_handles.hpp>
0021 #include <boost/graph/planar_detail/face_iterators.hpp>
0022 #include <boost/graph/planar_detail/bucket_sort.hpp>
0023
0024 namespace boost
0025 {
0026 namespace detail
0027 {
0028 enum bm_case_t
0029 {
0030 BM_NO_CASE_CHOSEN,
0031 BM_CASE_A,
0032 BM_CASE_B,
0033 BM_CASE_C,
0034 BM_CASE_D,
0035 BM_CASE_E
0036 };
0037 }
0038
0039 template < typename LowPointMap, typename DFSParentMap, typename DFSNumberMap,
0040 typename LeastAncestorMap, typename DFSParentEdgeMap, typename SizeType >
0041 struct planar_dfs_visitor : public dfs_visitor<>
0042 {
0043 planar_dfs_visitor(LowPointMap lpm, DFSParentMap dfs_p, DFSNumberMap dfs_n,
0044 LeastAncestorMap lam, DFSParentEdgeMap dfs_edge)
0045 : low(lpm)
0046 , parent(dfs_p)
0047 , df_number(dfs_n)
0048 , least_ancestor(lam)
0049 , df_edge(dfs_edge)
0050 , count(0)
0051 {
0052 }
0053
0054 template < typename Vertex, typename Graph >
0055 void start_vertex(const Vertex& u, Graph&)
0056 {
0057 put(parent, u, u);
0058 put(least_ancestor, u, count);
0059 }
0060
0061 template < typename Vertex, typename Graph >
0062 void discover_vertex(const Vertex& u, Graph&)
0063 {
0064 put(low, u, count);
0065 put(df_number, u, count);
0066 ++count;
0067 }
0068
0069 template < typename Edge, typename Graph >
0070 void tree_edge(const Edge& e, Graph& g)
0071 {
0072 typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
0073 vertex_t s(source(e, g));
0074 vertex_t t(target(e, g));
0075
0076 put(parent, t, s);
0077 put(df_edge, t, e);
0078 put(least_ancestor, t, get(df_number, s));
0079 }
0080
0081 template < typename Edge, typename Graph >
0082 void back_edge(const Edge& e, Graph& g)
0083 {
0084 typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
0085 typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
0086
0087 vertex_t s(source(e, g));
0088 vertex_t t(target(e, g));
0089 BOOST_USING_STD_MIN();
0090
0091 if (t != get(parent, s))
0092 {
0093 v_size_t s_low_df_number = get(low, s);
0094 v_size_t t_df_number = get(df_number, t);
0095 v_size_t s_least_ancestor_df_number = get(least_ancestor, s);
0096
0097 put(low, s,
0098 min BOOST_PREVENT_MACRO_SUBSTITUTION(
0099 s_low_df_number, t_df_number));
0100
0101 put(least_ancestor, s,
0102 min BOOST_PREVENT_MACRO_SUBSTITUTION(
0103 s_least_ancestor_df_number, t_df_number));
0104 }
0105 }
0106
0107 template < typename Vertex, typename Graph >
0108 void finish_vertex(const Vertex& u, Graph&)
0109 {
0110 typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
0111
0112 Vertex u_parent = get(parent, u);
0113 v_size_t u_parent_lowpoint = get(low, u_parent);
0114 v_size_t u_lowpoint = get(low, u);
0115 BOOST_USING_STD_MIN();
0116
0117 if (u_parent != u)
0118 {
0119 put(low, u_parent,
0120 min BOOST_PREVENT_MACRO_SUBSTITUTION(
0121 u_lowpoint, u_parent_lowpoint));
0122 }
0123 }
0124
0125 LowPointMap low;
0126 DFSParentMap parent;
0127 DFSNumberMap df_number;
0128 LeastAncestorMap least_ancestor;
0129 DFSParentEdgeMap df_edge;
0130 SizeType count;
0131 };
0132
0133 template < typename Graph, typename VertexIndexMap,
0134 typename StoreOldHandlesPolicy = graph::detail::store_old_handles,
0135 typename StoreEmbeddingPolicy = graph::detail::recursive_lazy_list >
0136 class boyer_myrvold_impl
0137 {
0138
0139 typedef typename graph_traits< Graph >::vertices_size_type v_size_t;
0140 typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
0141 typedef typename graph_traits< Graph >::edge_descriptor edge_t;
0142 typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
0143 typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
0144 typedef
0145 typename graph_traits< Graph >::out_edge_iterator out_edge_iterator_t;
0146 typedef graph::detail::face_handle< Graph, StoreOldHandlesPolicy,
0147 StoreEmbeddingPolicy >
0148 face_handle_t;
0149 typedef std::vector< vertex_t > vertex_vector_t;
0150 typedef std::vector< edge_t > edge_vector_t;
0151 typedef std::list< vertex_t > vertex_list_t;
0152 typedef std::list< face_handle_t > face_handle_list_t;
0153 typedef boost::shared_ptr< face_handle_list_t > face_handle_list_ptr_t;
0154 typedef boost::shared_ptr< vertex_list_t > vertex_list_ptr_t;
0155 typedef boost::tuple< vertex_t, bool, bool > merge_stack_frame_t;
0156 typedef std::vector< merge_stack_frame_t > merge_stack_t;
0157
0158 template < typename T > struct map_vertex_to_
0159 {
0160 typedef iterator_property_map< typename std::vector< T >::iterator,
0161 VertexIndexMap >
0162 type;
0163 };
0164
0165 typedef typename map_vertex_to_< v_size_t >::type vertex_to_v_size_map_t;
0166 typedef typename map_vertex_to_< vertex_t >::type vertex_to_vertex_map_t;
0167 typedef typename map_vertex_to_< edge_t >::type vertex_to_edge_map_t;
0168 typedef typename map_vertex_to_< vertex_list_ptr_t >::type
0169 vertex_to_vertex_list_ptr_map_t;
0170 typedef typename map_vertex_to_< edge_vector_t >::type
0171 vertex_to_edge_vector_map_t;
0172 typedef typename map_vertex_to_< bool >::type vertex_to_bool_map_t;
0173 typedef typename map_vertex_to_< face_handle_t >::type
0174 vertex_to_face_handle_map_t;
0175 typedef typename map_vertex_to_< face_handle_list_ptr_t >::type
0176 vertex_to_face_handle_list_ptr_map_t;
0177 typedef typename map_vertex_to_< typename vertex_list_t::iterator >::type
0178 vertex_to_separated_node_map_t;
0179
0180 template < typename BicompSideToTraverse = single_side,
0181 typename VisitorType = lead_visitor, typename Time = current_iteration >
0182 struct face_vertex_iterator
0183 {
0184 typedef face_iterator< Graph, vertex_to_face_handle_map_t, vertex_t,
0185 BicompSideToTraverse, VisitorType, Time >
0186 type;
0187 };
0188
0189 template < typename BicompSideToTraverse = single_side,
0190 typename Time = current_iteration >
0191 struct face_edge_iterator
0192 {
0193 typedef face_iterator< Graph, vertex_to_face_handle_map_t, edge_t,
0194 BicompSideToTraverse, lead_visitor, Time >
0195 type;
0196 };
0197
0198 public:
0199 boyer_myrvold_impl(const Graph& arg_g, VertexIndexMap arg_vm)
0200 : g(arg_g)
0201 , vm(arg_vm)
0202 ,
0203
0204 low_point_vector(num_vertices(g))
0205 , dfs_parent_vector(num_vertices(g))
0206 , dfs_number_vector(num_vertices(g))
0207 , least_ancestor_vector(num_vertices(g))
0208 , pertinent_roots_vector(num_vertices(g))
0209 , backedge_flag_vector(num_vertices(g), num_vertices(g) + 1)
0210 , visited_vector(num_vertices(g), num_vertices(g) + 1)
0211 , face_handles_vector(num_vertices(g))
0212 , dfs_child_handles_vector(num_vertices(g))
0213 , separated_dfs_child_list_vector(num_vertices(g))
0214 , separated_node_in_parent_list_vector(num_vertices(g))
0215 , canonical_dfs_child_vector(num_vertices(g))
0216 , flipped_vector(num_vertices(g), false)
0217 , backedges_vector(num_vertices(g))
0218 , dfs_parent_edge_vector(num_vertices(g))
0219 ,
0220
0221 vertices_by_dfs_num(num_vertices(g))
0222 ,
0223
0224 low_point(low_point_vector.begin(), vm)
0225 , dfs_parent(dfs_parent_vector.begin(), vm)
0226 , dfs_number(dfs_number_vector.begin(), vm)
0227 , least_ancestor(least_ancestor_vector.begin(), vm)
0228 , pertinent_roots(pertinent_roots_vector.begin(), vm)
0229 , backedge_flag(backedge_flag_vector.begin(), vm)
0230 , visited(visited_vector.begin(), vm)
0231 , face_handles(face_handles_vector.begin(), vm)
0232 , dfs_child_handles(dfs_child_handles_vector.begin(), vm)
0233 , separated_dfs_child_list(separated_dfs_child_list_vector.begin(), vm)
0234 , separated_node_in_parent_list(
0235 separated_node_in_parent_list_vector.begin(), vm)
0236 , canonical_dfs_child(canonical_dfs_child_vector.begin(), vm)
0237 , flipped(flipped_vector.begin(), vm)
0238 , backedges(backedges_vector.begin(), vm)
0239 , dfs_parent_edge(dfs_parent_edge_vector.begin(), vm)
0240
0241 {
0242
0243 planar_dfs_visitor< vertex_to_v_size_map_t, vertex_to_vertex_map_t,
0244 vertex_to_v_size_map_t, vertex_to_v_size_map_t,
0245 vertex_to_edge_map_t, v_size_t >
0246 vis(low_point, dfs_parent, dfs_number, least_ancestor,
0247 dfs_parent_edge);
0248
0249
0250
0251 depth_first_search(g, visitor(vis).vertex_index_map(vm));
0252
0253
0254 vertex_vector_t vertices_by_lowpoint(num_vertices(g));
0255 std::copy(vertices(g).first, vertices(g).second,
0256 vertices_by_lowpoint.begin());
0257 bucket_sort(vertices_by_lowpoint.begin(), vertices_by_lowpoint.end(),
0258 low_point, num_vertices(g));
0259
0260
0261
0262 std::copy(
0263 vertices(g).first, vertices(g).second, vertices_by_dfs_num.begin());
0264 bucket_sort(vertices_by_dfs_num.begin(), vertices_by_dfs_num.end(),
0265 dfs_number, num_vertices(g));
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321 vertex_iterator_t vi, vi_end;
0322 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
0323 {
0324 vertex_t v(*vi);
0325 vertex_t parent = dfs_parent[v];
0326
0327 if (parent != v)
0328 {
0329 edge_t parent_edge = dfs_parent_edge[v];
0330 add_to_embedded_edges(parent_edge, StoreOldHandlesPolicy());
0331 face_handles[v] = face_handle_t(v, parent_edge, g);
0332 dfs_child_handles[v] = face_handle_t(parent, parent_edge, g);
0333 }
0334 else
0335 {
0336 face_handles[v] = face_handle_t(v);
0337 dfs_child_handles[v] = face_handle_t(parent);
0338 }
0339
0340 canonical_dfs_child[v] = v;
0341 pertinent_roots[v] = face_handle_list_ptr_t(new face_handle_list_t);
0342 separated_dfs_child_list[v] = vertex_list_ptr_t(new vertex_list_t);
0343 }
0344
0345
0346
0347
0348
0349
0350
0351
0352 for (typename vertex_vector_t::iterator itr
0353 = vertices_by_lowpoint.begin();
0354 itr != vertices_by_lowpoint.end(); ++itr)
0355 {
0356 vertex_t v(*itr);
0357 vertex_t parent(dfs_parent[v]);
0358 if (v != parent)
0359 {
0360 separated_node_in_parent_list[v]
0361 = separated_dfs_child_list[parent]->insert(
0362 separated_dfs_child_list[parent]->end(), v);
0363 }
0364 }
0365
0366
0367 merge_stack.reserve(num_vertices(g));
0368 }
0369
0370 bool is_planar()
0371 {
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 typename vertex_vector_t::reverse_iterator vi, vi_end;
0395
0396 vi_end = vertices_by_dfs_num.rend();
0397 for (vi = vertices_by_dfs_num.rbegin(); vi != vi_end; ++vi)
0398 {
0399
0400 store_old_face_handles(StoreOldHandlesPolicy());
0401
0402 vertex_t v(*vi);
0403
0404 walkup(v);
0405
0406 if (!walkdown(v))
0407 return false;
0408 }
0409
0410 clean_up_embedding(StoreEmbeddingPolicy());
0411
0412 return true;
0413 }
0414
0415 private:
0416 void walkup(vertex_t v)
0417 {
0418
0419
0420
0421
0422
0423
0424
0425 typedef
0426 typename face_vertex_iterator< both_sides >::type walkup_iterator_t;
0427
0428 out_edge_iterator_t oi, oi_end;
0429 for (boost::tie(oi, oi_end) = out_edges(v, g); oi != oi_end; ++oi)
0430 {
0431 edge_t e(*oi);
0432 vertex_t e_source(source(e, g));
0433 vertex_t e_target(target(e, g));
0434
0435 if (e_source == e_target)
0436 {
0437 self_loops.push_back(e);
0438 continue;
0439 }
0440
0441 vertex_t w(e_source == v ? e_target : e_source);
0442
0443
0444 if (dfs_number[w] < dfs_number[v] || e == dfs_parent_edge[w])
0445 continue;
0446
0447 backedges[w].push_back(e);
0448
0449 v_size_t timestamp = dfs_number[v];
0450 backedge_flag[w] = timestamp;
0451
0452 walkup_iterator_t walkup_itr(w, face_handles);
0453 walkup_iterator_t walkup_end;
0454 vertex_t lead_vertex = w;
0455
0456 while (true)
0457 {
0458
0459
0460
0461
0462 while (walkup_itr != walkup_end
0463 && visited[*walkup_itr] != timestamp)
0464 {
0465 lead_vertex = *walkup_itr;
0466 visited[lead_vertex] = timestamp;
0467 ++walkup_itr;
0468 }
0469
0470
0471
0472
0473
0474
0475 if (walkup_itr == walkup_end)
0476 {
0477 vertex_t dfs_child = canonical_dfs_child[lead_vertex];
0478 vertex_t parent = dfs_parent[dfs_child];
0479
0480 visited[dfs_child_handles[dfs_child].first_vertex()]
0481 = timestamp;
0482 visited[dfs_child_handles[dfs_child].second_vertex()]
0483 = timestamp;
0484
0485 if (low_point[dfs_child] < dfs_number[v]
0486 || least_ancestor[dfs_child] < dfs_number[v])
0487 {
0488 pertinent_roots[parent]->push_back(
0489 dfs_child_handles[dfs_child]);
0490 }
0491 else
0492 {
0493 pertinent_roots[parent]->push_front(
0494 dfs_child_handles[dfs_child]);
0495 }
0496
0497 if (parent != v && visited[parent] != timestamp)
0498 {
0499 walkup_itr = walkup_iterator_t(parent, face_handles);
0500 lead_vertex = parent;
0501 }
0502 else
0503 break;
0504 }
0505 else
0506 break;
0507 }
0508 }
0509 }
0510
0511 bool walkdown(vertex_t v)
0512 {
0513
0514
0515
0516
0517
0518
0519
0520
0521 vertex_t w;
0522
0523 while (!pertinent_roots[v]->empty())
0524 {
0525
0526 face_handle_t root_face_handle = pertinent_roots[v]->front();
0527 face_handle_t curr_face_handle = root_face_handle;
0528 pertinent_roots[v]->pop_front();
0529
0530 merge_stack.clear();
0531
0532 while (true)
0533 {
0534
0535 typename face_vertex_iterator<>::type first_face_itr,
0536 second_face_itr, face_end;
0537 vertex_t first_side_vertex
0538 = graph_traits< Graph >::null_vertex();
0539 vertex_t second_side_vertex
0540 = graph_traits< Graph >::null_vertex();
0541 vertex_t first_tail, second_tail;
0542
0543 first_tail = second_tail = curr_face_handle.get_anchor();
0544 first_face_itr = typename face_vertex_iterator<>::type(
0545 curr_face_handle, face_handles, first_side());
0546 second_face_itr = typename face_vertex_iterator<>::type(
0547 curr_face_handle, face_handles, second_side());
0548
0549 for (; first_face_itr != face_end; ++first_face_itr)
0550 {
0551 vertex_t face_vertex(*first_face_itr);
0552 if (pertinent(face_vertex, v)
0553 || externally_active(face_vertex, v))
0554 {
0555 first_side_vertex = face_vertex;
0556 second_side_vertex = face_vertex;
0557 break;
0558 }
0559 first_tail = face_vertex;
0560 }
0561
0562 if (first_side_vertex == graph_traits< Graph >::null_vertex()
0563 || first_side_vertex == curr_face_handle.get_anchor())
0564 break;
0565
0566 for (; second_face_itr != face_end; ++second_face_itr)
0567 {
0568 vertex_t face_vertex(*second_face_itr);
0569 if (pertinent(face_vertex, v)
0570 || externally_active(face_vertex, v))
0571 {
0572 second_side_vertex = face_vertex;
0573 break;
0574 }
0575 second_tail = face_vertex;
0576 }
0577
0578 vertex_t chosen;
0579 bool chose_first_upper_path;
0580 if (internally_active(first_side_vertex, v))
0581 {
0582 chosen = first_side_vertex;
0583 chose_first_upper_path = true;
0584 }
0585 else if (internally_active(second_side_vertex, v))
0586 {
0587 chosen = second_side_vertex;
0588 chose_first_upper_path = false;
0589 }
0590 else if (pertinent(first_side_vertex, v))
0591 {
0592 chosen = first_side_vertex;
0593 chose_first_upper_path = true;
0594 }
0595 else if (pertinent(second_side_vertex, v))
0596 {
0597 chosen = second_side_vertex;
0598 chose_first_upper_path = false;
0599 }
0600 else
0601 {
0602
0603
0604
0605
0606 for (; *first_face_itr != second_side_vertex;
0607 ++first_face_itr)
0608 {
0609 vertex_t p(*first_face_itr);
0610 if (pertinent(p, v))
0611 {
0612
0613 kuratowski_v = v;
0614 kuratowski_x = first_side_vertex;
0615 kuratowski_y = second_side_vertex;
0616 return false;
0617 }
0618 }
0619
0620
0621
0622
0623
0624
0625 if (first_side_vertex == second_side_vertex)
0626 {
0627 if (first_tail != v)
0628 {
0629 vertex_t first
0630 = face_handles[first_tail].first_vertex();
0631 vertex_t second
0632 = face_handles[first_tail].second_vertex();
0633 boost::tie(first_side_vertex, first_tail)
0634 = make_tuple(first_tail,
0635 first == first_side_vertex ? second
0636 : first);
0637 }
0638 else if (second_tail != v)
0639 {
0640 vertex_t first
0641 = face_handles[second_tail].first_vertex();
0642 vertex_t second
0643 = face_handles[second_tail].second_vertex();
0644 boost::tie(second_side_vertex, second_tail)
0645 = make_tuple(second_tail,
0646 first == second_side_vertex ? second
0647 : first);
0648 }
0649 else
0650 break;
0651 }
0652
0653 canonical_dfs_child[first_side_vertex]
0654 = canonical_dfs_child[root_face_handle.first_vertex()];
0655 canonical_dfs_child[second_side_vertex]
0656 = canonical_dfs_child[root_face_handle.second_vertex()];
0657 root_face_handle.set_first_vertex(first_side_vertex);
0658 root_face_handle.set_second_vertex(second_side_vertex);
0659
0660 if (face_handles[first_side_vertex].first_vertex()
0661 == first_tail)
0662 face_handles[first_side_vertex].set_first_vertex(v);
0663 else
0664 face_handles[first_side_vertex].set_second_vertex(v);
0665
0666 if (face_handles[second_side_vertex].first_vertex()
0667 == second_tail)
0668 face_handles[second_side_vertex].set_first_vertex(v);
0669 else
0670 face_handles[second_side_vertex].set_second_vertex(v);
0671
0672 break;
0673 }
0674
0675
0676
0677
0678 bool chose_first_lower_path
0679 = (chose_first_upper_path
0680 && face_handles[chosen].first_vertex() == first_tail)
0681 || (!chose_first_upper_path
0682 && face_handles[chosen].first_vertex() == second_tail);
0683
0684
0685 if (backedge_flag[chosen] == dfs_number[v])
0686 {
0687 w = chosen;
0688
0689 backedge_flag[chosen] = num_vertices(g) + 1;
0690 add_to_merge_points(chosen, StoreOldHandlesPolicy());
0691
0692 typename edge_vector_t::iterator ei, ei_end;
0693 ei_end = backedges[chosen].end();
0694 for (ei = backedges[chosen].begin(); ei != ei_end; ++ei)
0695 {
0696 edge_t e(*ei);
0697 add_to_embedded_edges(e, StoreOldHandlesPolicy());
0698
0699 if (chose_first_lower_path)
0700 face_handles[chosen].push_first(e, g);
0701 else
0702 face_handles[chosen].push_second(e, g);
0703 }
0704 }
0705 else
0706 {
0707 merge_stack.push_back(make_tuple(chosen,
0708 chose_first_upper_path, chose_first_lower_path));
0709 curr_face_handle = *pertinent_roots[chosen]->begin();
0710 continue;
0711 }
0712
0713
0714
0715 bool bottom_path_follows_first;
0716 bool top_path_follows_first;
0717 bool next_bottom_follows_first = chose_first_upper_path;
0718
0719 vertex_t merge_point = chosen;
0720
0721 while (!merge_stack.empty())
0722 {
0723
0724 bottom_path_follows_first = next_bottom_follows_first;
0725 boost::tie(merge_point, next_bottom_follows_first,
0726 top_path_follows_first)
0727 = merge_stack.back();
0728 merge_stack.pop_back();
0729
0730 face_handle_t top_handle(face_handles[merge_point]);
0731 face_handle_t bottom_handle(
0732 *pertinent_roots[merge_point]->begin());
0733
0734 vertex_t bottom_dfs_child = canonical_dfs_child
0735 [pertinent_roots[merge_point]->begin()->first_vertex()];
0736
0737 remove_vertex_from_separated_dfs_child_list(
0738 canonical_dfs_child[pertinent_roots[merge_point]
0739 ->begin()
0740 ->first_vertex()]);
0741
0742 pertinent_roots[merge_point]->pop_front();
0743
0744 add_to_merge_points(
0745 top_handle.get_anchor(), StoreOldHandlesPolicy());
0746
0747 if (top_path_follows_first && bottom_path_follows_first)
0748 {
0749 bottom_handle.flip();
0750 top_handle.glue_first_to_second(bottom_handle);
0751 }
0752 else if (!top_path_follows_first
0753 && bottom_path_follows_first)
0754 {
0755 flipped[bottom_dfs_child] = true;
0756 top_handle.glue_second_to_first(bottom_handle);
0757 }
0758 else if (top_path_follows_first
0759 && !bottom_path_follows_first)
0760 {
0761 flipped[bottom_dfs_child] = true;
0762 top_handle.glue_first_to_second(bottom_handle);
0763 }
0764 else
0765
0766 {
0767 bottom_handle.flip();
0768 top_handle.glue_second_to_first(bottom_handle);
0769 }
0770 }
0771
0772
0773 canonical_dfs_child[w]
0774 = canonical_dfs_child[root_face_handle.first_vertex()];
0775
0776 add_to_merge_points(
0777 root_face_handle.get_anchor(), StoreOldHandlesPolicy());
0778
0779 typename edge_vector_t::iterator ei, ei_end;
0780 ei_end = backedges[chosen].end();
0781 for (ei = backedges[chosen].begin(); ei != ei_end; ++ei)
0782 {
0783 if (next_bottom_follows_first)
0784 root_face_handle.push_first(*ei, g);
0785 else
0786 root_face_handle.push_second(*ei, g);
0787 }
0788
0789 backedges[chosen].clear();
0790 curr_face_handle = root_face_handle;
0791
0792 }
0793
0794 }
0795
0796 return true;
0797 }
0798
0799 void store_old_face_handles(graph::detail::no_old_handles) {}
0800
0801 void store_old_face_handles(graph::detail::store_old_handles)
0802 {
0803 for (typename std::vector< vertex_t >::iterator mp_itr
0804 = current_merge_points.begin();
0805 mp_itr != current_merge_points.end(); ++mp_itr)
0806 {
0807 face_handles[*mp_itr].store_old_face_handles();
0808 }
0809 current_merge_points.clear();
0810 }
0811
0812 void add_to_merge_points(vertex_t, graph::detail::no_old_handles) {}
0813
0814 void add_to_merge_points(vertex_t v, graph::detail::store_old_handles)
0815 {
0816 current_merge_points.push_back(v);
0817 }
0818
0819 void add_to_embedded_edges(edge_t, graph::detail::no_old_handles) {}
0820
0821 void add_to_embedded_edges(edge_t e, graph::detail::store_old_handles)
0822 {
0823 embedded_edges.push_back(e);
0824 }
0825
0826 void clean_up_embedding(graph::detail::no_embedding) {}
0827
0828 void clean_up_embedding(graph::detail::store_embedding)
0829 {
0830
0831
0832
0833
0834
0835
0836 vertex_iterator_t xi, xi_end;
0837 for (boost::tie(xi, xi_end) = vertices(g); xi != xi_end; ++xi)
0838 {
0839 if (!separated_dfs_child_list[*xi]->empty())
0840 {
0841 typename vertex_list_t::iterator yi, yi_end;
0842 yi_end = separated_dfs_child_list[*xi]->end();
0843 for (yi = separated_dfs_child_list[*xi]->begin(); yi != yi_end;
0844 ++yi)
0845 {
0846 dfs_child_handles[*yi].flip();
0847 face_handles[*xi].glue_first_to_second(
0848 dfs_child_handles[*yi]);
0849 }
0850 }
0851 }
0852
0853
0854
0855
0856
0857
0858
0859
0860 typedef typename vertex_vector_t::iterator vertex_vector_itr_t;
0861 vertex_vector_itr_t vi_end = vertices_by_dfs_num.end();
0862 for (vertex_vector_itr_t vi = vertices_by_dfs_num.begin(); vi != vi_end;
0863 ++vi)
0864 {
0865 vertex_t v(*vi);
0866 bool v_flipped = flipped[v];
0867 bool p_flipped = flipped[dfs_parent[v]];
0868 if (v_flipped && !p_flipped)
0869 {
0870 face_handles[v].flip();
0871 }
0872 else if (p_flipped && !v_flipped)
0873 {
0874 face_handles[v].flip();
0875 flipped[v] = true;
0876 }
0877 else
0878 {
0879 flipped[v] = false;
0880 }
0881 }
0882
0883
0884
0885
0886
0887
0888
0889 typename edge_vector_t::iterator ei, ei_end;
0890 ei_end = self_loops.end();
0891 for (ei = self_loops.begin(); ei != ei_end; ++ei)
0892 {
0893 edge_t e(*ei);
0894 face_handles[source(e, g)].push_second(e, g);
0895 }
0896 }
0897
0898 bool pertinent(vertex_t w, vertex_t v)
0899 {
0900
0901
0902
0903 return backedge_flag[w] == dfs_number[v]
0904 || !pertinent_roots[w]->empty();
0905 }
0906
0907 bool externally_active(vertex_t w, vertex_t v)
0908 {
0909
0910
0911
0912
0913 v_size_t dfs_number_of_v = dfs_number[v];
0914 return (least_ancestor[w] < dfs_number_of_v)
0915 || (!separated_dfs_child_list[w]->empty()
0916 && low_point[separated_dfs_child_list[w]->front()]
0917 < dfs_number_of_v);
0918 }
0919
0920 bool internally_active(vertex_t w, vertex_t v)
0921 {
0922 return pertinent(w, v) && !externally_active(w, v);
0923 }
0924
0925 void remove_vertex_from_separated_dfs_child_list(vertex_t v)
0926 {
0927 typename vertex_list_t::iterator to_delete
0928 = separated_node_in_parent_list[v];
0929 garbage.splice(garbage.end(), *separated_dfs_child_list[dfs_parent[v]],
0930 to_delete, boost::next(to_delete));
0931 }
0932
0933
0934
0935
0936
0937
0938 public:
0939 template < typename EdgeToBoolPropertyMap, typename EdgeContainer >
0940 vertex_t kuratowski_walkup(vertex_t v, EdgeToBoolPropertyMap forbidden_edge,
0941 EdgeToBoolPropertyMap goal_edge, EdgeToBoolPropertyMap is_embedded,
0942 EdgeContainer& path_edges)
0943 {
0944 vertex_t current_endpoint;
0945 bool seen_goal_edge = false;
0946 out_edge_iterator_t oi, oi_end;
0947
0948 for (boost::tie(oi, oi_end) = out_edges(v, g); oi != oi_end; ++oi)
0949 forbidden_edge[*oi] = true;
0950
0951 for (boost::tie(oi, oi_end) = out_edges(v, g); oi != oi_end; ++oi)
0952 {
0953 path_edges.clear();
0954
0955 edge_t e(*oi);
0956 current_endpoint
0957 = target(*oi, g) == v ? source(*oi, g) : target(*oi, g);
0958
0959 if (dfs_number[current_endpoint] < dfs_number[v] || is_embedded[e]
0960 || v == current_endpoint
0961 )
0962 {
0963
0964 continue;
0965 }
0966
0967 path_edges.push_back(e);
0968 if (goal_edge[e])
0969 {
0970 return current_endpoint;
0971 }
0972
0973 typedef typename face_edge_iterator<>::type walkup_itr_t;
0974
0975 walkup_itr_t walkup_itr(
0976 current_endpoint, face_handles, first_side());
0977 walkup_itr_t walkup_end;
0978
0979 seen_goal_edge = false;
0980
0981 while (true)
0982 {
0983
0984 if (walkup_itr != walkup_end && forbidden_edge[*walkup_itr])
0985 break;
0986
0987 while (walkup_itr != walkup_end && !goal_edge[*walkup_itr]
0988 && !forbidden_edge[*walkup_itr])
0989 {
0990 edge_t f(*walkup_itr);
0991 forbidden_edge[f] = true;
0992 path_edges.push_back(f);
0993 current_endpoint = source(f, g) == current_endpoint
0994 ? target(f, g)
0995 : source(f, g);
0996 ++walkup_itr;
0997 }
0998
0999 if (walkup_itr != walkup_end && goal_edge[*walkup_itr])
1000 {
1001 path_edges.push_back(*walkup_itr);
1002 seen_goal_edge = true;
1003 break;
1004 }
1005
1006 walkup_itr = walkup_itr_t(
1007 current_endpoint, face_handles, first_side());
1008 }
1009
1010 if (seen_goal_edge)
1011 break;
1012 }
1013
1014 if (seen_goal_edge)
1015 return current_endpoint;
1016 else
1017 return graph_traits< Graph >::null_vertex();
1018 }
1019
1020 template < typename OutputIterator, typename EdgeIndexMap >
1021 void extract_kuratowski_subgraph(OutputIterator o_itr, EdgeIndexMap em)
1022 {
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064 vertex_iterator_t vi, vi_end;
1065 edge_iterator_t ei, ei_end;
1066 out_edge_iterator_t oei, oei_end;
1067 typename std::vector< edge_t >::iterator xi, xi_end;
1068
1069
1070
1071
1072 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
1073 {
1074 face_handles[*vi].reset_vertex_cache();
1075 dfs_child_handles[*vi].reset_vertex_cache();
1076 }
1077
1078 vertex_t v = kuratowski_v;
1079 vertex_t x = kuratowski_x;
1080 vertex_t y = kuratowski_y;
1081
1082 typedef iterator_property_map< typename std::vector< bool >::iterator,
1083 EdgeIndexMap >
1084 edge_to_bool_map_t;
1085
1086 std::vector< bool > is_in_subgraph_vector(num_edges(g), false);
1087 edge_to_bool_map_t is_in_subgraph(is_in_subgraph_vector.begin(), em);
1088
1089 std::vector< bool > is_embedded_vector(num_edges(g), false);
1090 edge_to_bool_map_t is_embedded(is_embedded_vector.begin(), em);
1091
1092 typename std::vector< edge_t >::iterator embedded_itr, embedded_end;
1093 embedded_end = embedded_edges.end();
1094 for (embedded_itr = embedded_edges.begin();
1095 embedded_itr != embedded_end; ++embedded_itr)
1096 is_embedded[*embedded_itr] = true;
1097
1098
1099
1100 std::vector< bool > upper_face_vertex_vector(num_vertices(g), false);
1101 vertex_to_bool_map_t upper_face_vertex(
1102 upper_face_vertex_vector.begin(), vm);
1103
1104 std::vector< bool > lower_face_vertex_vector(num_vertices(g), false);
1105 vertex_to_bool_map_t lower_face_vertex(
1106 lower_face_vertex_vector.begin(), vm);
1107
1108
1109
1110 vertex_t z = graph_traits< Graph >::null_vertex();
1111 vertex_t bicomp_root;
1112 vertex_t w = graph_traits< Graph >::null_vertex();
1113 face_handle_t w_handle;
1114 face_handle_t v_dfchild_handle;
1115 vertex_t first_x_y_path_endpoint = graph_traits< Graph >::null_vertex();
1116 vertex_t second_x_y_path_endpoint
1117 = graph_traits< Graph >::null_vertex();
1118 vertex_t w_ancestor = v;
1119
1120 detail::bm_case_t chosen_case = detail::BM_NO_CASE_CHOSEN;
1121
1122 std::vector< edge_t > x_external_path;
1123 std::vector< edge_t > y_external_path;
1124 std::vector< edge_t > case_d_edges;
1125
1126 std::vector< edge_t > z_v_path;
1127 std::vector< edge_t > w_path;
1128
1129
1130
1131
1132
1133 typename face_vertex_iterator<>::type x_upper_itr(
1134 x, face_handles, first_side());
1135 typename face_vertex_iterator<>::type x_lower_itr(
1136 x, face_handles, second_side());
1137 typename face_vertex_iterator<>::type face_itr, face_end;
1138
1139
1140
1141 for (face_itr = x_upper_itr; face_itr != face_end; ++face_itr)
1142 {
1143 if (*face_itr == y)
1144 {
1145 std::swap(x_upper_itr, x_lower_itr);
1146 break;
1147 }
1148 }
1149
1150 upper_face_vertex[x] = true;
1151
1152 vertex_t current_vertex = x;
1153 vertex_t previous_vertex;
1154 for (face_itr = x_upper_itr; face_itr != face_end; ++face_itr)
1155 {
1156 previous_vertex = current_vertex;
1157 current_vertex = *face_itr;
1158 upper_face_vertex[current_vertex] = true;
1159 }
1160
1161 v_dfchild_handle
1162 = dfs_child_handles[canonical_dfs_child[previous_vertex]];
1163
1164 for (face_itr = x_lower_itr; *face_itr != y; ++face_itr)
1165 {
1166 vertex_t current_vertex(*face_itr);
1167 lower_face_vertex[current_vertex] = true;
1168
1169 typename face_handle_list_t::iterator roots_itr, roots_end;
1170
1171 if (w == graph_traits< Graph >::null_vertex())
1172
1173 {
1174 roots_end = pertinent_roots[current_vertex]->end();
1175 for (roots_itr = pertinent_roots[current_vertex]->begin();
1176 roots_itr != roots_end; ++roots_itr)
1177 {
1178 if (low_point
1179 [canonical_dfs_child[roots_itr->first_vertex()]]
1180 < dfs_number[v])
1181 {
1182 w = current_vertex;
1183 w_handle = *roots_itr;
1184 break;
1185 }
1186 }
1187 }
1188 }
1189
1190 for (; face_itr != face_end; ++face_itr)
1191 {
1192 vertex_t current_vertex(*face_itr);
1193 upper_face_vertex[current_vertex] = true;
1194 bicomp_root = current_vertex;
1195 }
1196
1197 typedef typename face_edge_iterator<>::type walkup_itr_t;
1198
1199 std::vector< bool > outer_face_edge_vector(num_edges(g), false);
1200 edge_to_bool_map_t outer_face_edge(outer_face_edge_vector.begin(), em);
1201
1202 walkup_itr_t walkup_end;
1203 for (walkup_itr_t walkup_itr(x, face_handles, first_side());
1204 walkup_itr != walkup_end; ++walkup_itr)
1205 {
1206 outer_face_edge[*walkup_itr] = true;
1207 is_in_subgraph[*walkup_itr] = true;
1208 }
1209
1210 for (walkup_itr_t walkup_itr(x, face_handles, second_side());
1211 walkup_itr != walkup_end; ++walkup_itr)
1212 {
1213 outer_face_edge[*walkup_itr] = true;
1214 is_in_subgraph[*walkup_itr] = true;
1215 }
1216
1217 std::vector< bool > forbidden_edge_vector(num_edges(g), false);
1218 edge_to_bool_map_t forbidden_edge(forbidden_edge_vector.begin(), em);
1219
1220 std::vector< bool > goal_edge_vector(num_edges(g), false);
1221 edge_to_bool_map_t goal_edge(goal_edge_vector.begin(), em);
1222
1223
1224
1225 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
1226 {
1227 edge_t e(*ei);
1228 goal_edge[e] = !outer_face_edge[e]
1229 && (source(e, g) == x || target(e, g) == x);
1230 forbidden_edge[*ei] = outer_face_edge[*ei];
1231 }
1232
1233 vertex_t x_ancestor = v;
1234 vertex_t x_endpoint = graph_traits< Graph >::null_vertex();
1235
1236 while (x_endpoint == graph_traits< Graph >::null_vertex())
1237 {
1238 x_ancestor = dfs_parent[x_ancestor];
1239 x_endpoint = kuratowski_walkup(x_ancestor, forbidden_edge,
1240 goal_edge, is_embedded, x_external_path);
1241 }
1242
1243 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
1244 {
1245 edge_t e(*ei);
1246 goal_edge[e] = !outer_face_edge[e]
1247 && (source(e, g) == y || target(e, g) == y);
1248 forbidden_edge[*ei] = outer_face_edge[*ei];
1249 }
1250
1251 vertex_t y_ancestor = v;
1252 vertex_t y_endpoint = graph_traits< Graph >::null_vertex();
1253
1254 while (y_endpoint == graph_traits< Graph >::null_vertex())
1255 {
1256 y_ancestor = dfs_parent[y_ancestor];
1257 y_endpoint = kuratowski_walkup(y_ancestor, forbidden_edge,
1258 goal_edge, is_embedded, y_external_path);
1259 }
1260
1261 vertex_t parent, child;
1262
1263
1264 if (bicomp_root != v)
1265 {
1266 chosen_case = detail::BM_CASE_A;
1267
1268 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
1269 if (lower_face_vertex[*vi])
1270 for (boost::tie(oei, oei_end) = out_edges(*vi, g);
1271 oei != oei_end; ++oei)
1272 if (!outer_face_edge[*oei])
1273 goal_edge[*oei] = true;
1274
1275 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
1276 forbidden_edge[*ei] = outer_face_edge[*ei];
1277
1278 z = kuratowski_walkup(
1279 v, forbidden_edge, goal_edge, is_embedded, z_v_path);
1280 }
1281 else if (w != graph_traits< Graph >::null_vertex())
1282 {
1283 chosen_case = detail::BM_CASE_B;
1284
1285 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
1286 {
1287 edge_t e(*ei);
1288 goal_edge[e] = false;
1289 forbidden_edge[e] = outer_face_edge[e];
1290 }
1291
1292 goal_edge[w_handle.first_edge()] = true;
1293 goal_edge[w_handle.second_edge()] = true;
1294
1295 z = kuratowski_walkup(
1296 v, forbidden_edge, goal_edge, is_embedded, z_v_path);
1297
1298 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
1299 {
1300 forbidden_edge[*ei] = outer_face_edge[*ei];
1301 }
1302
1303 typename std::vector< edge_t >::iterator pi, pi_end;
1304 pi_end = z_v_path.end();
1305 for (pi = z_v_path.begin(); pi != pi_end; ++pi)
1306 {
1307 goal_edge[*pi] = true;
1308 }
1309
1310 w_ancestor = v;
1311 vertex_t w_endpoint = graph_traits< Graph >::null_vertex();
1312
1313 while (w_endpoint == graph_traits< Graph >::null_vertex())
1314 {
1315 w_ancestor = dfs_parent[w_ancestor];
1316 w_endpoint = kuratowski_walkup(
1317 w_ancestor, forbidden_edge, goal_edge, is_embedded, w_path);
1318 }
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328 if ((w_path.back() == w_handle.first_edge()
1329 && z_v_path.back() == w_handle.second_edge())
1330 || (w_path.back() == w_handle.second_edge()
1331 && z_v_path.back() == w_handle.first_edge()))
1332 {
1333 walkup_itr_t wi, wi_end;
1334 edge_t final_edge = w_path.back();
1335 vertex_t anchor = source(final_edge, g) == w_handle.get_anchor()
1336 ? target(final_edge, g)
1337 : source(final_edge, g);
1338 if (face_handles[anchor].first_edge() == final_edge)
1339 wi = walkup_itr_t(anchor, face_handles, second_side());
1340 else
1341 wi = walkup_itr_t(anchor, face_handles, first_side());
1342
1343 w_path.pop_back();
1344
1345 for (; wi != wi_end; ++wi)
1346 {
1347 edge_t e(*wi);
1348 if (w_path.back() == e)
1349 w_path.pop_back();
1350 else
1351 w_path.push_back(e);
1352 }
1353 }
1354 }
1355 else
1356 {
1357
1358
1359
1360
1361
1362 chosen_case = detail::BM_CASE_E;
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375 for (face_itr = x_lower_itr; *face_itr != y; ++face_itr)
1376 {
1377 vertex_t possible_z(*face_itr);
1378 if (pertinent(possible_z, v)
1379 && outer_face_edge[face_handles[possible_z]
1380 .old_first_edge()]
1381 && outer_face_edge[face_handles[possible_z]
1382 .old_second_edge()])
1383 {
1384 z = possible_z;
1385 break;
1386 }
1387 }
1388
1389
1390
1391 if (externally_active(z, v))
1392 w = z;
1393
1394 typedef typename face_edge_iterator< single_side,
1395 previous_iteration >::type old_face_iterator_t;
1396
1397 old_face_iterator_t first_old_face_itr(
1398 z, face_handles, first_side());
1399 old_face_iterator_t second_old_face_itr(
1400 z, face_handles, second_side());
1401 old_face_iterator_t old_face_itr, old_face_end;
1402
1403 std::vector< old_face_iterator_t > old_face_iterators;
1404 old_face_iterators.push_back(first_old_face_itr);
1405 old_face_iterators.push_back(second_old_face_itr);
1406
1407 std::vector< bool > x_y_path_vertex_vector(num_vertices(g), false);
1408 vertex_to_bool_map_t x_y_path_vertex(
1409 x_y_path_vertex_vector.begin(), vm);
1410
1411 typename std::vector< old_face_iterator_t >::iterator of_itr,
1412 of_itr_end;
1413 of_itr_end = old_face_iterators.end();
1414 for (of_itr = old_face_iterators.begin(); of_itr != of_itr_end;
1415 ++of_itr)
1416 {
1417
1418 old_face_itr = *of_itr;
1419
1420 vertex_t previous_vertex;
1421 bool seen_x_or_y = false;
1422 vertex_t current_vertex = z;
1423 for (; old_face_itr != old_face_end; ++old_face_itr)
1424 {
1425 edge_t e(*old_face_itr);
1426 previous_vertex = current_vertex;
1427 current_vertex = source(e, g) == current_vertex
1428 ? target(e, g)
1429 : source(e, g);
1430
1431 if (current_vertex == x || current_vertex == y)
1432 seen_x_or_y = true;
1433
1434 if (w == graph_traits< Graph >::null_vertex()
1435 && externally_active(current_vertex, v)
1436 && outer_face_edge[e]
1437 && outer_face_edge[*boost::next(old_face_itr)]
1438 && !seen_x_or_y)
1439 {
1440 w = current_vertex;
1441 }
1442
1443 if (!outer_face_edge[e])
1444 {
1445 if (!upper_face_vertex[current_vertex]
1446 && !lower_face_vertex[current_vertex])
1447 {
1448 x_y_path_vertex[current_vertex] = true;
1449 }
1450
1451 is_in_subgraph[e] = true;
1452 if (upper_face_vertex[source(e, g)]
1453 || lower_face_vertex[source(e, g)])
1454 {
1455 if (first_x_y_path_endpoint
1456 == graph_traits< Graph >::null_vertex())
1457 first_x_y_path_endpoint = source(e, g);
1458 else
1459 second_x_y_path_endpoint = source(e, g);
1460 }
1461 if (upper_face_vertex[target(e, g)]
1462 || lower_face_vertex[target(e, g)])
1463 {
1464 if (first_x_y_path_endpoint
1465 == graph_traits< Graph >::null_vertex())
1466 first_x_y_path_endpoint = target(e, g);
1467 else
1468 second_x_y_path_endpoint = target(e, g);
1469 }
1470 }
1471 else if (previous_vertex == x || previous_vertex == y)
1472 {
1473 chosen_case = detail::BM_CASE_C;
1474 }
1475 }
1476 }
1477
1478
1479
1480
1481
1482
1483 out_edge_iterator_t v_edge_itr, v_edge_end;
1484 for (boost::tie(v_edge_itr, v_edge_end) = out_edges(v, g);
1485 v_edge_itr != v_edge_end; ++v_edge_itr)
1486 {
1487 edge_t embedded_edge(*v_edge_itr);
1488
1489 if (!is_embedded[embedded_edge]
1490 || embedded_edge == dfs_parent_edge[v])
1491 continue;
1492
1493 case_d_edges.push_back(embedded_edge);
1494
1495 vertex_t current_vertex = source(embedded_edge, g) == v
1496 ? target(embedded_edge, g)
1497 : source(embedded_edge, g);
1498
1499 typename face_edge_iterator<>::type internal_face_itr,
1500 internal_face_end;
1501 if (face_handles[current_vertex].first_vertex() == v)
1502 {
1503 internal_face_itr = typename face_edge_iterator<>::type(
1504 current_vertex, face_handles, second_side());
1505 }
1506 else
1507 {
1508 internal_face_itr = typename face_edge_iterator<>::type(
1509 current_vertex, face_handles, first_side());
1510 }
1511
1512 while (internal_face_itr != internal_face_end
1513 && !outer_face_edge[*internal_face_itr]
1514 && !x_y_path_vertex[current_vertex])
1515 {
1516 edge_t e(*internal_face_itr);
1517 case_d_edges.push_back(e);
1518 current_vertex = source(e, g) == current_vertex
1519 ? target(e, g)
1520 : source(e, g);
1521 ++internal_face_itr;
1522 }
1523
1524 if (x_y_path_vertex[current_vertex])
1525 {
1526 chosen_case = detail::BM_CASE_D;
1527 break;
1528 }
1529 else
1530 {
1531 case_d_edges.clear();
1532 }
1533 }
1534 }
1535
1536 if (chosen_case != detail::BM_CASE_B
1537 && chosen_case != detail::BM_CASE_A)
1538 {
1539
1540
1541
1542 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
1543 {
1544 edge_t e(*ei);
1545 goal_edge[e] = !outer_face_edge[e]
1546 && (source(e, g) == z || target(e, g) == z);
1547 forbidden_edge[e] = outer_face_edge[e];
1548 }
1549
1550 kuratowski_walkup(
1551 v, forbidden_edge, goal_edge, is_embedded, z_v_path);
1552
1553 if (chosen_case == detail::BM_CASE_E)
1554 {
1555
1556 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
1557 {
1558 forbidden_edge[*ei] = outer_face_edge[*ei];
1559 goal_edge[*ei] = !outer_face_edge[*ei]
1560 && (source(*ei, g) == w || target(*ei, g) == w);
1561 }
1562
1563 for (boost::tie(oei, oei_end) = out_edges(w, g); oei != oei_end;
1564 ++oei)
1565 {
1566 if (!outer_face_edge[*oei])
1567 goal_edge[*oei] = true;
1568 }
1569
1570 typename std::vector< edge_t >::iterator pi, pi_end;
1571 pi_end = z_v_path.end();
1572 for (pi = z_v_path.begin(); pi != pi_end; ++pi)
1573 {
1574 goal_edge[*pi] = true;
1575 }
1576
1577 w_ancestor = v;
1578 vertex_t w_endpoint = graph_traits< Graph >::null_vertex();
1579
1580 while (w_endpoint == graph_traits< Graph >::null_vertex())
1581 {
1582 w_ancestor = dfs_parent[w_ancestor];
1583 w_endpoint = kuratowski_walkup(w_ancestor, forbidden_edge,
1584 goal_edge, is_embedded, w_path);
1585 }
1586 }
1587 }
1588
1589
1590
1591
1592
1593
1594 xi_end = x_external_path.end();
1595 for (xi = x_external_path.begin(); xi != xi_end; ++xi)
1596 is_in_subgraph[*xi] = true;
1597
1598 xi_end = y_external_path.end();
1599 for (xi = y_external_path.begin(); xi != xi_end; ++xi)
1600 is_in_subgraph[*xi] = true;
1601
1602 xi_end = z_v_path.end();
1603 for (xi = z_v_path.begin(); xi != xi_end; ++xi)
1604 is_in_subgraph[*xi] = true;
1605
1606 xi_end = case_d_edges.end();
1607 for (xi = case_d_edges.begin(); xi != xi_end; ++xi)
1608 is_in_subgraph[*xi] = true;
1609
1610 xi_end = w_path.end();
1611 for (xi = w_path.begin(); xi != xi_end; ++xi)
1612 is_in_subgraph[*xi] = true;
1613
1614 child = bicomp_root;
1615 parent = dfs_parent[child];
1616 while (child != parent)
1617 {
1618 is_in_subgraph[dfs_parent_edge[child]] = true;
1619 boost::tie(parent, child)
1620 = std::make_pair(dfs_parent[parent], parent);
1621 }
1622
1623
1624
1625
1626
1627
1628
1629 if (chosen_case == detail::BM_CASE_B)
1630 {
1631 is_in_subgraph[dfs_parent_edge[v]] = false;
1632 }
1633 else if (chosen_case == detail::BM_CASE_C)
1634 {
1635
1636
1637
1638
1639
1640
1641
1642 typename face_vertex_iterator< single_side, follow_visitor >::type
1643 face_itr,
1644 face_end;
1645 if (face_handles[v_dfchild_handle.first_vertex()].first_edge()
1646 == v_dfchild_handle.first_edge())
1647 {
1648 face_itr = typename face_vertex_iterator< single_side,
1649 follow_visitor >::type(v_dfchild_handle.first_vertex(),
1650 face_handles, second_side());
1651 }
1652 else
1653 {
1654 face_itr = typename face_vertex_iterator< single_side,
1655 follow_visitor >::type(v_dfchild_handle.first_vertex(),
1656 face_handles, first_side());
1657 }
1658
1659 for (; true; ++face_itr)
1660 {
1661 vertex_t current_vertex(*face_itr);
1662 if (current_vertex == x || current_vertex == y)
1663 {
1664 is_in_subgraph[v_dfchild_handle.first_edge()] = false;
1665 break;
1666 }
1667 else if (current_vertex == first_x_y_path_endpoint
1668 || current_vertex == second_x_y_path_endpoint)
1669 {
1670 is_in_subgraph[v_dfchild_handle.second_edge()] = false;
1671 break;
1672 }
1673 }
1674 }
1675 else if (chosen_case == detail::BM_CASE_D)
1676 {
1677
1678
1679
1680
1681
1682 is_in_subgraph[v_dfchild_handle.first_edge()] = false;
1683 is_in_subgraph[v_dfchild_handle.second_edge()] = false;
1684 }
1685 else if (chosen_case == detail::BM_CASE_E)
1686 {
1687
1688
1689
1690
1691 if ((first_x_y_path_endpoint != x && first_x_y_path_endpoint != y)
1692 || (second_x_y_path_endpoint != x
1693 && second_x_y_path_endpoint != y))
1694 {
1695 is_in_subgraph[dfs_parent_edge[v]] = false;
1696
1697 vertex_t deletion_endpoint, other_endpoint;
1698 if (lower_face_vertex[first_x_y_path_endpoint])
1699 {
1700 deletion_endpoint = second_x_y_path_endpoint;
1701 other_endpoint = first_x_y_path_endpoint;
1702 }
1703 else
1704 {
1705 deletion_endpoint = first_x_y_path_endpoint;
1706 other_endpoint = second_x_y_path_endpoint;
1707 }
1708
1709 typename face_edge_iterator<>::type face_itr, face_end;
1710
1711 bool found_other_endpoint = false;
1712 for (face_itr = typename face_edge_iterator<>::type(
1713 deletion_endpoint, face_handles, first_side());
1714 face_itr != face_end; ++face_itr)
1715 {
1716 edge_t e(*face_itr);
1717 if (source(e, g) == other_endpoint
1718 || target(e, g) == other_endpoint)
1719 {
1720 found_other_endpoint = true;
1721 break;
1722 }
1723 }
1724
1725 if (found_other_endpoint)
1726 {
1727 is_in_subgraph[face_handles[deletion_endpoint].first_edge()]
1728 = false;
1729 }
1730 else
1731 {
1732 is_in_subgraph[face_handles[deletion_endpoint]
1733 .second_edge()]
1734 = false;
1735 }
1736 }
1737 }
1738
1739 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
1740 if (is_in_subgraph[*ei])
1741 *o_itr = *ei;
1742 }
1743
1744 template < typename EdgePermutation >
1745 void make_edge_permutation(EdgePermutation perm)
1746 {
1747 vertex_iterator_t vi, vi_end;
1748 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
1749 {
1750 vertex_t v(*vi);
1751 perm[v].clear();
1752 face_handles[v].get_list(std::back_inserter(perm[v]));
1753 }
1754 }
1755
1756 private:
1757 const Graph& g;
1758 VertexIndexMap vm;
1759
1760 vertex_t kuratowski_v;
1761 vertex_t kuratowski_x;
1762 vertex_t kuratowski_y;
1763
1764 vertex_list_t garbage;
1765
1766
1767
1768 std::vector< vertex_t > current_merge_points;
1769 std::vector< edge_t > embedded_edges;
1770
1771
1772 std::vector< v_size_t > low_point_vector;
1773 std::vector< vertex_t > dfs_parent_vector;
1774 std::vector< v_size_t > dfs_number_vector;
1775 std::vector< v_size_t > least_ancestor_vector;
1776 std::vector< face_handle_list_ptr_t > pertinent_roots_vector;
1777 std::vector< v_size_t > backedge_flag_vector;
1778 std::vector< v_size_t > visited_vector;
1779 std::vector< face_handle_t > face_handles_vector;
1780 std::vector< face_handle_t > dfs_child_handles_vector;
1781 std::vector< vertex_list_ptr_t > separated_dfs_child_list_vector;
1782 std::vector< typename vertex_list_t::iterator >
1783 separated_node_in_parent_list_vector;
1784 std::vector< vertex_t > canonical_dfs_child_vector;
1785 std::vector< bool > flipped_vector;
1786 std::vector< edge_vector_t > backedges_vector;
1787 edge_vector_t self_loops;
1788 std::vector< edge_t > dfs_parent_edge_vector;
1789 vertex_vector_t vertices_by_dfs_num;
1790
1791
1792 vertex_to_v_size_map_t low_point;
1793 vertex_to_vertex_map_t dfs_parent;
1794 vertex_to_v_size_map_t dfs_number;
1795 vertex_to_v_size_map_t least_ancestor;
1796 vertex_to_face_handle_list_ptr_map_t pertinent_roots;
1797 vertex_to_v_size_map_t backedge_flag;
1798 vertex_to_v_size_map_t visited;
1799 vertex_to_face_handle_map_t face_handles;
1800 vertex_to_face_handle_map_t dfs_child_handles;
1801 vertex_to_vertex_list_ptr_map_t separated_dfs_child_list;
1802 vertex_to_separated_node_map_t separated_node_in_parent_list;
1803 vertex_to_vertex_map_t canonical_dfs_child;
1804 vertex_to_bool_map_t flipped;
1805 vertex_to_edge_vector_map_t backedges;
1806 vertex_to_edge_map_t dfs_parent_edge;
1807
1808 merge_stack_t merge_stack;
1809 };
1810
1811 }
1812
1813 #endif