Go to the documentation of this file.00001 #ifndef OPENTISSUE_BVH_BVH_DEFAULT_TOPDOWN_POLICY_H
00002 #define OPENTISSUE_BVH_BVH_DEFAULT_TOPDOWN_POLICY_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <boost/shared_ptr.hpp>
00013 #include <vector>
00014
00015 namespace OpenTissue
00016 {
00017 namespace bvh
00018 {
00019
00023 template<typename bvh_type>
00024 class DefaultTopDownPolicy
00025 {
00026 public:
00027
00028 typedef DefaultTopDownPolicy<bvh_type> top_down_type;
00029 typedef typename bvh_type::bv_ptr bv_ptr;
00030 typedef typename bvh_type::annotated_bv_type annotated_bv_type;
00031 typedef typename bvh_type::annotated_bv_ptr annotated_bv_ptr;
00032 typedef typename bvh_type::volume_type volume_type;
00033 typedef typename bvh_type::geometry_type geometry_type;
00034 typedef typename std::vector<geometry_type> geometry_container;
00035
00036 protected:
00037
00038 geometry_container m_geometry;
00039
00040 public:
00041
00042 class partition_type
00043 {
00044 public:
00045
00046 friend class DefaultTopDownPolicy<bvh_type>;
00047
00048 public:
00049
00050 typedef std::vector<partition_type> partition_container;
00051 typedef typename partition_container::iterator partition_iterator;
00052
00053 protected:
00054
00055 partition_container m_sub_partitions;
00056 unsigned int m_left;
00057 unsigned int m_right;
00058 top_down_type * m_owner;
00059
00060 public:
00061
00062 partition_type()
00063 : m_left(0)
00064 , m_right(0)
00065 , m_owner(0)
00066 {}
00067
00068 partition_type(top_down_type * owner,unsigned int left,unsigned int right)
00069 : m_left(left)
00070 , m_right(right)
00071 , m_owner(owner)
00072 {}
00073
00074 bool annotated() const { return size()==1; }
00075 unsigned int size() const { return (m_right-m_left+1); }
00076 bool empty() { return (size()==0); }
00077 void split() { m_owner->split((*this)); }
00078 partition_iterator sub_partition_begin() { return m_sub_partitions.begin(); }
00079 partition_iterator sub_partition_end() { return m_sub_partitions.end(); }
00080 void fit(bv_ptr bv){ m_owner->fit(bv,(*this)); }
00081
00082 };
00083
00084 public:
00085
00086 typedef typename partition_type::partition_container partition_container;
00087 typedef typename partition_type::partition_iterator partition_iterator;
00088
00089 public:
00090
00091 partition_type all() { return partition_type(this,0,m_geometry.size()-1); }
00092
00093 template<typename iterator>
00094 void init(iterator begin,iterator end)
00095 {
00096
00097
00098
00099
00100
00101 m_geometry.clear();
00102 std::copy( begin, end, std::back_inserter( m_geometry ) );
00103 }
00104
00105 protected:
00106
00107 unsigned int degree() const {return 3;}
00108
00109 void split(partition_type & partition)
00110 {
00111 using std::min;
00112
00113 unsigned int total_size = partition.size();
00114 unsigned int cnt = min(total_size,degree());
00115 unsigned int subset_size = total_size/cnt;
00116 partition.m_sub_partitions.resize(cnt);
00117 for(unsigned int i=0;i<cnt;++i)
00118 {
00119 unsigned int left = i*subset_size;
00120 unsigned int right = (i==cnt-1)?total_size - 1:(i+1)*subset_size - 1;
00121 left += + partition.m_left;
00122 right += + partition.m_left;
00123 partition.m_sub_partitions[i] = partition_type(this,left,right);
00124 assert(!partition.m_sub_partitions[i].empty());
00125 }
00126 }
00127
00128
00129 void fit(bv_ptr bv,partition_type & partition)
00130 {
00131 if(partition.annotated())
00132 {
00133 annotated_bv_ptr A = boost::static_pointer_cast<annotated_bv_type>(bv);
00134 A->insert( m_geometry[partition.m_left] );
00135 }
00136 }
00137
00138 };
00139
00140 }
00141 }
00142
00143
00144 #endif