MOAB: Mesh Oriented datABase  (version 5.4.1)
SetIterator.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines