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