Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
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"
8 #include "MeshSet.hpp"
9 #include "Internals.hpp"
10 #include "moab/CN.hpp"
11 #include "moab/Error.hpp"
12 
13 namespace moab
14 {
15 
17 {
18  myCore->remove_set_iterator( this );
19 }
20 
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 
41 {
42  if( pairPtr ) delete[] pairPtr;
43  numPairs = 0;
44 }
45 
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()];
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;
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 
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 
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 )
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 )
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 &&
223 
224  if( !iterPos || CN::Dimension( TYPE_FROM_HANDLE( iterPos ) ) != entDimension ) atend = true;
225 
226  return MB_SUCCESS;
227 }
228 
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;
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 
286 {
287  iterPos = 0;
288  return MB_SUCCESS;
289 }
290 
291 } // namespace moab