BOOST_AUTO_TEST_CASE_TEMPLATE( intint_bgl_mutable_graph_test, Graph, intint_graphtest_types ) { typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex; typedef typename boost::graph_traits<Graph>::vertex_iterator VertexIter; typedef typename boost::graph_traits<Graph>::edge_descriptor Edge; typedef typename boost::graph_traits<Graph>::edge_iterator EdgeIter; typedef typename boost::graph_traits<Graph>::out_edge_iterator OutEdgeIter; typedef typename boost::graph_traits<Graph>::in_edge_iterator InEdgeIter; Graph g; Vertex v_root = Vertex(); BOOST_CHECK_NO_THROW( v_root = add_vertex(g) ); BOOST_CHECK_EQUAL( num_vertices(g), 1); BOOST_CHECK_NO_THROW( remove_vertex(v_root,g) ); BOOST_CHECK_EQUAL( num_vertices(g), 0); BOOST_CHECK_NO_THROW( v_root = add_vertex(1, g) ); g[v_root] = 1; BOOST_CHECK_EQUAL( g[v_root], 1 ); int vp_rc[] = {2,3,4,5}; int ep_rc[] = {1002,1003,1004,1005}; Vertex v_rc[4]; Edge e_rc[4]; for(int i = 0; i < 4; ++i) { BOOST_CHECK_NO_THROW( v_rc[i] = add_vertex(g) ); g[ v_rc[i] ] = vp_rc[i]; BOOST_CHECK_EQUAL( g[ v_rc[i] ], vp_rc[i] ); bool edge_added_success = false; BOOST_CHECK_NO_THROW( boost::tie(e_rc[i],edge_added_success) = add_edge(v_root, v_rc[i], g) ); BOOST_CHECK( edge_added_success ); g[ e_rc[i] ] = ep_rc[i]; BOOST_CHECK_EQUAL( g[ e_rc[i] ], ep_rc[i] ); }; BOOST_CHECK_EQUAL( num_vertices(g), 5 ); int vp_rc1c[] = {6,7,8,9}; int ep_rc1c[] = {2006,2007,2008,2009}; Vertex v_rc1c[4]; Edge e_rc1c[4]; for(std::size_t i = 0; i < 4; ++i) { BOOST_CHECK_NO_THROW( v_rc1c[i] = add_vertex(vp_rc1c[i], g) ); BOOST_CHECK_EQUAL( g[ v_rc1c[i] ], vp_rc1c[i] ); bool edge_added_success = false; BOOST_CHECK_NO_THROW( boost::tie(e_rc1c[i],edge_added_success) = add_edge(v_rc[0], v_rc1c[i], ep_rc1c[i], g) ); BOOST_CHECK( edge_added_success ); BOOST_CHECK_EQUAL( g[ e_rc1c[i] ], ep_rc1c[i] ); }; BOOST_CHECK_EQUAL( num_vertices(g), 9 ); BOOST_CHECK_EQUAL( g[v_root], 1 ); { OutEdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei,ei_end) = out_edges(v_root,g) ); std::vector<int> e_list; for(; ei != ei_end; ++ei) { if(is_edge_valid(*ei,g)) { BOOST_CHECK_EQUAL( g[*ei], (g[source(*ei,g)] * 1000 + g[target(*ei,g)]) ); e_list.push_back(g[*ei]); }; }; std::sort(e_list.begin(), e_list.end()); BOOST_CHECK_EQUAL( e_list[0], 1002); BOOST_CHECK_EQUAL( e_list[1], 1003); BOOST_CHECK_EQUAL( e_list[2], 1004); BOOST_CHECK_EQUAL( e_list[3], 1005); InEdgeIter iei, iei_end; BOOST_CHECK_NO_THROW( boost::tie(iei, iei_end) = in_edges(v_rc[0], g) ); BOOST_CHECK( iei != iei_end ); BOOST_CHECK_EQUAL( g[*iei], 1002); ++iei; BOOST_CHECK( iei == iei_end ); BOOST_CHECK_NO_THROW( boost::tie(ei,ei_end) = out_edges(v_rc[0],g) ); std::vector<int> e_list2; for(; ei != ei_end; ++ei) { if(is_edge_valid(*ei,g)) { BOOST_CHECK_EQUAL( g[*ei], (g[source(*ei,g)] * 1000 + g[target(*ei,g)]) ); e_list2.push_back(g[*ei]); }; }; std::sort(e_list2.begin(), e_list2.end()); BOOST_CHECK_EQUAL( e_list2[0], 2006); BOOST_CHECK_EQUAL( e_list2[1], 2007); BOOST_CHECK_EQUAL( e_list2[2], 2008); BOOST_CHECK_EQUAL( e_list2[3], 2009); }; int vp_rc2c[] = {10,11,12,13}; int ep_rc2c[] = {3010,3011,3012,3013}; Vertex v_rc2c[4]; Edge e_rc2c[4]; for(std::size_t i = 0; i < 4; ++i) { #ifdef RK_ENABLE_CXX0X_FEATURES BOOST_CHECK_NO_THROW( v_rc2c[i] = add_vertex(std::move(vp_rc2c[i]), g) ); #else BOOST_CHECK_NO_THROW( v_rc2c[i] = add_vertex(vp_rc2c[i], g) ); #endif bool edge_added_success = false; #ifdef RK_ENABLE_CXX0X_FEATURES BOOST_CHECK_NO_THROW( boost::tie(e_rc2c[i],edge_added_success) = add_edge(v_rc[1], v_rc2c[i], ep_rc2c[i], g) ); #else BOOST_CHECK_NO_THROW( boost::tie(e_rc2c[i],edge_added_success) = add_edge(v_rc[1], v_rc2c[i], ep_rc2c[i], g) ); #endif BOOST_CHECK( edge_added_success ); }; BOOST_CHECK_EQUAL( num_vertices(g), 13 ); { OutEdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei,ei_end) = out_edges(v_rc[1],g) ); std::vector<int> e_list; std::vector<int> vp_list; for(; ei != ei_end; ++ei) { if(is_edge_valid(*ei,g)) { BOOST_CHECK_EQUAL( g[*ei], (g[source(*ei,g)] * 1000 + g[target(*ei,g)]) ); e_list.push_back(g[*ei]); vp_list.push_back(g[target(*ei,g)]); }; }; std::sort(e_list.begin(), e_list.end()); BOOST_CHECK_EQUAL( e_list[0], 3010); BOOST_CHECK_EQUAL( e_list[1], 3011); BOOST_CHECK_EQUAL( e_list[2], 3012); BOOST_CHECK_EQUAL( e_list[3], 3013); std::sort(vp_list.begin(), vp_list.end()); BOOST_CHECK_EQUAL( vp_list[0], 10); BOOST_CHECK_EQUAL( vp_list[1], 11); BOOST_CHECK_EQUAL( vp_list[2], 12); BOOST_CHECK_EQUAL( vp_list[3], 13); }; BOOST_CHECK_NO_THROW( clear_vertex(v_rc[0],g) ); BOOST_CHECK_EQUAL( out_degree(v_rc[0], g), 0 ); BOOST_CHECK_EQUAL( in_degree(v_rc[0], g), 0 ); BOOST_CHECK_EQUAL( out_degree(v_root, g), 3 ); BOOST_CHECK_EQUAL( in_degree(v_rc1c[0], g), 0 ); BOOST_CHECK_EQUAL( in_degree(v_rc1c[1], g), 0 ); BOOST_CHECK_EQUAL( in_degree(v_rc1c[2], g), 0 ); BOOST_CHECK_EQUAL( in_degree(v_rc1c[3], g), 0 ); BOOST_CHECK_EQUAL( num_vertices(g), 13 ); { VertexIter vi, vi_end; BOOST_CHECK_NO_THROW( boost::tie(vi, vi_end) = vertices(g) ); std::vector<int> vp_list; for(; vi != vi_end; ++vi) if( is_vertex_valid(*vi, g) ) vp_list.push_back( g[*vi] ); std::sort(vp_list.begin(), vp_list.end()); BOOST_CHECK_EQUAL( vp_list[0], 1 ); BOOST_CHECK_EQUAL( vp_list[1], 2 ); BOOST_CHECK_EQUAL( vp_list[2], 3 ); BOOST_CHECK_EQUAL( vp_list[3], 4 ); BOOST_CHECK_EQUAL( vp_list[4], 5 ); BOOST_CHECK_EQUAL( vp_list[5], 6 ); BOOST_CHECK_EQUAL( vp_list[6], 7 ); BOOST_CHECK_EQUAL( vp_list[7], 8 ); BOOST_CHECK_EQUAL( vp_list[8], 9 ); BOOST_CHECK_EQUAL( vp_list[9], 10 ); BOOST_CHECK_EQUAL( vp_list[10], 11 ); BOOST_CHECK_EQUAL( vp_list[11], 12 ); BOOST_CHECK_EQUAL( vp_list[12], 13 ); }; BOOST_CHECK_EQUAL( num_edges(g), 7 ); { EdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei, ei_end) = edges(g) ); std::vector<int> ep_list; for(; ei != ei_end; ++ei) if( is_edge_valid(*ei, g) ) ep_list.push_back( g[*ei] ); std::sort(ep_list.begin(), ep_list.end()); BOOST_CHECK_EQUAL( ep_list[0], 1003 ); BOOST_CHECK_EQUAL( ep_list[1], 1004 ); BOOST_CHECK_EQUAL( ep_list[2], 1005 ); BOOST_CHECK_EQUAL( ep_list[3], 3010 ); BOOST_CHECK_EQUAL( ep_list[4], 3011 ); BOOST_CHECK_EQUAL( ep_list[5], 3012 ); BOOST_CHECK_EQUAL( ep_list[6], 3013 ); }; BOOST_CHECK_NO_THROW( remove_edge(v_rc[1], v_rc2c[2], g) ); BOOST_CHECK_EQUAL( num_vertices(g), 13 ); { VertexIter vi, vi_end; BOOST_CHECK_NO_THROW( boost::tie(vi, vi_end) = vertices(g) ); std::vector<int> vp_list; for(; vi != vi_end; ++vi) { if( is_vertex_valid(*vi, g) ) { vp_list.push_back( g[*vi] ); }; }; std::sort(vp_list.begin(), vp_list.end()); BOOST_CHECK_EQUAL( vp_list[0], 1 ); BOOST_CHECK_EQUAL( vp_list[1], 2 ); BOOST_CHECK_EQUAL( vp_list[2], 3 ); BOOST_CHECK_EQUAL( vp_list[3], 4 ); BOOST_CHECK_EQUAL( vp_list[4], 5 ); BOOST_CHECK_EQUAL( vp_list[5], 6 ); BOOST_CHECK_EQUAL( vp_list[6], 7 ); BOOST_CHECK_EQUAL( vp_list[7], 8 ); BOOST_CHECK_EQUAL( vp_list[8], 9 ); BOOST_CHECK_EQUAL( vp_list[9], 10 ); BOOST_CHECK_EQUAL( vp_list[10], 11 ); BOOST_CHECK_EQUAL( vp_list[11], 12 ); BOOST_CHECK_EQUAL( vp_list[12], 13 ); }; BOOST_CHECK_EQUAL( num_edges(g), 6 ); { EdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei, ei_end) = edges(g) ); std::vector<int> ep_list; for(; ei != ei_end; ++ei) { if( is_edge_valid(*ei, g) ) { ep_list.push_back( g[*ei] ); }; }; std::sort(ep_list.begin(), ep_list.end()); BOOST_CHECK_EQUAL( ep_list[0], 1003 ); BOOST_CHECK_EQUAL( ep_list[1], 1004 ); BOOST_CHECK_EQUAL( ep_list[2], 1005 ); BOOST_CHECK_EQUAL( ep_list[3], 3010 ); BOOST_CHECK_EQUAL( ep_list[4], 3011 ); BOOST_CHECK_EQUAL( ep_list[5], 3013 ); }; BOOST_CHECK_NO_THROW( remove_edge(e_rc2c[3], g) ); BOOST_CHECK_EQUAL( num_vertices(g), 13 ); { VertexIter vi, vi_end; BOOST_CHECK_NO_THROW( boost::tie(vi, vi_end) = vertices(g) ); std::vector<int> vp_list; for(; vi != vi_end; ++vi) { if( is_vertex_valid(*vi, g) ) { vp_list.push_back( g[*vi] ); }; }; std::sort(vp_list.begin(), vp_list.end()); BOOST_CHECK_EQUAL( vp_list[0], 1 ); BOOST_CHECK_EQUAL( vp_list[1], 2 ); BOOST_CHECK_EQUAL( vp_list[2], 3 ); BOOST_CHECK_EQUAL( vp_list[3], 4 ); BOOST_CHECK_EQUAL( vp_list[4], 5 ); BOOST_CHECK_EQUAL( vp_list[5], 6 ); BOOST_CHECK_EQUAL( vp_list[6], 7 ); BOOST_CHECK_EQUAL( vp_list[7], 8 ); BOOST_CHECK_EQUAL( vp_list[8], 9 ); BOOST_CHECK_EQUAL( vp_list[9], 10 ); BOOST_CHECK_EQUAL( vp_list[10], 11 ); BOOST_CHECK_EQUAL( vp_list[11], 12 ); BOOST_CHECK_EQUAL( vp_list[12], 13 ); }; BOOST_CHECK_EQUAL( num_edges(g), 5 ); { EdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei, ei_end) = edges(g) ); std::vector<int> ep_list; for(; ei != ei_end; ++ei) { if( is_edge_valid(*ei, g) ) { ep_list.push_back( g[*ei] ); }; }; std::sort(ep_list.begin(), ep_list.end()); BOOST_CHECK_EQUAL( ep_list[0], 1003 ); BOOST_CHECK_EQUAL( ep_list[1], 1004 ); BOOST_CHECK_EQUAL( ep_list[2], 1005 ); BOOST_CHECK_EQUAL( ep_list[3], 3010 ); BOOST_CHECK_EQUAL( ep_list[4], 3011 ); }; BOOST_CHECK_NO_THROW( clear_vertex(v_rc2c[0], g) ); BOOST_CHECK_NO_THROW( remove_vertex(v_rc2c[0], g) ); BOOST_CHECK_EQUAL( num_vertices(g), 12 ); { VertexIter vi, vi_end; BOOST_CHECK_NO_THROW( boost::tie(vi, vi_end) = vertices(g) ); std::vector<int> vp_list; for(; vi != vi_end; ++vi) { if( is_vertex_valid(*vi, g) ) { vp_list.push_back( g[*vi] ); }; }; std::sort(vp_list.begin(), vp_list.end()); BOOST_CHECK_EQUAL( vp_list[0], 1 ); BOOST_CHECK_EQUAL( vp_list[1], 2 ); BOOST_CHECK_EQUAL( vp_list[2], 3 ); BOOST_CHECK_EQUAL( vp_list[3], 4 ); BOOST_CHECK_EQUAL( vp_list[4], 5 ); BOOST_CHECK_EQUAL( vp_list[5], 6 ); BOOST_CHECK_EQUAL( vp_list[6], 7 ); BOOST_CHECK_EQUAL( vp_list[7], 8 ); BOOST_CHECK_EQUAL( vp_list[8], 9 ); BOOST_CHECK_EQUAL( vp_list[9], 11 ); BOOST_CHECK_EQUAL( vp_list[10], 12 ); BOOST_CHECK_EQUAL( vp_list[11], 13 ); }; BOOST_CHECK_EQUAL( num_edges(g), 4 ); { EdgeIter ei, ei_end; BOOST_CHECK_NO_THROW( boost::tie(ei, ei_end) = edges(g) ); std::vector<int> ep_list; for(; ei != ei_end; ++ei) { if( is_edge_valid(*ei, g) ) { ep_list.push_back( g[*ei] ); }; }; std::sort(ep_list.begin(), ep_list.end()); BOOST_CHECK_EQUAL( ep_list[0], 1003 ); BOOST_CHECK_EQUAL( ep_list[1], 1004 ); BOOST_CHECK_EQUAL( ep_list[2], 1005 ); BOOST_CHECK_EQUAL( ep_list[3], 3011 ); }; };
int main(const int argc, const char* const argv[]) { //! undirected graphs with out-edges stored in lists and the vertices stored in a vector (to enable index-access) typedef boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, boost::property<boost::vertex_name_t, std::string> > UndirectedGraph; typedef boost::graph_traits<UndirectedGraph>::vertex_descriptor vertex_type; typedef boost::graph_traits<UndirectedGraph>::vertices_size_type vertices_size_type; typedef boost::graph_traits<UndirectedGraph>::edges_size_type edges_size_type; UndirectedGraph g; { boost::dynamic_properties p; p.property("node_id", get(boost::vertex_name, g)); boost::read_graphviz(std::cin, g, p); } const vertices_size_type n = num_vertices(g); const edges_size_type m = num_edges(g); std::cout << "\n" << n << ", " << m << std::endl; OKlib::HypergraphColouring::output_vertex_degrees(g, std::cout); std::cout << std::endl; OKlib::HypergraphColouring::Greedy_colouring<UndirectedGraph> fgg(g); assert(fgg.n == n); { typedef std::map<std::string, vertex_type> name_map_type; name_map_type map; for (vertices_size_type i = 0; i < n; ++i) map.insert(std::make_pair(get(boost::vertex_name, g, fgg.given_order[i]), fgg.given_order[i])); assert(map.size() == n); typedef name_map_type::const_iterator iterator; const iterator end(map.end()); vertices_size_type i = 0; for (iterator j(map.begin()); j != end; ++i, ++j) fgg.running_order[i] = j -> second; } fgg.colouring(); std::cout << "lexicographical order = " << fgg.num_colours << std::endl; for (vertices_size_type i = 0; i < n; ++i) std::cout << get(boost::vertex_name, g, fgg.running_order[i]) << " "; std::cout << std::endl; for (vertices_size_type i = 0; i < n; ++i) std::cout << get(boost::vertex_name, g, fgg.running_order[i]) << " -> " << fgg.colour_vec[get(boost::vertex_index, g, fgg.running_order[i])] << ", "; std::cout << std::endl; std::stable_sort(fgg.running_order.begin(), fgg.running_order.end(), fgg.sort); fgg.colouring(); std::cout << "smallest degrees first = " << fgg.num_colours << std::endl; for (vertices_size_type i = 0; i < n; ++i) std::cout << get(boost::vertex_name, g, fgg.running_order[i]) << " "; std::cout << std::endl; for (vertices_size_type i = 0; i < n; ++i) std::cout << get(boost::vertex_name, g, fgg.running_order[i]) << " -> " << fgg.colour_vec[get(boost::vertex_index, g, fgg.running_order[i])] << ", "; std::cout << std::endl; std::reverse(fgg.running_order.begin(), fgg.running_order.end()); fgg.colouring(); std::cout << "largest degrees first = " << fgg.num_colours << std::endl; for (vertices_size_type i = 0; i < n; ++i) std::cout << get(boost::vertex_name, g, fgg.running_order[i]) << " "; std::cout << std::endl; for (vertices_size_type i = 0; i < n; ++i) std::cout << get(boost::vertex_name, g, fgg.running_order[i]) << " -> " << fgg.colour_vec[get(boost::vertex_index, g, fgg.running_order[i])] << ", "; std::cout << std::endl; if (argc > 1) { fgg.evaluation(); std::cout << "\n"; for (vertices_size_type i = 0; i <= n; ++i) std::cout << i << " : " << fgg.hash_orders[i] << "\n"; std::cout << std::endl; std::cout << "min numbers of colours = " << fgg.min_colours << std::endl; for (vertices_size_type i = 0; i < n; ++i) std::cout << get(boost::vertex_name, g, fgg.optimal_order[i]) << " "; std::cout << std::endl; for (vertices_size_type i = 0; i < n; ++i) std::cout << get(boost::vertex_name, g, fgg.optimal_order[i]) << " -> " << fgg.optimal_colouring[get(boost::vertex_index, g, fgg.optimal_order[i])] << ", "; std::cout << std::endl; std::cout << "max number of colours = " << fgg.max_colours << std::endl; for (vertices_size_type i = 0; i < n; ++i) std::cout << get(boost::vertex_name, g, fgg.worst_order[i]) << " "; std::cout << std::endl; for (vertices_size_type i = 0; i < n; ++i) std::cout << get(boost::vertex_name, g, fgg.worst_order[i]) << " -> " << fgg.worst_colouring[get(boost::vertex_index, g, fgg.worst_order[i])] << ", "; std::cout << std::endl; } }
size_t num_edges(const NGHolder &h) { if (!h.isValidNumEdges) { return num_edges(h.g); } return h.numEdges; }
DANI_INLINE int EpsTrimesh::add_triangle(const int vid0, const int vid1, const int vid2, const int scalar) { assert(vid0 >= 0 && vid0 < num_vertices()); assert(vid1 >= 0 && vid1 < num_vertices()); assert(vid2 >= 0 && vid2 < num_vertices()); int tid = num_triangles(); // tris.push_back(vid0); tris.push_back(vid1); tris.push_back(vid2); // t_label.push_back(scalar); // tri2edg.push_back(std::vector<int>()); tri2tri.push_back(std::vector<int>()); // vtx2tri.at(vid0).push_back(tid); vtx2tri.at(vid1).push_back(tid); vtx2tri.at(vid2).push_back(tid); // ipair new_e[3] = { unique_pair(vid0, vid1), unique_pair(vid1, vid2), unique_pair(vid2, vid0) }; int new_eid[3] = { -1, -1, -1 }; for(int eid=0; eid<num_edges(); ++eid) { ipair e = unique_pair(edge_vertex_id(eid, 0), edge_vertex_id(eid, 1)); for(int i=0; i<3; ++i) if (e == new_e[i]) new_eid[i] = eid; } // for(int i=0; i<3; ++i) { if (new_eid[i] == -1) { new_eid[i] = num_edges(); edges.push_back(new_e[i].first); edges.push_back(new_e[i].second); edg2tri.push_back(std::vector<int>()); vtx2edg.at(new_e[i].first).push_back(num_edges()-1); vtx2edg.at(new_e[i].second).push_back(num_edges()-1); vtx2vtx.at(new_e[i].first).push_back(new_e[i].second); vtx2vtx.at(new_e[i].second).push_back(new_e[i].first); } // for(int nbr : edg2tri.at(new_eid[i])) { tri2tri.at(nbr).push_back(tid); tri2tri.at(tid).push_back(nbr); } edg2tri.at(new_eid[i]).push_back(tid); tri2edg.at(tid).push_back(new_eid[i]); } // t_norm.push_back(0); //tnx t_norm.push_back(0); //tny t_norm.push_back(0); //tnz #ifdef CINOLIB // update_t_normal(tid); update_v_normal(vid0); update_v_normal(vid1); update_v_normal(vid2); #else std::cerr << "[WARNING] Cinolib required to update triangle and vertex normals." << std::endl; #endif return tid; }
void planar_face_traversal(const Graph& g, PlanarEmbedding embedding, Visitor& visitor, EdgeIndexMap em ) { typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; typedef typename graph_traits<Graph>::edge_descriptor edge_t; typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t; typedef typename graph_traits<Graph>::edge_iterator edge_iterator_t; typedef typename property_traits<PlanarEmbedding>::value_type embedding_value_t; typedef typename embedding_value_t::const_iterator embedding_iterator_t; typedef typename std::vector< std::set<vertex_t> > distinguished_edge_storage_t; typedef typename std::vector< std::map<vertex_t, edge_t> > distinguished_edge_to_edge_storage_t; typedef typename boost::iterator_property_map <typename distinguished_edge_storage_t::iterator, EdgeIndexMap> distinguished_edge_map_t; typedef typename boost::iterator_property_map <typename distinguished_edge_to_edge_storage_t::iterator, EdgeIndexMap> distinguished_edge_to_edge_map_t; distinguished_edge_storage_t visited_vector(num_edges(g)); distinguished_edge_to_edge_storage_t next_edge_vector(num_edges(g)); distinguished_edge_map_t visited(visited_vector.begin(), em); distinguished_edge_to_edge_map_t next_edge(next_edge_vector.begin(), em); vertex_iterator_t vi, vi_end; typename std::vector<edge_t>::iterator ei, ei_end; edge_iterator_t fi, fi_end; embedding_iterator_t pi, pi_begin, pi_end; visitor.begin_traversal(); // Initialize the next_edge property map. This map is initialized from the // PlanarEmbedding so that get(next_edge, e)[v] is the edge that comes // after e in the clockwise embedding around vertex v. for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) { vertex_t v(*vi); pi_begin = embedding[v].begin(); pi_end = embedding[v].end(); for(pi = pi_begin; pi != pi_end; ++pi) { edge_t e(*pi); std::map<vertex_t, edge_t> m = get(next_edge, e); m[v] = boost::next(pi) == pi_end ? *pi_begin : *boost::next(pi); put(next_edge, e, m); } } // Take a copy of the edges in the graph here, since we want to accomodate // face traversals that add edges to the graph (for triangulation, in // particular) and don't want to use invalidated edge iterators. // Also, while iterating over all edges in the graph, we single out // any self-loops, which need some special treatment in the face traversal. std::vector<edge_t> self_loops; std::vector<edge_t> edges_cache; std::vector<vertex_t> vertices_in_edge; for(boost::tie(fi,fi_end) = edges(g); fi != fi_end; ++fi) { edge_t e(*fi); edges_cache.push_back(e); if (source(e,g) == target(e,g)) self_loops.push_back(e); } // Iterate over all edges in the graph ei_end = edges_cache.end(); for(ei = edges_cache.begin(); ei != ei_end; ++ei) { edge_t e(*ei); vertices_in_edge.clear(); vertices_in_edge.push_back(source(e,g)); vertices_in_edge.push_back(target(e,g)); typename std::vector<vertex_t>::iterator vi, vi_end; vi_end = vertices_in_edge.end(); //Iterate over both vertices in the current edge for(vi = vertices_in_edge.begin(); vi != vi_end; ++vi) { vertex_t v(*vi); std::set<vertex_t> e_visited = get(visited, e); typename std::set<vertex_t>::iterator e_visited_found = e_visited.find(v); if (e_visited_found == e_visited.end()) visitor.begin_face(); while (e_visited.find(v) == e_visited.end()) { visitor.next_vertex(v); visitor.next_edge(e); e_visited.insert(v); put(visited, e, e_visited); v = source(e,g) == v ? target(e,g) : source(e,g); e = get(next_edge, e)[v]; e_visited = get(visited, e); } if (e_visited_found == e_visited.end()) visitor.end_face(); } } // Iterate over all self-loops, visiting them once separately // (they've already been visited once, this visitation is for // the "inside" of the self-loop) ei_end = self_loops.end(); for(ei = self_loops.begin(); ei != ei_end; ++ei) { visitor.begin_face(); visitor.next_edge(*ei); visitor.next_vertex(source(*ei,g)); visitor.end_face(); } visitor.end_traversal(); }