Go to the documentation of this file.00001 #ifndef OPENTISSUE_COLLISION_BVH_BOTTOM_UP_CONSTRUCTOR_BVH_GRAPH_H
00002 #define OPENTISSUE_COLLISION_BVH_BOTTOM_UP_CONSTRUCTOR_BVH_GRAPH_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/collision/bvh/bottom_up_constructor/bvh_graph_node.h>
00013 #include <OpenTissue/collision/bvh/bottom_up_constructor/bvh_graph_edge.h>
00014
00015 #include <boost/shared_ptr.hpp>
00016 #include <boost/iterator/indirect_iterator.hpp>
00017
00018 #include <cmath>
00019 #include <list>
00020 #include <iostream>
00021
00022 namespace OpenTissue
00023 {
00024 namespace bvh
00025 {
00026
00031 template <typename bvh_type>
00032 class BVHGraph
00033 {
00034 public:
00035
00036
00037 typedef BVHGraph<bvh_type> graph_type;
00038 typedef BVHGraphNode<bvh_type> node_type;
00039 typedef BVHGraphEdge<bvh_type> edge_type;
00040
00041
00042 typedef boost::shared_ptr<node_type> node_ptr_type;
00043 typedef boost::shared_ptr<edge_type> edge_ptr_type;
00044 typedef boost::shared_ptr<node_type const> const_node_ptr_type;
00045 typedef boost::shared_ptr<edge_type const> const_edge_ptr_type;
00046 typedef typename bvh_type::geometry_container geometry_container;
00047 typedef typename bvh_type::geometry_type geometry_type;
00048 typedef typename bvh_type::volume_type volume_type;
00049 typedef typename std::list<volume_type> volume_container;
00050 typedef float real_type;
00051
00052 public:
00053
00054 typedef typename std::list< edge_ptr_type > edge_ptr_container;
00055 typedef typename edge_ptr_container::iterator edge_ptr_iterator;
00056 typedef typename edge_ptr_container::const_iterator const_edge_ptr_iterator;
00057 typedef boost::indirect_iterator<edge_ptr_iterator,edge_type> edge_iterator;
00058 typedef boost::indirect_iterator<const_edge_ptr_iterator,edge_type> const_edge_iterator;
00059
00060 edge_iterator edge_begin() { return edge_iterator(m_edges.begin()); }
00061 edge_iterator edge_end() { return edge_iterator(m_edges.end()); }
00062 const_edge_iterator edge_begin() const { return const_edge_iterator(m_edges.begin()); }
00063 const_edge_iterator edge_end() const { return const_edge_iterator(m_edges.end()); }
00064
00065 edge_ptr_iterator edge_ptr_begin() { return m_edges.begin(); }
00066 edge_ptr_iterator edge_ptr_end() { return m_edges.end(); }
00067 const_edge_ptr_iterator edge_ptr_begin() const { return m_edges.begin(); }
00068 const_edge_ptr_iterator edge_ptr_end() const { return m_edges.end(); }
00069
00070 typedef typename std::list< node_ptr_type > node_ptr_container;
00071 typedef typename node_ptr_container::iterator node_ptr_iterator;
00072 typedef typename node_ptr_container::const_iterator const_node_ptr_iterator;
00073 typedef boost::indirect_iterator<node_ptr_iterator,node_type> node_iterator;
00074 typedef boost::indirect_iterator<const_node_ptr_iterator,node_type> const_node_iterator;
00075
00076 node_iterator node_begin() { return node_iterator(m_nodes.begin()); }
00077 node_iterator node_end() { return node_iterator(m_nodes.end()); }
00078 const_node_iterator node_begin() const { return const_node_iterator(m_nodes.begin()); }
00079 const_node_iterator node_end() const { return const_node_iterator(m_nodes.end()); }
00080
00081 node_ptr_iterator node_ptr_begin() { return m_nodes.begin(); }
00082 node_ptr_iterator node_ptr_end() { return m_nodes.end(); }
00083 const_node_ptr_iterator node_ptr_begin() const { return m_nodes.begin(); }
00084 const_node_ptr_iterator node_ptr_end() const { return m_nodes.end(); }
00085
00086 public:
00087
00088 edge_ptr_container m_edges;
00089
00090 protected:
00091 node_ptr_container m_nodes;
00092
00093 public:
00094
00095 BVHGraph(){}
00096
00097 ~BVHGraph() { clear(); }
00098
00099 public:
00100
00106 std::size_t size_edges() const {return m_edges.size();}
00107
00113 std::size_t size_nodes()const{return m_nodes.size();}
00114
00122 node_ptr_type insert(geometry_type const & g){ return insert(volume_type(),g); }
00123
00131 node_ptr_type insert(volume_type const & volume)
00132 {
00133 geometry_container G;
00134 return insert(volume,G);
00135 }
00136
00145 node_ptr_type insert(volume_type const & volume,geometry_type const & g)
00146 {
00147 geometry_container G;
00148 G.push_back(g);
00149 return insert(volume,G);
00150 }
00151
00160 node_ptr_type insert(volume_type const & volume,geometry_container & geometry)
00161 {
00162 node_ptr_type node( new node_type() );
00163 node->m_volume = volume;
00164 if(!geometry.empty())
00165 {
00166
00167
00168 node->m_coverage.insert(node->m_coverage.end(),geometry.begin(),geometry.end());
00169 }
00170 m_nodes.push_back(node);
00171 return node;
00172 }
00173
00186 edge_ptr_type insert(node_ptr_type A,node_ptr_type B)
00187 {
00188 assert(A!=B);
00189
00190 edge_ptr_iterator e = A->edge_ptr_begin();
00191 edge_ptr_iterator end = A->edge_ptr_end();
00192 for(;e!=end;++e)
00193 {
00194 if(( (*e)->A()==A && (*e)->B()==B)||( (*e)->A()==B && (*e)->B()==A))
00195 return edge_ptr_type(*e);
00196 }
00197 edge_ptr_type new_edge(new edge_type());
00198 new_edge->m_A = A ;
00199 A->m_edges.push_back(new_edge);
00200 new_edge->m_B = B;
00201 B->m_edges.push_back(new_edge);
00202 m_edges.push_back(new_edge);
00203 return new_edge;
00204 }
00205
00210 void clear()
00211 {
00212 m_nodes.clear();
00213 m_edges.clear();
00214 }
00215
00224 node_ptr_type collapse(edge_ptr_type edge)
00225 {
00226 node_ptr_type C( new node_type() );
00227 node_ptr_type A = edge->A();
00228 node_ptr_type B = edge->B();
00229
00230 C->m_edges.splice(C->m_edges.end(),A->m_edges);
00231 C->m_edges.splice(C->m_edges.end(),B->m_edges);
00232 assert(A->m_edges.empty());
00233 assert(B->m_edges.empty());
00234
00235 {
00236 edge_iterator e = C->edge_begin();
00237 edge_iterator end = C->edge_end();
00238 for(; e != end; ++e)
00239 {
00240 if(e->A() == A)
00241 e->A() = C;
00242 if(e->B() == A)
00243 e->B() = C;
00244 if(e->A() == B)
00245 e->A() = C;
00246 if(e->B()== B)
00247 e->B() = C;
00248 }
00249 }
00250
00251
00252
00253
00254 for(edge_ptr_iterator e = C->edge_ptr_begin(); e != C->edge_ptr_end(); )
00255 {
00256 if( (*e)->A() == (*e)->B() )
00257 {
00258 edge_ptr_type self_loop( *e );
00259 remove(self_loop);
00260 e = C->edge_ptr_begin();
00261 }
00262 else
00263 ++e;
00264 }
00265
00266 for(edge_ptr_iterator i=C->edge_ptr_begin();i!=C->edge_ptr_end();++i)
00267 {
00268 edge_ptr_iterator j = i;
00269 ++j;
00270 for(;j!=C->edge_ptr_end();)
00271 {
00272 edge_ptr_iterator k = j;
00273 ++j;
00274 if(
00275 ((*k)->A()==(*i)->A() && (*k)->B()==(*i)->B())
00276 ||
00277 ((*k)->A()==(*i)->B() && (*k)->B()==(*i)->A())
00278 )
00279 {
00280 edge_ptr_type redundant( *k );
00281 remove(redundant);
00282 }
00283 }
00284 }
00285
00286
00287
00288
00289
00290 C->m_coverage.splice(C->m_coverage.end(),A->m_coverage);
00291 C->m_coverage.splice(C->m_coverage.end(),B->m_coverage);
00292
00293
00294 C->m_subtree_size = A->m_subtree_size + B->m_subtree_size;
00295 if(!A->size_sub_nodes())
00296 C->m_sub_nodes.push_back(A);
00297 else
00298 {
00299 C->m_sub_nodes.splice(C->m_sub_nodes.end(),A->m_sub_nodes);
00300 remove(A);
00301 }
00302 if(!B->size_sub_nodes())
00303 C->m_sub_nodes.push_back(B);
00304 else
00305 {
00306 C->m_sub_nodes.splice(C->m_sub_nodes.end(),B->m_sub_nodes);
00307 remove(B);
00308 }
00309 C->m_height = C->max_sub_node_height();
00310 m_nodes.push_back(C);
00311 return C;
00312 }
00313
00314
00315
00322 void remove_sub_nodes(node_ptr_type node)
00323 {
00324 if(!node->size_sub_nodes())
00325 return;
00326
00327 node_ptr_iterator sub_node = node->sub_node_ptr_begin();
00328 node_ptr_iterator end = node->sub_node_ptr_end();
00329 for(;sub_node!=end;++sub_node)
00330 {
00331 node_ptr_type target( *sub_node );
00332 m_nodes.remove( target );
00333 }
00334 node->m_sub_nodes.clear();
00335 }
00336
00337 protected:
00338
00345 void remove(edge_ptr_type edge)
00346 {
00347 assert(edge);
00348 assert(edge->A());
00349 assert(edge->B());
00350
00351 edge->m_A->m_edges.remove(edge);
00352 edge->m_B->m_edges.remove(edge);
00353
00354 m_edges.remove(edge);
00355
00356 edge.reset();
00357 }
00358
00365 void remove(node_ptr_type node)
00366 {
00367 assert(!node->size_sub_nodes() || !"BVHGraph::remove(node_ptr_type): Node has sub nodes!");
00368 assert(!node->size_edges() || !"BVHGraph::remove(node_ptr_type): Node got incident edges");
00369 m_nodes.remove(node);
00370
00371 node.reset();
00372 }
00373
00374 };
00375
00376 }
00377
00378 }
00379
00380
00381 #endif