moab
|
00001 00007 #include <vector> 00008 #include <set> 00009 #include <iostream> 00010 #include <map> 00011 #include <algorithm> 00012 #include <bitset> 00013 #include <numeric> 00014 #include <cmath> 00015 #include <tr1/unordered_map> 00016 #include <limits> 00017 00018 #ifndef COMMON_TREE_HPP 00019 #define COMMON_TREE_HPP 00020 #define NUM_DIM 3 00021 #define TREE_DEBUG 00022 namespace moab { 00023 namespace common_tree { 00024 00025 template< typename T, typename Stream> 00026 void print_vector( const T & v, Stream & out){ 00027 typedef typename T::const_iterator Iterator; 00028 out << "[ "; 00029 for(Iterator i = v.begin(); i != v.end(); ++i){ 00030 out << *i; 00031 if( i+1 != v.end()){ 00032 out << ", "; 00033 } 00034 } 00035 out << " ]" << std::endl; 00036 } 00037 00038 #ifdef TREE_DEBUG 00039 template< typename T> 00040 void print_vector( const T & begin, const T & end){ 00041 std::cout << "[ "; 00042 for(T i = begin; i != end; ++i){ 00043 std::cout << (*i)->second.second.to_ulong(); 00044 if( i+1 != end){ 00045 std::cout << ", "; 00046 } 00047 } 00048 std::cout << " ]" << std::endl; 00049 } 00050 #endif 00051 00052 template< typename _Box, typename _Point> 00053 bool box_contains_point( const _Box & box, const _Point & p, 00054 const double tol){ 00055 for( std::size_t i = 0; i < box.min.size(); ++i){ 00056 if( p[ i] < (box.min[ i]-tol) || 00057 p[ i] > (box.max[ i])+tol){ 00058 return false; 00059 } 00060 } 00061 return true; 00062 } 00063 00064 template< typename _Box> 00065 bool box_contains_box( const _Box & a, const _Box & b, const double tol){ 00066 for( std::size_t i = 0; i < a.min.size(); ++i){ 00067 if( b.min[ i] < (a.min[ i]-tol)){ 00068 return false; 00069 } 00070 if( b.max[ i] > (a.max[ i]+tol)){ 00071 return false; 00072 } 00073 } 00074 return true; 00075 } 00076 00077 namespace { 00078 template< typename T> 00079 struct Compute_center: public std::binary_function< T, T, T> { 00080 T operator()( const T a, const T b) const{ 00081 return (a+b)/2.0; 00082 } 00083 }; //Compute_center 00084 } //non-exported center computation. 00085 00086 template< typename Vector> 00087 inline void compute_box_center(Vector & max, Vector & min, Vector & center){ 00088 typedef typename Vector::value_type Unit; 00089 center = min; 00090 std::transform( max.begin(), max.end(), center.begin(), 00091 center.begin(), Compute_center< Unit>() ); 00092 } 00093 00094 00095 template< typename Box> 00096 inline typename Box::value_type compute_box_center( const Box & box, 00097 const int dim){ 00098 return (box.max[ dim] + box.min[ dim])/2.0; 00099 } 00100 00101 00102 template< typename T = float> 00103 class Box{ 00104 public: 00105 typedef T value_type; 00106 typedef std::vector< T> Vector; 00107 Box(): max(3,0.0), min(3,0.0) {} 00108 Box( const Box & from): max( from.max), 00109 min( from.min){} 00110 template< typename Iterator> 00111 Box( const Iterator begin, const Iterator end): 00112 max( begin, end), min(begin, end){} 00113 Box& operator=( const Box & from){ 00114 max = from.max; 00115 min = from.min; 00116 return *this; 00117 } 00118 Vector max; 00119 Vector min; 00120 }; //Box 00121 00122 template< typename T> 00123 std::ostream& operator<<( std::ostream& out, const Box<T> & box){ 00124 out << "Max: "; 00125 print_vector( box.max, out); 00126 out << "Min: "; 00127 print_vector( box.min, out); 00128 return out; 00129 } 00130 00131 //essentially a pair, but with an added constructor. 00132 template< typename T1, typename T2> 00133 struct _Element_data { 00134 typedef T1 first_type; 00135 typedef T2 second_type; 00136 T1 first; 00137 T2 second; 00138 _Element_data(): first(T1()), second(T2()){} 00139 _Element_data( const T1 & x): first(x), second(T2()) {} 00140 _Element_data( const T1 & x, T2 & y): first( x), second( y) {} 00141 template< typename U, typename V> 00142 _Element_data( const _Element_data<U,V> &p ): first(p.first), 00143 second( p.second) {} 00144 }; //Element_data 00145 00146 template< typename Entities, typename Iterator> 00147 void assign_entities( Entities & entities, 00148 const Iterator & begin, const Iterator & end){ 00149 entities.reserve( std::distance( begin, end)); 00150 for( Iterator i = begin; i != end; ++i){ 00151 entities.push_back( std::make_pair((*i)->second.first, 00152 (*i)->first)); 00153 } 00154 } 00155 00156 template<typename Coordinate, typename Coordinate_iterator> 00157 void update_bounding_max( Coordinate & max, Coordinate_iterator j){ 00158 typedef typename Coordinate::iterator Iterator; 00159 for( Iterator i = max.begin(); i != max.end(); ++i, ++j){ 00160 *i = std::max( *i, *j); 00161 } 00162 } 00163 00164 template<typename Coordinate, typename Coordinate_iterator> 00165 void update_bounding_min( Coordinate & min, Coordinate_iterator j){ 00166 typedef typename Coordinate::iterator Iterator; 00167 for( Iterator i = min.begin(); i != min.end(); ++i, ++j){ 00168 *i = std::min( *i, *j); 00169 } 00170 } 00171 00172 template< typename Box> 00173 void update_bounding_box( Box & a, const Box & b){ 00174 update_bounding_max( a.max, b.max.begin()); 00175 update_bounding_min( a.min, b.min.begin()); 00176 #ifdef COMMON_TREE_DEBUG 00177 if( !box_contains_box( a, b)){ 00178 std::cout << a << b << std::endl; 00179 } 00180 #endif 00181 } 00182 00183 00184 template< typename Entity_map, typename Ordering> 00185 void construct_ordering( Entity_map & entity_map, Ordering & entity_ordering){ 00186 entity_ordering.reserve( entity_map.size()); 00187 typedef typename Entity_map::iterator Map_iterator; 00188 for(Map_iterator i = entity_map.begin(); 00189 i != entity_map.end(); 00190 ++i){ 00191 entity_ordering.push_back( i); 00192 } 00193 } 00194 00195 //Input: A bunch of entity handles 00196 //Output: A map from handle -> Data 00197 //Requirements: Data contains at least a bounding box. 00198 //And a non-default constructor which takes only a Box& 00199 template< typename Entity_handles, 00200 typename Element_map, 00201 typename Bounding_box, 00202 typename Moab> 00203 void construct_element_map( const Entity_handles & elements, 00204 Element_map & map, 00205 Bounding_box & bounding_box, 00206 Moab & moab){ 00207 typedef typename Element_map::mapped_type Box_data; 00208 typedef typename Entity_handles::value_type Entity_handle; 00209 typedef typename Entity_handles::iterator Entity_handles_iterator; 00210 typedef typename Box_data::first_type::value_type Unit; 00211 typedef typename std::vector< Unit> Coordinates; 00212 typedef typename Coordinates::iterator Coordinate_iterator; 00213 00214 for( Entity_handles_iterator i = elements.begin(); 00215 i != elements.end(); ++i){ 00216 //TODO: not generic enough. Why dim != 3 00217 const int DIM = 3; 00218 int num_vertices=0; 00219 //Commence un-necessary deep copying. 00220 const Entity_handle* vertex_handle; 00221 moab.get_connectivity( *i, vertex_handle, num_vertices); 00222 Coordinates coordinate(DIM*num_vertices, 0.0); 00223 moab.get_coords( vertex_handle, num_vertices, &coordinate[ 0]); 00224 Bounding_box box( coordinate.begin(), coordinate.begin()+3); 00225 if( i == elements.begin() ){ bounding_box = box;} 00226 for( Coordinate_iterator j = coordinate.begin()+DIM; 00227 j != coordinate.end(); j+=DIM){ 00228 update_bounding_max( box.max, j); 00229 update_bounding_min( box.min, j); 00230 } 00231 update_bounding_box( bounding_box, box); 00232 map.insert( std::make_pair( *i, Box_data( box))); 00233 } 00234 } 00235 00236 } //namspace common_tree 00237 00238 } // namespace moab 00239 00240 #endif //COMMON_TREE_HPP