Go to the documentation of this file.00001 #ifndef OPENTISSUE_COLLISION_BVH_BVH_GET_NODES_AT_CLOSEST_HEIGHT_H
00002 #define OPENTISSUE_COLLISION_BVH_BVH_GET_NODES_AT_CLOSEST_HEIGHT_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/collision/bvh/bvh_get_all_nodes.h>
00013
00014 #include <boost/shared_ptr.hpp>
00015
00016 #include <map>
00017
00018 namespace OpenTissue
00019 {
00020 namespace bvh
00021 {
00022 namespace detail
00023 {
00024
00028 template<typename bvh_type, typename bv_ptr,typename height_map>
00029 inline unsigned int compute_heights(bvh_type const & bvh, bv_ptr bv, height_map & heights )
00030 {
00031 typedef typename bvh_type::bv_ptr_iterator bv_ptr_iterator;
00032 typedef typename bvh_type::bv_type bv_type;
00033
00034 using std::max;
00035
00036 unsigned int bv_height = 0;
00037 bv_ptr_iterator child = bv->child_ptr_begin();
00038 bv_ptr_iterator end = bv->child_ptr_end();
00039 for( ;child != end; ++child)
00040 {
00041 bv_ptr ptr( *child );
00042 bv_height = max( bv_height, compute_heights(bvh, ptr, heights ) );
00043 }
00044 bv_height = bv_height + 1;
00045 heights[ bv ] = bv_height;
00046 return bv_height;
00047 }
00048
00049 }
00050
00051
00055 template<typename bvh_type, typename bv_ptr_container>
00056 inline void get_nodes_at_closest_height(bvh_type const & bvh,unsigned int const & height,bv_ptr_container & nodes)
00057 {
00058 typedef typename bvh_type::bv_ptr bv_ptr;
00059 typedef typename bvh_type::bv_type bv_type;
00060 typedef typename bvh_type::bv_ptr_container internal_bv_ptr_container;
00061 typedef typename bvh_type::bv_ptr_iterator bv_ptr_iterator;
00062 typedef typename std::map< bv_ptr, unsigned int> height_map;
00063
00064 nodes.clear();
00065 if(!bvh.root())
00066 return;
00067
00068 height_map heights;
00069
00070 bv_ptr root = boost::const_pointer_cast<bv_type>( bvh.root() );
00071
00072 detail::compute_heights( bvh, root, heights );
00073
00074 internal_bv_ptr_container all;
00075 bvh::get_all_nodes(bvh,all);
00076 bv_ptr_iterator bv = all.begin();
00077 bv_ptr_iterator end = all.end();
00078
00079 for(; bv!=end; ++bv )
00080 {
00081 bv_ptr cur( *bv );
00082 unsigned int bv_height = heights[ cur ];
00083 if ( bv_height == height )
00084 nodes.push_back( cur );
00085 else if ( (*bv)->parent() )
00086 {
00087 bv_ptr ptr = boost::const_pointer_cast<bv_type>( (*bv)->parent() );
00088 bv_ptr parent( ptr );
00089 unsigned int parent_height= heights[ parent ];
00090 if ( bv_height < height && parent_height > height )
00091 nodes.push_back( cur );
00092 }
00093 }
00094 }
00095 }
00096
00097 }
00098
00099
00100 #endif