moab
common_tree.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines