MOAB: Mesh Oriented datABase  (version 5.3.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, 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines