MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 #ifndef IS_BUILDING_MB 00002 #error "SetIterator.hpp isn't supposed to be included into an application" 00003 #endif 00004 00005 #include "moab/SetIterator.hpp" 00006 #include "moab/Core.hpp" 00007 #include "moab/WriteUtilIface.hpp" 00008 #include "MeshSet.hpp" 00009 #include "Internals.hpp" 00010 #include "moab/CN.hpp" 00011 #include "moab/Error.hpp" 00012 00013 namespace moab 00014 { 00015 00016 SetIterator::~SetIterator() 00017 { 00018 myCore->remove_set_iterator( this ); 00019 } 00020 00021 RangeSetIterator::RangeSetIterator( Core* core, EntityHandle eset, int chunk_sz, EntityType ent_tp, int ent_dim, 00022 bool check_valid ) 00023 : SetIterator( core, eset, chunk_sz, ent_tp, ent_dim, check_valid ), iterPos( 0 ), pairPtr( NULL ), numPairs( 0 ) 00024 { 00025 if( !eset ) 00026 { 00027 // special case for the root set, have to keep a local array 00028 ErrorCode rval = build_pair_vec(); 00029 assert( MB_SUCCESS == rval ); 00030 00031 // empty statement to avoid warning 00032 (void)( rval ); 00033 } 00034 } 00035 00036 RangeSetIterator::~RangeSetIterator() 00037 { 00038 if( pairPtr ) delete[] pairPtr; 00039 numPairs = 0; 00040 } 00041 00042 ErrorCode RangeSetIterator::build_pair_vec() 00043 { 00044 // shouldn't be here unless we're iterating the root set 00045 assert( !entSet ); 00046 00047 Range all_ents; 00048 ErrorCode rval = myCore->get_entities_by_handle( 0, all_ents ); 00049 if( MB_SUCCESS != rval ) return rval; 00050 00051 if( pairPtr ) delete[] pairPtr; 00052 pairPtr = new EntityHandle[2 * all_ents.psize()]; 00053 Range::const_pair_iterator pi; 00054 int i; 00055 for( pi = all_ents.const_pair_begin(), i = 0; pi != all_ents.const_pair_end(); ++pi, i += 2 ) 00056 { 00057 pairPtr[i] = ( *pi ).first; 00058 pairPtr[i + 1] = ( *pi ).second; 00059 } 00060 numPairs = all_ents.psize(); 00061 00062 return MB_SUCCESS; 00063 } 00064 00065 ErrorCode RangeSetIterator::get_next_arr( std::vector< EntityHandle >& arr, bool& atend ) 00066 { 00067 atend = false; 00068 00069 int count; 00070 const EntityHandle* ptr; 00071 WriteUtilIface* iface; 00072 std::vector< EntityHandle > tmp_arr; 00073 std::vector< EntityHandle >* tmp_ptr = &arr; 00074 if( checkValid ) tmp_ptr = &tmp_arr; 00075 ErrorCode rval; 00076 if( !pairPtr ) 00077 { 00078 Interface* mbImpl = dynamic_cast< Interface* >( myCore ); 00079 rval = mbImpl->query_interface( iface ); 00080 if( MB_SUCCESS != rval ) return rval; 00081 00082 rval = iface->get_entity_list_pointers( &entSet, 1, &ptr, WriteUtilIface::CONTENTS, &count ); 00083 if( MB_SUCCESS != rval ) return rval; 00084 mbImpl->release_interface( iface ); 00085 } 00086 else 00087 { 00088 if( checkValid ) 00089 { 00090 rval = build_pair_vec(); 00091 if( MB_SUCCESS != rval ) return rval; 00092 } 00093 ptr = pairPtr; 00094 count = 2 * numPairs; 00095 } 00096 assert( !( count % 2 ) ); 00097 if( !count ) 00098 { 00099 atend = true; 00100 return MB_SUCCESS; 00101 } 00102 00103 if( -1 == entDimension ) 00104 rval = get_next_by_type( ptr, count, *tmp_ptr, atend ); 00105 else 00106 rval = get_next_by_dimension( ptr, count, *tmp_ptr, atend ); 00107 if( MB_SUCCESS != rval ) return rval; 00108 00109 if( checkValid ) 00110 { 00111 for( std::vector< EntityHandle >::iterator vit = tmp_ptr->begin(); vit != tmp_ptr->end(); ++vit ) 00112 { 00113 if( myCore->is_valid( *vit ) ) arr.push_back( *vit ); 00114 } 00115 } 00116 00117 return MB_SUCCESS; 00118 } 00119 00120 ErrorCode RangeSetIterator::get_next_by_type( const EntityHandle*& ptr, int count, std::vector< EntityHandle >& arr, 00121 bool& atend ) 00122 { 00123 unsigned int num_ret = 0; 00124 bool max_type = ( entType == MBMAXTYPE ); 00125 size_t idx = 0; 00126 // initialize to first relevant handle 00127 while( (int)idx < count && 00128 ( iterPos > ptr[idx + 1] || 00129 ( !max_type && !iterPos && CREATE_HANDLE( entType, ID_FROM_HANDLE( iterPos ) ) > ptr[idx + 1] ) ) ) 00130 idx += 2; 00131 if( (int)idx == count || TYPE_FROM_HANDLE( ptr[idx] ) > entType ) 00132 { 00133 atend = true; 00134 return MB_SUCCESS; 00135 } 00136 if( !iterPos && max_type ) 00137 iterPos = ptr[idx]; 00138 else if( !iterPos && TYPE_FROM_HANDLE( ptr[idx] ) <= entType && TYPE_FROM_HANDLE( ptr[idx + 1] ) >= entType ) 00139 { 00140 iterPos = std::max( CREATE_HANDLE( entType, 1 ), ptr[idx] ); 00141 } 00142 00143 // idx points to start of subrange, iterPos in that subrange 00144 do 00145 { 00146 EntityHandle next = ptr[idx + 1]; 00147 if( TYPE_FROM_HANDLE( next ) != entType && !max_type ) next = LAST_HANDLE( entType ); 00148 unsigned int this_ret = chunkSize - num_ret; 00149 unsigned int to_end = next - iterPos + 1; 00150 if( to_end < this_ret ) this_ret = to_end; 00151 std::copy( MeshSet::hdl_iter( iterPos ), MeshSet::hdl_iter( iterPos + this_ret ), std::back_inserter( arr ) ); 00152 if( this_ret == to_end ) 00153 { 00154 idx += 2; 00155 iterPos = ( (int)idx < count ? ptr[idx] : 0 ); 00156 } 00157 else 00158 iterPos += this_ret; 00159 00160 num_ret += this_ret; 00161 } while( (int)idx < count && num_ret < chunkSize && iterPos && 00162 ( max_type || TYPE_FROM_HANDLE( iterPos ) == entType ) ); 00163 00164 if( !iterPos || ( !max_type && TYPE_FROM_HANDLE( iterPos ) != entType ) ) atend = true; 00165 00166 return MB_SUCCESS; 00167 } 00168 00169 ErrorCode RangeSetIterator::get_next_by_dimension( const EntityHandle*& ptr, int count, 00170 std::vector< EntityHandle >& arr, bool& atend ) 00171 { 00172 // iterating by dimension - type should be maxtype 00173 if( entType != MBMAXTYPE ) { MB_SET_ERR( MB_FAILURE, "Both dimension and type should not be set on an iterator" ); } 00174 00175 unsigned int num_ret = 0; 00176 size_t idx = 0; 00177 // initialize to first relevant handle 00178 while( (int)idx < count && ( iterPos > ptr[idx + 1] || 00179 ( !iterPos && entDimension > CN::Dimension( TYPE_FROM_HANDLE( ptr[idx + 1] ) ) ) ) ) 00180 idx += 2; 00181 if( (int)idx == count || CN::Dimension( TYPE_FROM_HANDLE( ptr[idx] ) ) > entDimension ) 00182 { 00183 atend = true; 00184 return MB_SUCCESS; 00185 } 00186 if( !iterPos ) 00187 iterPos = ptr[idx]; 00188 else if( CN::Dimension( TYPE_FROM_HANDLE( ptr[idx] ) ) < entDimension ) 00189 iterPos = CREATE_HANDLE( CN::TypeDimensionMap[entDimension].first, 1 ); 00190 00191 // idx points to start of subrange, iterPos in that subrange 00192 do 00193 { 00194 EntityHandle next = ptr[idx + 1]; 00195 if( CN::Dimension( TYPE_FROM_HANDLE( next ) ) != entDimension ) 00196 next = LAST_HANDLE( CN::TypeDimensionMap[entDimension].second ); 00197 unsigned int this_ret = chunkSize - num_ret; 00198 unsigned int to_end = next - iterPos + 1; 00199 if( to_end < this_ret ) this_ret = to_end; 00200 std::copy( MeshSet::hdl_iter( iterPos ), MeshSet::hdl_iter( iterPos + this_ret ), std::back_inserter( arr ) ); 00201 if( this_ret == to_end ) 00202 { 00203 idx += 2; 00204 iterPos = ( (int)idx < count ? ptr[idx] : 0 ); 00205 } 00206 else 00207 iterPos += this_ret; 00208 00209 num_ret += this_ret; 00210 } while( (int)idx < count && num_ret < chunkSize && iterPos && 00211 CN::Dimension( TYPE_FROM_HANDLE( iterPos ) ) == entDimension ); 00212 00213 if( !iterPos || CN::Dimension( TYPE_FROM_HANDLE( iterPos ) ) != entDimension ) atend = true; 00214 00215 return MB_SUCCESS; 00216 } 00217 00218 ErrorCode RangeSetIterator::reset() 00219 { 00220 iterPos = 0; 00221 return MB_SUCCESS; 00222 } 00223 00224 ErrorCode VectorSetIterator::get_next_arr( std::vector< EntityHandle >& arr, bool& atend ) 00225 { 00226 int count; 00227 const EntityHandle* ptr; 00228 WriteUtilIface* iface; 00229 Interface* mbImpl = dynamic_cast< Interface* >( myCore ); 00230 ErrorCode rval = mbImpl->query_interface( iface ); 00231 if( MB_SUCCESS != rval ) return rval; 00232 00233 rval = iface->get_entity_list_pointers( &entSet, 1, &ptr, WriteUtilIface::CONTENTS, &count ); 00234 if( MB_SUCCESS != rval ) return rval; 00235 mbImpl->release_interface( iface ); 00236 00237 if( !count || iterPos >= count ) 00238 { 00239 atend = true; 00240 return MB_SUCCESS; 00241 } 00242 00243 std::vector< EntityHandle > tmp_arr; 00244 std::vector< EntityHandle >* tmp_ptr = &arr; 00245 if( checkValid ) tmp_ptr = &tmp_arr; 00246 00247 // just get the next chunkSize entities, or as many as you can 00248 int this_ct = 0; 00249 while( this_ct < (int)chunkSize && iterPos < count ) 00250 { 00251 if( ( MBMAXTYPE == entType || TYPE_FROM_HANDLE( ptr[iterPos] ) == entType ) && 00252 ( -1 == entDimension || CN::Dimension( TYPE_FROM_HANDLE( ptr[iterPos] ) ) == entDimension ) ) 00253 { 00254 arr.push_back( ptr[iterPos] ); 00255 this_ct++; 00256 } 00257 iterPos++; 00258 } 00259 00260 atend = ( iterPos == count ); 00261 00262 if( checkValid ) 00263 { 00264 for( std::vector< EntityHandle >::iterator vit = tmp_ptr->begin(); vit != tmp_ptr->end(); ++vit ) 00265 { 00266 if( myCore->is_valid( *vit ) ) arr.push_back( *vit ); 00267 } 00268 } 00269 00270 // step along list, adding entities 00271 return MB_SUCCESS; 00272 } 00273 00274 ErrorCode VectorSetIterator::reset() 00275 { 00276 iterPos = 0; 00277 return MB_SUCCESS; 00278 } 00279 00280 } // namespace moab