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