Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SetIterator.cpp
Go to the documentation of this file.
1 #ifndef IS_BUILDING_MB 2 #error "SetIterator.hpp isn't supposed to be included into an application" 3 #endif 4  5 #include "moab/SetIterator.hpp" 6 #include "moab/Core.hpp" 7 #include "moab/WriteUtilIface.hpp" 8 #include "MeshSet.hpp" 9 #include "Internals.hpp" 10 #include "moab/CN.hpp" 11 #include "moab/Error.hpp" 12  13 namespace moab 14 { 15  16 SetIterator::~SetIterator() 17 { 18  myCore->remove_set_iterator( this ); 19 } 20  21 RangeSetIterator::RangeSetIterator( Core* core, 22  EntityHandle eset, 23  int chunk_sz, 24  EntityType ent_tp, 25  int ent_dim, 26  bool check_valid ) 27  : SetIterator( core, eset, chunk_sz, ent_tp, ent_dim, check_valid ), iterPos( 0 ), pairPtr( NULL ), numPairs( 0 ) 28 { 29  if( !eset ) 30  { 31  // special case for the root set, have to keep a local array 32  ErrorCode rval = build_pair_vec(); 33  assert( MB_SUCCESS == rval ); 34  35  // empty statement to avoid warning 36  (void)( rval ); 37  } 38 } 39  40 RangeSetIterator::~RangeSetIterator() 41 { 42  if( pairPtr ) delete[] pairPtr; 43  numPairs = 0; 44 } 45  46 ErrorCode RangeSetIterator::build_pair_vec() 47 { 48  // shouldn't be here unless we're iterating the root set 49  assert( !entSet ); 50  51  Range all_ents; 52  ErrorCode rval = myCore->get_entities_by_handle( 0, all_ents ); 53  if( MB_SUCCESS != rval ) return rval; 54  55  if( pairPtr ) delete[] pairPtr; 56  pairPtr = new EntityHandle[2 * all_ents.psize()]; 57  Range::const_pair_iterator pi; 58  int i; 59  for( pi = all_ents.const_pair_begin(), i = 0; pi != all_ents.const_pair_end(); ++pi, i += 2 ) 60  { 61  pairPtr[i] = ( *pi ).first; 62  pairPtr[i + 1] = ( *pi ).second; 63  } 64  numPairs = all_ents.psize(); 65  66  return MB_SUCCESS; 67 } 68  69 ErrorCode RangeSetIterator::get_next_arr( std::vector< EntityHandle >& arr, bool& atend ) 70 { 71  atend = false; 72  73  int count; 74  const EntityHandle* ptr; 75  WriteUtilIface* iface; 76  std::vector< EntityHandle > tmp_arr; 77  std::vector< EntityHandle >* tmp_ptr = &arr; 78  if( checkValid ) tmp_ptr = &tmp_arr; 79  ErrorCode rval; 80  if( !pairPtr ) 81  { 82  Interface* mbImpl = dynamic_cast< Interface* >( myCore ); 83  rval = mbImpl->query_interface( iface ); 84  if( MB_SUCCESS != rval ) return rval; 85  86  rval = iface->get_entity_list_pointers( &entSet, 1, &ptr, WriteUtilIface::CONTENTS, &count ); 87  if( MB_SUCCESS != rval ) return rval; 88  mbImpl->release_interface( iface ); 89  } 90  else 91  { 92  if( checkValid ) 93  { 94  rval = build_pair_vec(); 95  if( MB_SUCCESS != rval ) return rval; 96  } 97  ptr = pairPtr; 98  count = 2 * numPairs; 99  } 100  assert( !( count % 2 ) ); 101  if( !count ) 102  { 103  atend = true; 104  return MB_SUCCESS; 105  } 106  107  if( -1 == entDimension ) 108  rval = get_next_by_type( ptr, count, *tmp_ptr, atend ); 109  else 110  rval = get_next_by_dimension( ptr, count, *tmp_ptr, atend ); 111  if( MB_SUCCESS != rval ) return rval; 112  113  if( checkValid ) 114  { 115  for( std::vector< EntityHandle >::iterator vit = tmp_ptr->begin(); vit != tmp_ptr->end(); ++vit ) 116  { 117  if( myCore->is_valid( *vit ) ) arr.push_back( *vit ); 118  } 119  } 120  121  return MB_SUCCESS; 122 } 123  124 ErrorCode RangeSetIterator::get_next_by_type( const EntityHandle*& ptr, 125  int count, 126  std::vector< EntityHandle >& arr, 127  bool& atend ) 128 { 129  unsigned int num_ret = 0; 130  bool max_type = ( entType == MBMAXTYPE ); 131  size_t idx = 0; 132  // initialize to first relevant handle 133  while( (int)idx < count && 134  ( iterPos > ptr[idx + 1] || 135  ( !max_type && !iterPos && CREATE_HANDLE( entType, ID_FROM_HANDLE( iterPos ) ) > ptr[idx + 1] ) ) ) 136  idx += 2; 137  if( (int)idx == count || TYPE_FROM_HANDLE( ptr[idx] ) > entType ) 138  { 139  atend = true; 140  return MB_SUCCESS; 141  } 142  if( !iterPos && max_type ) 143  iterPos = ptr[idx]; 144  else if( !iterPos && TYPE_FROM_HANDLE( ptr[idx] ) <= entType && TYPE_FROM_HANDLE( ptr[idx + 1] ) >= entType ) 145  { 146  iterPos = std::max( CREATE_HANDLE( entType, 1 ), ptr[idx] ); 147  } 148  149  // idx points to start of subrange, iterPos in that subrange 150  do 151  { 152  EntityHandle next = ptr[idx + 1]; 153  if( TYPE_FROM_HANDLE( next ) != entType && !max_type ) next = LAST_HANDLE( entType ); 154  unsigned int this_ret = chunkSize - num_ret; 155  unsigned int to_end = next - iterPos + 1; 156  if( to_end < this_ret ) this_ret = to_end; 157  std::copy( MeshSet::hdl_iter( iterPos ), MeshSet::hdl_iter( iterPos + this_ret ), std::back_inserter( arr ) ); 158  if( this_ret == to_end ) 159  { 160  idx += 2; 161  iterPos = ( (int)idx < count ? ptr[idx] : 0 ); 162  } 163  else 164  iterPos += this_ret; 165  166  num_ret += this_ret; 167  } while( (int)idx < count && num_ret < chunkSize && iterPos && 168  ( max_type || TYPE_FROM_HANDLE( iterPos ) == entType ) ); 169  170  if( !iterPos || ( !max_type && TYPE_FROM_HANDLE( iterPos ) != entType ) ) atend = true; 171  172  return MB_SUCCESS; 173 } 174  175 ErrorCode RangeSetIterator::get_next_by_dimension( const EntityHandle*& ptr, 176  int count, 177  std::vector< EntityHandle >& arr, 178  bool& atend ) 179 { 180  // iterating by dimension - type should be maxtype 181  if( entType != MBMAXTYPE ) 182  { 183  MB_SET_ERR( MB_FAILURE, "Both dimension and type should not be set on an iterator" ); 184  } 185  186  unsigned int num_ret = 0; 187  size_t idx = 0; 188  // initialize to first relevant handle 189  while( (int)idx < count && ( iterPos > ptr[idx + 1] || 190  ( !iterPos && entDimension > CN::Dimension( TYPE_FROM_HANDLE( ptr[idx + 1] ) ) ) ) ) 191  idx += 2; 192  if( (int)idx == count || CN::Dimension( TYPE_FROM_HANDLE( ptr[idx] ) ) > entDimension ) 193  { 194  atend = true; 195  return MB_SUCCESS; 196  } 197  if( !iterPos ) 198  iterPos = ptr[idx]; 199  else if( CN::Dimension( TYPE_FROM_HANDLE( ptr[idx] ) ) < entDimension ) 200  iterPos = CREATE_HANDLE( CN::TypeDimensionMap[entDimension].first, 1 ); 201  202  // idx points to start of subrange, iterPos in that subrange 203  do 204  { 205  EntityHandle next = ptr[idx + 1]; 206  if( CN::Dimension( TYPE_FROM_HANDLE( next ) ) != entDimension ) 207  next = LAST_HANDLE( CN::TypeDimensionMap[entDimension].second ); 208  unsigned int this_ret = chunkSize - num_ret; 209  unsigned int to_end = next - iterPos + 1; 210  if( to_end < this_ret ) this_ret = to_end; 211  std::copy( MeshSet::hdl_iter( iterPos ), MeshSet::hdl_iter( iterPos + this_ret ), std::back_inserter( arr ) ); 212  if( this_ret == to_end ) 213  { 214  idx += 2; 215  iterPos = ( (int)idx < count ? ptr[idx] : 0 ); 216  } 217  else 218  iterPos += this_ret; 219  220  num_ret += this_ret; 221  } while( (int)idx < count && num_ret < chunkSize && iterPos && 222  CN::Dimension( TYPE_FROM_HANDLE( iterPos ) ) == entDimension ); 223  224  if( !iterPos || CN::Dimension( TYPE_FROM_HANDLE( iterPos ) ) != entDimension ) atend = true; 225  226  return MB_SUCCESS; 227 } 228  229 ErrorCode RangeSetIterator::reset() 230 { 231  iterPos = 0; 232  return MB_SUCCESS; 233 } 234  235 ErrorCode VectorSetIterator::get_next_arr( std::vector< EntityHandle >& arr, bool& atend ) 236 { 237  int count; 238  const EntityHandle* ptr; 239  WriteUtilIface* iface; 240  Interface* mbImpl = dynamic_cast< Interface* >( myCore ); 241  ErrorCode rval = mbImpl->query_interface( iface ); 242  if( MB_SUCCESS != rval ) return rval; 243  244  rval = iface->get_entity_list_pointers( &entSet, 1, &ptr, WriteUtilIface::CONTENTS, &count ); 245  if( MB_SUCCESS != rval ) return rval; 246  mbImpl->release_interface( iface ); 247  248  if( !count || iterPos >= count ) 249  { 250  atend = true; 251  return MB_SUCCESS; 252  } 253  254  std::vector< EntityHandle > tmp_arr; 255  std::vector< EntityHandle >* tmp_ptr = &arr; 256  if( checkValid ) tmp_ptr = &tmp_arr; 257  258  // just get the next chunkSize entities, or as many as you can 259  int this_ct = 0; 260  while( this_ct < (int)chunkSize && iterPos < count ) 261  { 262  if( ( MBMAXTYPE == entType || TYPE_FROM_HANDLE( ptr[iterPos] ) == entType ) && 263  ( -1 == entDimension || CN::Dimension( TYPE_FROM_HANDLE( ptr[iterPos] ) ) == entDimension ) ) 264  { 265  arr.push_back( ptr[iterPos] ); 266  this_ct++; 267  } 268  iterPos++; 269  } 270  271  atend = ( iterPos == count ); 272  273  if( checkValid ) 274  { 275  for( std::vector< EntityHandle >::iterator vit = tmp_ptr->begin(); vit != tmp_ptr->end(); ++vit ) 276  { 277  if( myCore->is_valid( *vit ) ) arr.push_back( *vit ); 278  } 279  } 280  281  // step along list, adding entities 282  return MB_SUCCESS; 283 } 284  285 ErrorCode VectorSetIterator::reset() 286 { 287  iterPos = 0; 288  return MB_SUCCESS; 289 } 290  291 } // namespace moab