Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #ifndef MOAB_MB_ITER_HPP 00002 #define MOAB_MB_ITER_HPP 00003 00004 #define IS_BUILDING_MB 00005 #include "Internals.hpp" 00006 #include "moab/Range.hpp" 00007 #include "moab/Core.hpp" 00008 #include <vector> 00009 #include <algorithm> 00010 00011 struct iBase_EntityArrIterator_Private 00012 { 00013 protected: 00014 iBase_EntityType entType; 00015 iMesh_EntityTopology entTopo; 00016 EntityHandle entSet; 00017 int arrSize; 00018 bool isRecursive; 00019 00020 public: 00021 iBase_EntityArrIterator_Private( iBase_EntityType type, 00022 iMesh_EntityTopology topology, 00023 EntityHandle set, 00024 int array_sz, 00025 bool recursive = false ) 00026 : entType( type ), entTopo( topology ), entSet( set ), arrSize( array_sz ), isRecursive( recursive ) 00027 { 00028 } 00029 00030 virtual ~iBase_EntityArrIterator_Private() {} 00031 00032 int array_size() const 00033 { 00034 return arrSize; 00035 } 00036 00037 virtual ErrorCode step( int num_steps, bool& at_end ) = 0; 00038 00039 // NOTE: input array must be at least arrLen long 00040 virtual void get_entities( Core* mb, EntityHandle* array, int& count_out ) = 0; 00041 00042 virtual ErrorCode reset( Interface* mb ) = 0; 00043 00044 class IsType 00045 { 00046 private: 00047 EntityType type; 00048 00049 public: 00050 IsType( EntityType t ) : type( t ) {} 00051 bool operator()( EntityHandle h ) 00052 { 00053 return TYPE_FROM_HANDLE( h ) == type; 00054 } 00055 }; 00056 00057 void remove_type( std::vector< EntityHandle >& vect, EntityType t ) 00058 { 00059 vect.erase( std::remove_if( vect.begin(), vect.end(), IsType( t ) ), vect.end() ); 00060 } 00061 00062 void remove_type( Range& range, EntityType t ) 00063 { 00064 std::pair< Range::iterator, Range::iterator > p = range.equal_range( t ); 00065 range.erase( p.first, p.second ); 00066 } 00067 }; 00068 00069 // step_iterator will safely step forward N steps in a iterator. We specialize 00070 // for random-access iterators (vectors and Ranges) so that they perform better. 00071 00072 template < typename T > 00073 inline ErrorCode step_iterator( T& curr, const T& end, int num_steps, bool& at_end ) 00074 { 00075 if( 0 > num_steps ) return MB_FAILURE; 00076 00077 while( num_steps && curr != end ) 00078 { 00079 num_steps--; 00080 curr++; 00081 } 00082 at_end = ( curr == end ); 00083 return MB_SUCCESS; 00084 } 00085 00086 template < typename T > 00087 inline ErrorCode step_iterator( typename std::vector< T >::const_iterator& curr, 00088 const typename std::vector< T >::const_iterator& end, 00089 int num_steps, 00090 bool& at_end ) 00091 { 00092 if( 0 > num_steps ) return MB_FAILURE; 00093 00094 assert( curr <= end ); // Sanity check 00095 at_end = ( end - curr <= num_steps ); 00096 00097 if( at_end ) 00098 curr = end; 00099 else 00100 curr += num_steps; 00101 return MB_SUCCESS; 00102 } 00103 00104 inline ErrorCode step_iterator( Range::const_iterator& curr, 00105 const Range::const_iterator& end, 00106 int num_steps, 00107 bool& at_end ) 00108 { 00109 if( 0 > num_steps ) return MB_FAILURE; 00110 00111 at_end = ( end - curr <= num_steps ); 00112 00113 if( at_end ) 00114 curr = end; 00115 else 00116 curr += num_steps; 00117 return MB_SUCCESS; 00118 } 00119 00120 template < class Container > 00121 class MBIter : public iBase_EntityArrIterator_Private 00122 { 00123 protected: 00124 Container iterData; 00125 typename Container::const_iterator iterPos; 00126 00127 public: 00128 MBIter( iBase_EntityType type, 00129 iMesh_EntityTopology topology, 00130 EntityHandle set, 00131 int arr_size, 00132 bool recursive = false ) 00133 : iBase_EntityArrIterator_Private( type, topology, set, arr_size, recursive ), iterPos( iterData.end() ) 00134 { 00135 } 00136 00137 ~MBIter() {} 00138 00139 typename Container::const_iterator position() const 00140 { 00141 return iterPos; 00142 }; 00143 00144 typename Container::const_iterator end() const 00145 { 00146 return iterData.end(); 00147 }; 00148 00149 ErrorCode step( int num_steps, bool& at_end ) 00150 { 00151 return step_iterator( iterPos, end(), num_steps, at_end ); 00152 } 00153 00154 void get_entities( Core* mb, EntityHandle* array, int& count ) 00155 { 00156 for( count = 0; count < arrSize && iterPos != iterData.end(); ++iterPos ) 00157 if( mb->is_valid( *iterPos ) ) array[count++] = *iterPos; 00158 } 00159 00160 virtual ErrorCode reset( Interface* mb ) 00161 { 00162 ErrorCode result; 00163 iterData.clear(); 00164 if( entTopo != iMesh_ALL_TOPOLOGIES ) 00165 { 00166 if( entTopo == iMesh_SEPTAHEDRON ) 00167 result = MB_SUCCESS; 00168 else 00169 result = mb->get_entities_by_type( entSet, mb_topology_table[entTopo], iterData, isRecursive ); 00170 } 00171 else if( entType != iBase_ALL_TYPES ) 00172 { 00173 result = mb->get_entities_by_dimension( entSet, entType, iterData, isRecursive ); 00174 if( entType == iBase_REGION ) remove_type( iterData, MBKNIFE ); 00175 } 00176 else 00177 { 00178 result = mb->get_entities_by_handle( entSet, iterData, isRecursive ); 00179 remove_type( iterData, MBENTITYSET ); 00180 remove_type( iterData, MBKNIFE ); 00181 } 00182 iterPos = iterData.begin(); 00183 return result; 00184 } 00185 }; 00186 00187 typedef MBIter< std::vector< EntityHandle > > MBListIter; 00188 typedef MBIter< moab::Range > MBRangeIter; 00189 00190 #endif