Go to the documentation of this file.00001 #ifndef OPENTISSUE_COLLISION_AABB_TREE_POLICIES_AABB_TREE_GRAPH_CONVERTER_H
00002 #define OPENTISSUE_COLLISION_AABB_TREE_POLICIES_AABB_TREE_GRAPH_CONVERTER_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 namespace OpenTissue
00013 {
00014 namespace aabb_tree
00015 {
00016 template <typename graph_type>
00017 class GraphConverter
00018 {
00019 public:
00020
00021 typedef typename graph_type::geometry_type geometry_type;
00022 typedef typename graph_type::volume_type volume_type;
00023 typedef typename graph_type::node_ptr_type node_ptr;
00024
00025 public:
00026
00039 template<
00040 typename mesh_type
00041 , typename vertex_data_binder
00042 >
00043 void run(mesh_type & mesh, graph_type & graph, vertex_data_binder & binder)
00044 {
00045 typedef typename mesh_type::halfedge_type halfedge_type;
00046 typedef typename mesh_type::face_type face_type;
00047 typedef typename mesh_type::vertex_type vertex_type;
00048 typedef typename mesh_type::face_iterator face_iterator;
00049
00050 typedef typename std::queue<face_type*> face_ptr_queue;
00051 typedef typename std::map<face_type *,node_ptr> graph_node_map;
00052
00053 graph_node_map lookup;
00054 lookup.clear();
00055
00056 face_iterator face = mesh.face_begin();
00057 face_iterator end = mesh.face_end();
00058 for(;face!=end;++face)
00059 {
00060 geometry_type triangle;
00061
00062 typename mesh_type::face_vertex_circulator v0(*face);
00063 typename mesh_type::face_vertex_circulator v1(*face);++v1;
00064 typename mesh_type::face_vertex_circulator v2(*face);++v2;++v2;
00065
00066
00067 triangle.m_p0 = binder( &(*v0) );
00068 triangle.m_p1 = binder( &(*v1) );
00069 triangle.m_p2 = binder( &(*v2) );
00070
00071 node_ptr node = graph.insert( triangle );
00072 lookup[ &(*face) ] = node;
00073 }
00074
00075 face_ptr_queue Q;
00076
00077 mesh::clear_face_tags(mesh);
00078 mesh::clear_halfedge_tags(mesh);
00079
00080 Q.push( &( *(mesh.face_begin()) ) );
00081 while(!Q.empty())
00082 {
00083 face_type * face = Q.front(); Q.pop();
00084
00085 face->m_tag = 1;
00086
00087 typename mesh_type::face_halfedge_circulator h(*face),hend;
00088 for(;h!=hend;++h)
00089 visist_connection( face, &(*h), Q, graph, lookup);
00090
00091 }
00092 std::cout << "GraphConverter::run(): graph created with |N| = "
00093 << graph.size_nodes()
00094 << " and |E| = "
00095 << graph.size_edges()
00096 << std::endl;
00097 }
00098
00099 protected:
00100
00113 template<
00114 typename face_type
00115 , typename halfedge_type
00116 , typename face_ptr_queue
00117 , typename lookup_map
00118 >
00119 void visist_connection( face_type * face, halfedge_type * edge, face_ptr_queue & Q, graph_type & graph, lookup_map & lookup )
00120 {
00121
00122 if(edge->get_twin_handle().is_null())
00123 return;
00124
00125 if(edge->m_tag == 1)
00126 return;
00127
00128 halfedge_type * twin_edge = &(*edge->get_twin_iterator());
00129
00130 if(twin_edge->get_face_handle().is_null())
00131 return;
00132
00133 face_type * twin_face = &(*(twin_edge->get_face_iterator()));
00134
00135 node_ptr A = lookup[face];
00136 node_ptr B = lookup[twin_face];
00137
00138 assert(A!=B);
00139
00140 edge->m_tag = 1;
00141 twin_edge->m_tag = 1;
00142
00143 graph.insert(A,B);
00144
00145 if(twin_face->m_tag == 0)
00146 Q.push(twin_face);
00147 }
00148
00149 };
00150
00151 }
00152 }
00153
00154
00155 #endif