![]() |
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
00009 #include
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