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
32 ErrorCode rval = build_pair_vec();
33 assert( MB_SUCCESS == rval );
34
35
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
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
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
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
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
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
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
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
282 return MB_SUCCESS;
283 }
284
285 ErrorCode VectorSetIterator::reset()
286 {
287 iterPos = 0;
288 return MB_SUCCESS;
289 }
290
291 }