Branch data Line data Source code
1 : : #ifdef WIN32
2 : : #ifdef _DEBUG
3 : : // turn off warnings that say they debugging identifier has been truncated
4 : : // this warning comes up when using some STL containers
5 : : #pragma warning( disable : 4786 )
6 : : #endif
7 : : #endif
8 : :
9 : : #include "MeshSet.hpp"
10 : : #include "AEntityFactory.hpp"
11 : :
12 : : namespace moab
13 : : {
14 : :
15 : : /*****************************************************************************************
16 : : * Helper Function Declarations *
17 : : *****************************************************************************************/
18 : :
19 : : /**\brief Insert into parent/child list */
20 : : static inline MeshSet::Count insert_in_vector( const MeshSet::Count count, MeshSet::CompactList& list,
21 : : const EntityHandle h, int& result );
22 : :
23 : : /**\brief Remvoe from parent/child list */
24 : : static inline MeshSet::Count remove_from_vector( const MeshSet::Count count, MeshSet::CompactList& list,
25 : : const EntityHandle h, int& result );
26 : :
27 : : /**\brief Resize MeshSet::CompactList. Returns pointer to storage */
28 : : static EntityHandle* resize_compact_list( MeshSet::Count& count, MeshSet::CompactList& clist, size_t new_list_size );
29 : : /**\brief Methods to insert/remove range-based data from contents list.
30 : : * Templatized to operate on both Range and set-based MeshSets.
31 : : */
32 : : template < typename pair_iter_t >
33 : : class range_tool
34 : : {
35 : : public:
36 : : /** Insert range-based data into range-based MeshSet */
37 : : inline static ErrorCode ranged_insert_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
38 : : pair_iter_t begin, pair_iter_t end, EntityHandle my_handle,
39 : : AEntityFactory* adj );
40 : :
41 : : /** Remove range-based data from range-based MeshSet */
42 : : inline static ErrorCode ranged_remove_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
43 : : pair_iter_t begin, pair_iter_t end, EntityHandle my_handle,
44 : : AEntityFactory* adj );
45 : :
46 : : /** Insert range-based data into list-based MeshSet */
47 : : inline static ErrorCode vector_insert_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
48 : : pair_iter_t begin, pair_iter_t end, EntityHandle my_handle,
49 : : AEntityFactory* adj );
50 : : };
51 : :
52 : : /** Remove Range of handles fromr vector-based MeshSet */
53 : : static ErrorCode vector_remove_range( MeshSet::Count& count, MeshSet::CompactList& clist, const Range& range,
54 : : EntityHandle my_handle, AEntityFactory* adj );
55 : :
56 : : /** Remove range-based MeshSet contents from vector-based MeshSet */
57 : : static ErrorCode vector_remove_ranges( MeshSet::Count& count, MeshSet::CompactList& clist,
58 : : const EntityHandle* pair_list, size_t num_pairs, EntityHandle my_handle,
59 : : AEntityFactory* adj );
60 : :
61 : : /** Remove unsorted array of handles from vector-based MeshSet */
62 : : static ErrorCode vector_remove_vector( MeshSet::Count& count, MeshSet::CompactList& clist, const EntityHandle* vect,
63 : : size_t vect_size, EntityHandle my_handle, AEntityFactory* adj );
64 : :
65 : : /** Insert unsorted array of handles into vector-based MeshSet */
66 : : static ErrorCode vector_insert_vector( MeshSet::Count& count, MeshSet::CompactList& clist, const EntityHandle* vect,
67 : : size_t vect_size, EntityHandle my_handle, AEntityFactory* adj );
68 : :
69 : : /** Convert unsorted array of handles into array of ranged [begin,end] pairs */
70 : : static void convert_to_ranges( const EntityHandle* vect_in, size_t vect_in_len, std::vector< EntityHandle >& vect_out );
71 : :
72 : : /*****************************************************************************************
73 : : * Parent/Child Operations *
74 : : *****************************************************************************************/
75 : :
76 : 34896 : static inline MeshSet::Count insert_in_vector( const MeshSet::Count count, MeshSet::CompactList& list,
77 : : const EntityHandle h, int& result )
78 : : {
79 [ + + + + : 34896 : switch( count )
- ]
80 : : {
81 : : case MeshSet::ZERO:
82 : 17191 : list.hnd[0] = h;
83 : 17191 : result = true;
84 : 17191 : return MeshSet::ONE;
85 : : case MeshSet::ONE:
86 [ + + ]: 16714 : if( list.hnd[0] == h )
87 : : {
88 : 2 : result = false;
89 : 2 : return MeshSet::ONE;
90 : : }
91 : : else
92 : : {
93 : 16712 : result = true;
94 : 16712 : list.hnd[1] = h;
95 : 16712 : return MeshSet::TWO;
96 : : }
97 : : case MeshSet::TWO:
98 [ + + ][ + + ]: 616 : if( list.hnd[0] == h || list.hnd[1] == h )
99 : : {
100 : 86 : result = false;
101 : 86 : return MeshSet::TWO;
102 : : }
103 : : else
104 : : {
105 : 530 : EntityHandle* ptr = (EntityHandle*)malloc( 3 * sizeof( EntityHandle ) );
106 : 530 : ptr[0] = list.hnd[0];
107 : 530 : ptr[1] = list.hnd[1];
108 : 530 : ptr[2] = h;
109 : 530 : list.ptr[0] = ptr;
110 : 530 : list.ptr[1] = ptr + 3;
111 : 530 : result = true;
112 : 530 : return MeshSet::MANY;
113 : : }
114 : : case MeshSet::MANY:
115 [ + + ]: 375 : if( std::find( list.ptr[0], list.ptr[1], h ) != list.ptr[1] ) { result = false; }
116 : : else
117 : : {
118 : 373 : int size = list.ptr[1] - list.ptr[0];
119 : 373 : list.ptr[0] = (EntityHandle*)realloc( list.ptr[0], ( size + 1 ) * sizeof( EntityHandle ) );
120 : 373 : list.ptr[0][size] = h;
121 : 373 : list.ptr[1] = list.ptr[0] + size + 1;
122 : 373 : result = true;
123 : : }
124 : 375 : return MeshSet::MANY;
125 : : }
126 : :
127 : 0 : return MeshSet::ZERO;
128 : : }
129 : :
130 : 29610 : static inline MeshSet::Count remove_from_vector( const MeshSet::Count count, MeshSet::CompactList& list,
131 : : const EntityHandle h, int& result )
132 : : {
133 [ + + + + : 29610 : switch( count )
- ]
134 : : {
135 : : case MeshSet::ZERO:
136 : 29198 : result = false;
137 : 29198 : return MeshSet::ZERO;
138 : : case MeshSet::ONE:
139 [ + - ]: 232 : if( h == list.hnd[0] )
140 : : {
141 : 232 : result = true;
142 : 232 : return MeshSet::ZERO;
143 : : }
144 : : else
145 : : {
146 : 0 : result = false;
147 : 0 : return MeshSet::ONE;
148 : : }
149 : : case MeshSet::TWO:
150 [ + + ]: 80 : if( h == list.hnd[0] )
151 : : {
152 : 52 : list.hnd[0] = list.hnd[1];
153 : 52 : result = true;
154 : 52 : return MeshSet::ONE;
155 : : }
156 [ + + ]: 28 : else if( h == list.hnd[1] )
157 : : {
158 : 26 : result = true;
159 : 26 : return MeshSet::ONE;
160 : : }
161 : : else
162 : : {
163 : 2 : result = false;
164 : 2 : return MeshSet::TWO;
165 : : }
166 : : case MeshSet::MANY: {
167 : : EntityHandle *i, *j, *p;
168 : 100 : i = std::find( list.ptr[0], list.ptr[1], h );
169 [ + + ]: 100 : if( i == list.ptr[1] )
170 : : {
171 : 2 : result = false;
172 : 2 : return MeshSet::MANY;
173 : : }
174 : :
175 : 98 : result = true;
176 : 98 : p = list.ptr[1] - 1;
177 [ + + ]: 206 : while( i != p )
178 : : {
179 : 108 : j = i + 1;
180 : 108 : *i = *j;
181 : 108 : i = j;
182 : : }
183 : 98 : int size = p - list.ptr[0];
184 [ + + ]: 98 : if( size == 2 )
185 : : {
186 : 90 : p = list.ptr[0];
187 : 90 : list.hnd[0] = p[0];
188 : 90 : list.hnd[1] = p[1];
189 : 90 : free( p );
190 : 90 : return MeshSet::TWO;
191 : : }
192 : : else
193 : : {
194 : 8 : list.ptr[0] = (EntityHandle*)realloc( list.ptr[0], size * sizeof( EntityHandle ) );
195 : 8 : list.ptr[1] = list.ptr[0] + size;
196 : 8 : return MeshSet::MANY;
197 : : }
198 : : }
199 : : }
200 : :
201 : 0 : return MeshSet::ZERO;
202 : : }
203 : :
204 : 2207 : int MeshSet::add_parent( EntityHandle parent )
205 : : {
206 : 2207 : int result = 0;
207 [ + - ]: 2207 : mParentCount = insert_in_vector( (Count)mParentCount, parentMeshSets, parent, result );
208 : 2207 : return result;
209 : : }
210 : 32689 : int MeshSet::add_child( EntityHandle child )
211 : : {
212 : 32689 : int result = 0;
213 [ + - ]: 32689 : mChildCount = insert_in_vector( (Count)mChildCount, childMeshSets, child, result );
214 : 32689 : return result;
215 : : }
216 : :
217 : 29367 : int MeshSet::remove_parent( EntityHandle parent )
218 : : {
219 : 29367 : int result = 0;
220 [ + - ]: 29367 : mParentCount = remove_from_vector( (Count)mParentCount, parentMeshSets, parent, result );
221 : 29367 : return result;
222 : : }
223 : 243 : int MeshSet::remove_child( EntityHandle child )
224 : : {
225 : 243 : int result = 0;
226 [ + - ]: 243 : mChildCount = remove_from_vector( (Count)mChildCount, childMeshSets, child, result );
227 : 243 : return result;
228 : : }
229 : :
230 : : /*****************************************************************************************
231 : : * Flag Conversion Operations *
232 : : *****************************************************************************************/
233 : :
234 : 4 : ErrorCode MeshSet::convert( unsigned flg, EntityHandle my_handle, AEntityFactory* adj )
235 : : {
236 : 4 : ErrorCode rval = MB_SUCCESS;
237 [ + + ][ + - ]: 4 : if( ( mFlags & MESHSET_TRACK_OWNER ) && !( flg & MESHSET_TRACK_OWNER ) )
238 : 1 : rval = remove_adjacencies( my_handle, adj );
239 [ + - ][ + + ]: 3 : else if( !( mFlags & MESHSET_TRACK_OWNER ) && ( flg & MESHSET_TRACK_OWNER ) )
240 : 1 : rval = create_adjacencies( my_handle, adj );
241 [ - + ]: 4 : if( MB_SUCCESS != rval ) return rval;
242 : :
243 [ + + ][ + + ]: 4 : if( !( mFlags & MESHSET_ORDERED ) && ( flg & MESHSET_ORDERED ) )
244 : : {
245 : : size_t datalen;
246 [ + - ]: 1 : EntityHandle* data = get_contents( datalen );
247 [ + - ]: 1 : if( datalen )
248 : : {
249 [ + - ]: 1 : std::vector< EntityHandle > list( datalen );
250 [ + - ]: 1 : memcpy( &list[0], data, datalen * sizeof( EntityHandle ) );
251 [ + - ]: 1 : int num_ents = num_entities();
252 : 1 : Count count = (Count)mContentCount;
253 : 1 : data = resize_compact_list( count, contentList, num_ents );
254 : 1 : mContentCount = count;
255 [ - + ]: 1 : assert( list.size() % 2 == 0 );
256 : 1 : std::vector< EntityHandle >::iterator i = list.begin();
257 [ + - ][ + + ]: 2 : while( i != list.end() )
258 : : {
259 [ + - ]: 1 : EntityHandle h = *i;
260 [ + - ]: 1 : ++i;
261 [ + - ]: 1 : EntityHandle e = *i;
262 [ + - ]: 1 : ++i;
263 [ + + ]: 11 : for( ; h <= e; ++h )
264 : : {
265 : 10 : *data = h;
266 : 10 : ++data;
267 : : }
268 : 1 : }
269 : 1 : }
270 : : }
271 [ + + ][ + - ]: 3 : else if( ( mFlags & MESHSET_ORDERED ) && !( flg & MESHSET_ORDERED ) )
272 : : {
273 : : size_t datalen;
274 [ + - ]: 1 : EntityHandle* data = get_contents( datalen );
275 [ + - ]: 1 : if( datalen )
276 : : {
277 [ + - ]: 1 : std::vector< EntityHandle > ranges;
278 [ + - ]: 1 : convert_to_ranges( data, datalen, ranges );
279 : 1 : Count count = (Count)mContentCount;
280 : 1 : data = resize_compact_list( count, contentList, ranges.size() );
281 : 1 : mContentCount = count;
282 [ + - ]: 1 : memcpy( data, &ranges[0], ranges.size() * sizeof( EntityHandle ) );
283 : : }
284 : : }
285 : :
286 : 4 : return MB_SUCCESS;
287 : : }
288 : :
289 : 1 : ErrorCode MeshSet::create_adjacencies( EntityHandle my_handle, AEntityFactory* adj )
290 : : {
291 : 1 : ErrorCode rval = MB_SUCCESS;
292 : : ;
293 : : size_t count;
294 [ + - ]: 1 : const EntityHandle* const ptr = get_contents( count );
295 : 1 : const EntityHandle* const end = ptr + count;
296 [ + - ][ - + ]: 1 : if( vector_based() )
297 : : {
298 [ # # ]: 0 : for( const EntityHandle* i = ptr; i != end; ++i )
299 : : {
300 [ # # ]: 0 : rval = adj->add_adjacency( *i, my_handle, false );
301 [ # # ]: 0 : if( MB_SUCCESS != rval )
302 : : {
303 [ # # ]: 0 : for( const EntityHandle* j = ptr; j != i; ++j )
304 [ # # ]: 0 : adj->remove_adjacency( *j, my_handle );
305 : 0 : return rval;
306 : : }
307 : : }
308 : : }
309 : : else
310 : : {
311 [ - + ]: 1 : assert( 0 == count % 2 );
312 [ + + ]: 2 : for( const EntityHandle* i = ptr; i != end; i += 2 )
313 : : {
314 [ + + ]: 11 : for( EntityHandle h = i[0]; h <= i[1]; ++h )
315 : : {
316 [ + - ]: 10 : rval = adj->add_adjacency( h, my_handle, false );
317 [ - + ]: 10 : if( MB_SUCCESS != rval )
318 : : {
319 [ # # ]: 0 : for( EntityHandle j = i[0]; j < h; ++j )
320 [ # # ]: 0 : adj->remove_adjacency( j, my_handle );
321 [ # # ]: 0 : for( const EntityHandle* j = ptr; j != i; j += 2 )
322 [ # # ]: 0 : for( EntityHandle k = j[0]; k <= j[1]; ++k )
323 [ # # ]: 0 : adj->remove_adjacency( k, my_handle );
324 : 0 : return rval;
325 : : }
326 : : }
327 : : }
328 : : }
329 : 1 : return MB_SUCCESS;
330 : : }
331 : :
332 : 8 : ErrorCode MeshSet::remove_adjacencies( EntityHandle my_handle, AEntityFactory* adj )
333 : : {
334 : : size_t count;
335 [ + - ]: 8 : const EntityHandle* const ptr = get_contents( count );
336 : 8 : const EntityHandle* const end = ptr + count;
337 [ + - ][ + + ]: 8 : if( vector_based() )
338 : : {
339 [ + + ]: 61 : for( const EntityHandle* i = ptr; i != end; ++i )
340 [ + - ]: 57 : adj->remove_adjacency( *i, my_handle );
341 : : }
342 : : else
343 : : {
344 [ - + ]: 4 : assert( 0 == count % 2 );
345 [ + + ]: 12 : for( const EntityHandle* i = ptr; i != end; i += 2 )
346 [ + + ]: 234 : for( EntityHandle h = i[0]; h <= i[1]; ++h )
347 [ + - ]: 226 : adj->remove_adjacency( h, my_handle );
348 : : }
349 : 8 : return MB_SUCCESS;
350 : : }
351 : :
352 : : /*****************************************************************************************
353 : : * Contents Modifiction Methods *
354 : : *****************************************************************************************/
355 : :
356 : 31109 : static EntityHandle* resize_compact_list( MeshSet::Count& count, MeshSet::CompactList& clist, size_t new_list_size )
357 : : {
358 [ + + ]: 31109 : if( count <= 2 )
359 : : {
360 [ + + ]: 22334 : if( new_list_size <= 2 )
361 : : {
362 : 3883 : count = (MeshSet::Count)new_list_size;
363 : 3883 : return clist.hnd;
364 : : }
365 : : else
366 : : {
367 : 18451 : EntityHandle* list = (EntityHandle*)malloc( new_list_size * sizeof( EntityHandle ) );
368 : 18451 : list[0] = clist.hnd[0];
369 : 18451 : list[1] = clist.hnd[1];
370 : 18451 : clist.ptr[0] = list;
371 : 18451 : clist.ptr[1] = list + new_list_size;
372 : 18451 : count = MeshSet::MANY;
373 : 18451 : return list;
374 : : }
375 : : }
376 [ + + ]: 8775 : else if( new_list_size > 2 )
377 : : {
378 [ + + ]: 8752 : if( new_list_size > ( size_t )( clist.ptr[1] - clist.ptr[0] ) )
379 : 514 : clist.ptr[0] = (EntityHandle*)realloc( clist.ptr[0], new_list_size * sizeof( EntityHandle ) );
380 : 8752 : clist.ptr[1] = clist.ptr[0] + new_list_size;
381 : 8752 : count = MeshSet::MANY;
382 : 8752 : return clist.ptr[0];
383 : : }
384 : : else
385 : : {
386 : 23 : EntityHandle* list = clist.ptr[0];
387 : 23 : clist.hnd[0] = list[0];
388 : 23 : clist.hnd[1] = list[1];
389 : 23 : free( list );
390 : 23 : count = (MeshSet::Count)new_list_size;
391 : 23 : return clist.hnd;
392 : : }
393 : : }
394 : :
395 : : typedef std::pair< EntityHandle, EntityHandle > MeshSetRange;
396 : :
397 : : class MeshSetRComp
398 : : {
399 : : public:
400 : 26863 : bool operator()( const MeshSetRange& r, const MeshSetRange& h )
401 : : {
402 : 26863 : return r.second < h.first;
403 : : }
404 : : };
405 : :
406 : : template < typename pair_iter_t >
407 : 29893 : inline ErrorCode range_tool< pair_iter_t >::ranged_insert_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
408 : : pair_iter_t begin, pair_iter_t end,
409 : : EntityHandle my_handle, AEntityFactory* adj )
410 : : {
411 : : // first pass:
412 : : // 1) merge existing ranges
413 : : // 2) count number of new ranges that must be inserted
414 : : EntityHandle* list_ptr;
415 : : size_t list_size;
416 [ + + ][ + + ]: 29893 : if( count < MeshSet::MANY )
417 : : {
418 : 21520 : list_ptr = clist.hnd;
419 : 21520 : list_size = count;
420 : : }
421 : : else
422 : : {
423 : 8373 : list_ptr = clist.ptr[0];
424 : 8373 : list_size = clist.ptr[1] - clist.ptr[0];
425 : : }
426 : :
427 : 29893 : MeshSetRange* list = reinterpret_cast< MeshSetRange* >( list_ptr );
428 [ - + ][ - + ]: 29893 : assert( 0 == list_size % 2 );
429 [ - + ][ - + ]: 29893 : assert( 2 * sizeof( EntityHandle ) == sizeof( MeshSetRange ) );
430 : 29893 : list_size /= 2;
431 : 29893 : MeshSetRange* const list_end = list + list_size;
432 : 29893 : MeshSetRange *list_read = list, *list_write = list;
433 : 29893 : pair_iter_t i = begin;
434 : :
435 : : // count number of range pairs that are straight insertions
436 : : // (don't overlap any range pair in the current set) that
437 : : // could not be inserted during the first pass.
438 : 29893 : size_t insert_count = 0;
439 : :
440 : : // merge lists
441 [ + - ][ + + ]: 59621 : while( i != end )
[ + + ]
442 : : {
443 : : // find first range that intersects the current input range
444 : :
445 : : // do binary search if no holes in current set contents
446 [ + + ][ + + ]: 29728 : if( list_read == list_write )
447 : : {
448 : : // subtract one from i->first because if it is one greater
449 : : // then the the last value of some block, then we want that
450 : : // block to append to.
451 : 29714 : MeshSetRange tmp;
452 [ + - ]: 18691 : tmp.first = i->first - 1;
453 [ + - ]: 18691 : tmp.second = i->second;
454 [ + - ][ + - ]: 29714 : list_write = std::lower_bound( list_read, list_end, tmp, MeshSetRComp() );
455 : 29714 : list_read = list_write;
456 : : }
457 : : // otherwise shift down until we find where we find a range block
458 : : // that intersects
459 : : else
460 [ + + ][ + - ]: 15 : while( list_read != list_end && list_read->second + 1 < i->first )
[ - + ][ - + ]
[ + + ][ + + ]
461 : : {
462 [ # # ]: 1 : *list_write = *list_read;
463 : 1 : ++list_write;
464 : 1 : ++list_read;
465 : : }
466 : :
467 : : // handle any straight insertions of range blocks
468 [ + - ][ + - ]: 121486 : for( ; i != end && ( list_read == list_end || i->second + 1 < list_read->first ); ++i )
[ + + ][ + + ]
[ + - ][ + + ]
[ + + ][ + + ]
[ + + ][ + + ]
469 : : {
470 : : // If we haven't removed any range pairs, we don't have space to
471 : : // insert here. Defer the insertion until later.
472 [ + + ][ + + ]: 91758 : if( list_read == list_write ) { ++insert_count; }
473 : : else
474 : : {
475 [ - + ][ + + ]: 9 : if( adj )
476 [ # # ][ # # ]: 4 : for( EntityHandle j = i->first; j <= i->second; ++j )
[ # # ][ + + ]
477 [ # # ]: 2 : adj->add_adjacency( j, my_handle, false );
478 : :
479 [ + - ]: 4 : list_write->first = i->first;
480 [ + - ]: 4 : list_write->second = i->second;
481 : 9 : ++list_write;
482 : : }
483 : : }
484 : :
485 : : // merge all the stuff that gets merged into a single range pair
486 : : // from both the input list and the existing set data
487 [ + + ][ + + ]: 29728 : if( list_read != list_end )
488 : : {
489 : 9661 : MeshSetRange working = *list_read; // copy because might be the same as list_write
490 : 9661 : ++list_read;
491 : :
492 : : // Check if we need to prepend to the existing block.
493 : : // We only need to check this for the first input range because
494 : : // after this working.first will always be the first possible handle
495 : : // in the merged set of ranges.
496 [ + - ][ + + ]: 9661 : if( i != end && i->first < working.first && i->second + 1 >= working.first )
[ + - ][ + + ]
[ + - ][ + - ]
[ + + ][ + + ]
[ + + ][ + - ]
497 : : {
498 [ + + ][ + + ]: 34 : if( adj )
499 [ + - ][ + + ]: 119 : for( EntityHandle h = i->first; h < working.first; ++h )
[ + + ]
500 [ + - ][ + - ]: 111 : adj->add_adjacency( h, my_handle, false );
501 [ + - ]: 34 : working.first = i->first;
502 : : }
503 : :
504 : : // Now append from the input list and the remaining set contents
505 : : // until we've consolidated all overlapping/touching ranges.
506 : 9661 : bool done = false;
507 [ + + ][ + + ]: 29073 : while( !done )
508 : : {
509 : : // does next set contents range touch working range?
510 [ + + ][ + + ]: 19412 : bool set_overlap = list_read != list_end && list_read->first <= working.second + 1;
[ + + ][ + + ]
511 : : // does next input range touch working range?
512 [ + - ][ + + ]: 19412 : bool inp_overlap = i != end && i->first <= working.second + 1;
[ + - ][ + + ]
[ + + ][ + + ]
513 : :
514 : : // if both ranges touch...
515 [ + + ][ + + ]: 19412 : if( inp_overlap && set_overlap )
[ + + ][ + + ]
516 : : {
517 : : // if next set range is contained in working, skip it
518 [ - + ][ - + ]: 40 : if( list_read->second <= working.second ) ++list_read;
519 : : // if next input range is contained in working, skip it
520 [ + - ][ - + ]: 20 : else if( i->second <= working.second )
[ - + ]
521 [ # # ]: 0 : ++i;
522 : : // Otherwise set the working end to the smaller of the two
523 : : // ends: either the next set end or the next input end.
524 : : // We want the smaller of the two because the larger might
525 : : // intersect additional ranges in the other list.
526 [ + - ][ + - ]: 20 : else if( list_read->second <= i->second )
[ + + ]
527 : : {
528 : 18 : working.second = list_read->second;
529 : 18 : ++list_read;
530 : : }
531 : : else
532 : : {
533 [ # # ]: 0 : working.second = i->second;
534 [ # # ]: 2 : ++i;
535 : : }
536 : : }
537 : : // If only the input range intersect the current working range...
538 [ + + ][ + + ]: 19392 : else if( inp_overlap )
539 : : {
540 : : // Would it be more efficient to just extent 'working' to
541 : : // the end of the current input range? We'd end up adding
542 : : // adjacencies for for entities that are already in the tracking
543 : : // set and therefore already have the adjacency.
544 [ + - ]: 87 : EntityHandle last = i->second;
545 [ + + ][ + + ]: 9702 : if( list_read != list_end && list_read->first < last )
[ + + ][ + + ]
546 : 20 : last = list_read->first - 1;
547 : : else
548 [ + - ]: 9682 : ++i;
549 : :
550 [ + + ][ + + ]: 9702 : if( last > working.second )
551 : : {
552 [ + + ][ + + ]: 9640 : if( adj )
553 [ + + ][ + + ]: 345 : for( EntityHandle h = working.second + 1; h <= last; ++h )
554 [ + - ][ + - ]: 325 : adj->add_adjacency( h, my_handle, false );
555 : :
556 : 9702 : working.second = last;
557 : : }
558 : : }
559 [ + + ][ + + ]: 9690 : else if( set_overlap )
560 : : {
561 [ + - ][ + + ]: 29 : if( working.second < list_read->second ) working.second = list_read->second;
562 : 29 : ++list_read;
563 : : }
564 : : else
565 : : {
566 : 9661 : done = true;
567 : : }
568 : : }
569 : :
570 [ - + ][ - + ]: 9661 : assert( list_write < list_read );
571 [ + - ][ + - ]: 9661 : *list_write = working;
572 : 9661 : ++list_write;
573 : : }
574 : : }
575 : :
576 : : // shuffle down entries to fill holes
577 [ + + ][ + + ]: 29893 : if( list_read == list_write )
578 : 29875 : list_read = list_write = list_end;
579 : : else
580 [ + + ][ + + ]: 27 : while( list_read < list_end )
581 : : {
582 [ + - ]: 9 : *list_write = *list_read;
583 : 9 : ++list_read;
584 : 9 : ++list_write;
585 : : }
586 : :
587 : : // adjust allocated array size
588 : 29893 : const size_t occupied_size = list_write - list;
589 : 29893 : const size_t new_list_size = occupied_size + insert_count;
590 : 29893 : list_ptr = resize_compact_list( count, clist, 2 * new_list_size );
591 : : // done?
592 [ + + ][ + + ]: 29893 : if( !insert_count ) return MB_SUCCESS;
593 : 20087 : list = reinterpret_cast< MeshSetRange* >( list_ptr );
594 : :
595 : : // Second pass: insert non-mergable range pairs
596 : : // All range pairs in the input are either completely disjoint from
597 : : // the ones in the mesh set and must be inserted or are entirely contained
598 : : // within a range pair in the mesh set.
599 [ + - ][ - + ]: 20087 : assert( begin != end ); // can't have items to insert if given empty input list
[ - + ]
600 : 20087 : pair_iter_t ri = end;
601 [ + - ]: 18649 : --ri;
602 : 20087 : list_write = list + new_list_size - 1;
603 : 20087 : list_read = list + occupied_size - 1;
604 [ + - ][ + - ]: 91823 : for( ; list_write >= list; --list_write )
605 : : {
606 [ + + ][ + + ]: 91823 : if( list_read >= list )
607 : : {
608 [ + - ][ + + ]: 848 : while( ri->first >= list_read->first && ri->second <= list_read->second )
[ + - ][ + + ]
[ + + ][ + + ]
[ + + ]
609 : : {
610 [ + - ][ - + ]: 20 : assert( ri != begin );
[ - + ]
611 [ + - ]: 20 : --ri;
612 : : }
613 : :
614 [ + - ][ + + ]: 828 : if( list_read->first > ri->second )
[ + + ]
615 : : {
616 [ + - ]: 74 : *list_write = *list_read;
617 : 74 : --list_read;
618 : 74 : continue;
619 : : }
620 : : }
621 : :
622 [ - + ][ - + ]: 91749 : assert( insert_count > 0 );
623 [ + + ][ + + ]: 91749 : if( adj )
624 [ + - ][ + - ]: 267868 : for( EntityHandle h = ri->first; h <= ri->second; ++h )
[ + + ][ + + ]
625 [ + - ]: 267615 : adj->add_adjacency( h, my_handle, false );
626 [ + - ]: 88005 : list_write->first = ri->first;
627 [ + - ]: 88005 : list_write->second = ri->second;
628 : :
629 : : // don't have reverse iterator, so check before decrement
630 : : // if insert_count isn't zero, must be more in range
631 [ + + ][ + + ]: 91749 : if( 0 == --insert_count )
632 : : {
633 [ - + ][ - + ]: 20087 : assert( list_read == list_write - 1 );
634 : 20087 : break;
635 : : }
636 : : else
637 : : {
638 [ + - ]: 71662 : --ri;
639 : : }
640 : : }
641 : :
642 [ - + ][ - + ]: 20087 : assert( !insert_count );
643 : 29893 : return MB_SUCCESS;
644 : : }
645 : :
646 : : template < typename pair_iter_t >
647 : 342 : inline ErrorCode range_tool< pair_iter_t >::ranged_remove_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
648 : : pair_iter_t begin, pair_iter_t end,
649 : : EntityHandle my_handle, AEntityFactory* adj )
650 : : {
651 : : // first pass:
652 : : // 1) remove (from) existing ranges
653 : : // 2) count number of ranges that must be split
654 : 342 : ptrdiff_t split_count = 0;
655 : : EntityHandle* list;
656 : : size_t list_size;
657 [ + + ][ + + ]: 342 : if( count < MeshSet::MANY )
658 : : {
659 : 121 : list = clist.hnd;
660 : 121 : list_size = count;
661 : : }
662 : : else
663 : : {
664 : 221 : list = clist.ptr[0];
665 : 221 : list_size = clist.ptr[1] - clist.ptr[0];
666 : : }
667 : :
668 : 342 : EntityHandle* list_write = list;
669 : 342 : EntityHandle *const list_end = list + list_size, *list_read = list;
670 : 342 : pair_iter_t i = begin;
671 : :
672 [ + + ][ + - ]: 659 : while( list_read != list_end && i != end )
[ + + ][ + + ]
[ + + ][ + + ]
673 : : {
674 : :
675 [ + - ][ + + ]: 415 : while( i != end && i->second < list_read[0] )
[ + - ][ + + ]
[ + + ][ + + ]
[ + + ]
676 [ + - ]: 80 : ++i;
677 [ + - ][ + + ]: 335 : if( i == end ) break;
[ + + ]
678 : :
679 : : // if there are holes in the current array, shuffle blocks
680 : : // down until we find the next block to remove
681 [ + + ][ + + ]: 322 : if( list_read != list_write )
682 : : {
683 [ + - ][ + - ]: 57 : while( list_read != list_end && i->second < list_read[0] )
[ - + ][ - + ]
[ + - ][ - + ]
684 : : {
685 : 0 : list_write[0] = list_read[0];
686 : 0 : list_write[1] = list_read[1];
687 : 0 : list_write += 2;
688 : 0 : list_read += 2;
689 : : }
690 : : }
691 : : // otherwise do a binary search
692 : : else
693 : : {
694 [ + - ][ + - ]: 265 : list_write = std::lower_bound( list_write, list_end, i->first );
695 : : // if in middle of range block (odd index), back up to start of block
696 : 265 : list_write -= ( list_write - list ) % 2;
697 : 265 : list_read = list_write;
698 : : }
699 : :
700 : : // if everything remaning is past end of set contents...
701 [ + + ][ + + ]: 322 : if( list_read == list_end ) break;
702 : :
703 : : // skip any remove pairs that aren't in the list
704 [ + - ][ - + ]: 317 : if( i->second < list_read[0] )
[ + + ]
705 : : {
706 [ # # ]: 0 : ++i;
707 : 3 : continue;
708 : : }
709 : :
710 : : // Begin by assuming that we will keep the entire block
711 : 314 : list_write[0] = list_read[0];
712 : 314 : list_write[1] = list_read[1];
713 : 314 : list_read += 2;
714 : :
715 [ + - ][ + - ]: 536 : for( ; i != end && i->first <= list_write[1]; ++i )
[ + + ][ + - ]
[ + + ][ + + ]
[ + + ][ + + ]
716 : : {
717 [ + - ][ + + ]: 331 : if( i->first <= list_write[0] )
[ + + ]
718 : : {
719 : : // remove whole block
720 [ + - ][ + + ]: 264 : if( i->second >= list_write[1] )
[ + + ]
721 : : {
722 [ + + ][ + + ]: 84 : if( adj )
723 [ + + ][ + + ]: 909 : for( EntityHandle h = list_write[0]; h <= list_write[1]; ++h )
724 [ + - ]: 886 : adj->remove_adjacency( h, my_handle );
725 : 84 : list_write -= 2;
726 : 84 : break;
727 : : }
728 : : // remove from start of block
729 [ + - ][ + - ]: 180 : else if( i->second >= list_write[0] )
[ + - ]
730 : : {
731 [ + + ][ + + ]: 180 : if( adj )
732 [ + - ][ + + ]: 245 : for( EntityHandle h = list_write[0]; h <= i->second; ++h )
[ + + ]
733 [ + - ]: 155 : adj->remove_adjacency( h, my_handle );
734 [ + - ]: 180 : list_write[0] = i->second + 1;
735 : : }
736 : : }
737 [ + - ][ + - ]: 67 : else if( i->first <= list_write[1] )
[ + - ]
738 : : {
739 : : // remove from end of block
740 [ + - ][ + + ]: 67 : if( i->second >= list_write[1] )
[ + + ]
741 : : {
742 [ + + ][ + + ]: 25 : if( adj )
743 [ + - ][ + + ]: 272 : for( EntityHandle h = i->first; h <= list_write[1]; ++h )
[ + + ]
744 [ + - ]: 259 : adj->remove_adjacency( h, my_handle );
745 [ + - ]: 10 : list_write[1] = i->first - 1;
746 : : // list_write += 2;
747 : 25 : break;
748 : : }
749 : : // split block
750 : : else
751 : : {
752 [ + + ][ + + ]: 42 : if( adj )
753 [ + - ][ + - ]: 394 : for( EntityHandle h = i->first; h <= i->second; ++h )
[ + + ][ + + ]
754 [ + - ]: 375 : adj->remove_adjacency( h, my_handle );
755 : :
756 [ + - ][ + + ]: 42 : if( list_read - list_write <= 2 )
757 : : {
758 : 40 : ++split_count;
759 : 40 : continue;
760 : : }
761 : : else
762 : : {
763 : 2 : list_write[3] = list_write[1];
764 [ # # ]: 0 : list_write[1] = i->first - 1;
765 [ # # ]: 0 : list_write[2] = i->second + 1;
766 : 2 : list_write += 2;
767 : : }
768 : : }
769 : : }
770 : : }
771 : 314 : list_write += 2;
772 : : }
773 : :
774 : : // shuffle down entries to fill holes
775 [ + + ][ + + ]: 342 : if( list_read == list_write )
776 : 306 : list_read = list_write = list_end;
777 : : else
778 [ + + ][ + + ]: 53 : while( list_read < list_end )
779 : : {
780 : 17 : list_write[0] = list_read[0];
781 : 17 : list_write[1] = list_read[1];
782 : 17 : list_read += 2;
783 : 17 : list_write += 2;
784 : : }
785 : :
786 : : // adjust allocated array size
787 : 342 : const size_t occupied_size = list_write - list;
788 : 342 : const size_t new_list_size = occupied_size + 2 * split_count;
789 : 342 : list = resize_compact_list( count, clist, new_list_size );
790 : : // done?
791 [ + + ][ + + ]: 342 : if( !split_count ) return MB_SUCCESS;
792 : :
793 : : // Second pass: split range pairs
794 : : // All range pairs in the input are either already removed or
795 : : // require one of the existing range pairs to be split
796 [ + - ][ - + ]: 33 : assert( begin != end ); // can't have ranges to split if given empty input list
[ - + ]
797 : 33 : pair_iter_t ri = end;
798 [ + - ]: 20 : --ri;
799 : 33 : list_write = list + new_list_size - 2;
800 : 33 : list_read = list + occupied_size - 2;
801 [ + - ][ + - ]: 70 : for( ; list_write >= list; list_write -= 2 )
802 : : {
803 [ + - ][ + - ]: 70 : if( list_read >= list )
804 : : {
805 [ + - ][ + + ]: 108 : while( ri->second > list_read[1] )
[ + + ]
806 : : {
807 [ + - ][ - + ]: 38 : assert( ri != begin );
[ - + ]
808 [ + - ]: 38 : --ri;
809 : : }
810 : :
811 [ + - ][ + + ]: 70 : if( list_read[0] > ri->second )
[ + + ]
812 : : {
813 : 30 : list_write[0] = list_read[0];
814 : 30 : list_write[1] = list_read[1];
815 : 30 : list_read -= 2;
816 : 30 : continue;
817 : : }
818 : : }
819 : :
820 [ - + ][ - + ]: 40 : assert( split_count > 0 );
821 [ + - ]: 24 : list_write[0] = ri->second + 1;
822 : 40 : list_write[1] = list_read[1];
823 [ + - ]: 24 : list_read[1] = ri->first - 1;
824 : :
825 : : // don't have reverse iterator, so check before decrement
826 : : // if insert_count isn't zero, must be more in range
827 [ + + ][ + + ]: 40 : if( 0 == --split_count )
828 : : {
829 [ - + ][ - + ]: 33 : assert( list_read == list_write - 2 );
830 : 33 : break;
831 : : }
832 : : else
833 : : {
834 [ + - ]: 7 : --ri;
835 : : }
836 : : }
837 : :
838 [ - + ][ - + ]: 33 : assert( !split_count );
839 : 150 : return MB_SUCCESS;
840 : : }
841 : :
842 : : template < typename pair_iter_t >
843 : 196 : inline ErrorCode range_tool< pair_iter_t >::vector_insert_entities( MeshSet::Count& count, MeshSet::CompactList& clist,
844 : : pair_iter_t begin, pair_iter_t end,
845 : : EntityHandle my_handle, AEntityFactory* adj )
846 : : {
847 [ + + ][ + + ]: 196 : const size_t init_size = count < MeshSet::MANY ? (int)count : clist.ptr[1] - clist.ptr[0];
848 : 196 : size_t add_size = 0;
849 [ + - ][ + - ]: 500 : for( pair_iter_t i = begin; i != end; ++i )
[ + + ][ + + ]
850 [ + - ][ + - ]: 284 : add_size += i->second - i->first + 1;
851 : 196 : EntityHandle* list = resize_compact_list( count, clist, init_size + add_size );
852 : 196 : EntityHandle* li = list + init_size;
853 : :
854 [ + - ][ + - ]: 500 : for( pair_iter_t i = begin; i != end; ++i )
[ + + ][ + + ]
855 : : {
856 [ + - ][ + - ]: 16446 : for( EntityHandle h = i->first; h <= i->second; ++h )
[ + + ][ + + ]
857 : : {
858 [ + + ][ + - ]: 16142 : if( adj ) adj->add_adjacency( h, my_handle, false );
[ + + ]
859 : 16142 : *li = h;
860 : 16142 : ++li;
861 : : }
862 : : }
863 : :
864 : 196 : return MB_SUCCESS;
865 : : }
866 : :
867 : 61 : static ErrorCode vector_remove_range( MeshSet::Count& count, MeshSet::CompactList& clist, const Range& range,
868 : : EntityHandle my_handle, AEntityFactory* adj )
869 : : {
870 : : EntityHandle* list;
871 : : size_t list_size;
872 [ + + ]: 61 : if( count < MeshSet::MANY )
873 : : {
874 : 10 : list = clist.hnd;
875 : 10 : list_size = count;
876 : : }
877 : : else
878 : : {
879 : 51 : list = clist.ptr[0];
880 : 51 : list_size = clist.ptr[1] - clist.ptr[0];
881 : : }
882 : :
883 : 61 : const EntityHandle* const list_end = list + list_size;
884 : 61 : EntityHandle* list_write = list;
885 [ + + ]: 33775 : for( const EntityHandle* list_read = list; list_read != list_end; ++list_read )
886 : : {
887 [ + - ][ + - ]: 33714 : if( range.find( *list_read ) == range.end() )
[ + + ]
888 : : { // keep
889 : 31223 : *list_write = *list_read;
890 : 31223 : ++list_write;
891 : : }
892 [ + + ]: 2491 : else if( adj )
893 : : {
894 : 1246 : adj->remove_adjacency( *list_read, my_handle );
895 : : }
896 : : }
897 : :
898 : 61 : resize_compact_list( count, clist, list_write - list );
899 : 61 : return MB_SUCCESS;
900 : : }
901 : :
902 : 8 : static ErrorCode vector_remove_ranges( MeshSet::Count& count, MeshSet::CompactList& clist,
903 : : const EntityHandle* pair_list, size_t num_pairs, EntityHandle my_handle,
904 : : AEntityFactory* adj )
905 : : {
906 : : EntityHandle* list;
907 : : size_t list_size;
908 [ + + ]: 8 : if( count < MeshSet::MANY )
909 : : {
910 : 4 : list = clist.hnd;
911 : 4 : list_size = count;
912 : : }
913 : : else
914 : : {
915 : 4 : list = clist.ptr[0];
916 : 4 : list_size = clist.ptr[1] - clist.ptr[0];
917 : : }
918 : :
919 : 8 : const EntityHandle *const list_end = list + list_size, *const input_end = pair_list + 2 * num_pairs;
920 : 8 : EntityHandle* list_write = list;
921 [ + + ]: 856 : for( const EntityHandle* list_read = list; list_read != list_end; ++list_read )
922 : : {
923 : 848 : const EntityHandle* ptr = std::lower_bound( pair_list, input_end, *list_read );
924 [ + + ][ + + ]: 1154 : if( ( ptr != input_end && ( *ptr == *list_read || ( ptr - pair_list ) % 2 ) ) && // if in delete list
[ + + + - ]
[ + + ]
925 : 306 : std::find( list_read + 1, list_end, *list_read ) == list_end )
926 : : { // and is last occurance in list
927 : : // only remove adj if no previous occurance
928 [ + + ][ + - ]: 306 : if( adj && std::find( list, list_write, *list_read ) == list_write )
[ + + ]
929 : 153 : adj->remove_adjacency( *list_read, my_handle );
930 : : }
931 : : else
932 : : {
933 : 542 : *list_write = *list_read;
934 : 542 : ++list_write;
935 : : }
936 : : }
937 : :
938 : 8 : resize_compact_list( count, clist, list_write - list );
939 : 8 : return MB_SUCCESS;
940 : : }
941 : :
942 : 31 : static ErrorCode vector_remove_vector( MeshSet::Count& count, MeshSet::CompactList& clist, const EntityHandle* vect,
943 : : size_t vect_size, EntityHandle my_handle, AEntityFactory* adj )
944 : : {
945 : : EntityHandle* list;
946 : : size_t list_size;
947 [ + + ]: 31 : if( count < MeshSet::MANY )
948 : : {
949 : 7 : list = clist.hnd;
950 : 7 : list_size = count;
951 : : }
952 : : else
953 : : {
954 : 24 : list = clist.ptr[0];
955 : 24 : list_size = clist.ptr[1] - clist.ptr[0];
956 : : }
957 : :
958 : 31 : const EntityHandle *const list_end = list + list_size, *const input_end = vect + vect_size;
959 : 31 : EntityHandle* list_write = list;
960 [ + + ]: 5938 : for( const EntityHandle* list_read = list; list_read != list_end; ++list_read )
961 : : {
962 [ + + + - ]: 8640 : if( std::find( vect, input_end, *list_read ) != input_end && // if in delete list
[ + + ]
963 : 2733 : std::find( list_read + 1, list_end, *list_read ) == list_end )
964 : : { // and is last occurance in list
965 : : // only remove adj if no previous occurance?
966 [ + + ]: 2733 : if( adj ) // && std::find(list, list_write, *list_read) == list_write)
967 : 409 : adj->remove_adjacency( *list_read, my_handle );
968 : : }
969 : : else
970 : : {
971 : 3174 : *list_write = *list_read;
972 : 3174 : ++list_write;
973 : : }
974 : : }
975 : :
976 : 31 : resize_compact_list( count, clist, list_write - list );
977 : 31 : return MB_SUCCESS;
978 : : }
979 : :
980 : 576 : static ErrorCode vector_insert_vector( MeshSet::Count& count, MeshSet::CompactList& clist, const EntityHandle* vect,
981 : : size_t vect_size, EntityHandle my_handle, AEntityFactory* adj )
982 : : {
983 [ + + ]: 576 : const size_t orig_size = count < MeshSet::MANY ? (int)count : clist.ptr[1] - clist.ptr[0];
984 : 576 : EntityHandle* list = resize_compact_list( count, clist, orig_size + vect_size );
985 [ + + ]: 576 : if( adj )
986 [ + + ]: 1475 : for( size_t i = 0; i < vect_size; ++i )
987 : 1374 : adj->add_adjacency( vect[i], my_handle, false );
988 : 576 : memcpy( list + orig_size, vect, sizeof( EntityHandle ) * vect_size );
989 : 576 : return MB_SUCCESS;
990 : : }
991 : :
992 : 20 : ErrorCode MeshSet::insert_entity_ranges( const EntityHandle* range_vect, size_t len, EntityHandle my_h,
993 : : AEntityFactory* adj )
994 : : {
995 : : typedef const std::pair< EntityHandle, EntityHandle >* pair_vect_t;
996 : 20 : pair_vect_t pair_vect = reinterpret_cast< pair_vect_t >( range_vect );
997 : 20 : MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
998 : : ErrorCode rval;
999 [ + - ][ + + ]: 20 : if( !vector_based() )
1000 : 12 : rval = range_tool< pair_vect_t >::ranged_insert_entities( count, contentList, pair_vect, pair_vect + len / 2,
1001 [ + - ][ + + ]: 12 : my_h, tracking() ? adj : 0 );
[ + - ]
1002 : : else
1003 : 8 : rval = range_tool< pair_vect_t >::vector_insert_entities( count, contentList, pair_vect, pair_vect + len / 2,
1004 [ + - ][ + + ]: 8 : my_h, tracking() ? adj : 0 );
[ + - ]
1005 : 20 : mContentCount = count;
1006 : 20 : return rval;
1007 : : }
1008 : :
1009 : 19052 : ErrorCode MeshSet::insert_entity_ranges( const Range& range, EntityHandle my_h, AEntityFactory* adj )
1010 : : {
1011 : : ErrorCode rval;
1012 : 19052 : MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
1013 [ + - ][ + + ]: 19052 : if( !vector_based() )
1014 : : rval = range_tool< Range::const_pair_iterator >::ranged_insert_entities(
1015 [ + - ][ + + ]: 18864 : count, contentList, range.const_pair_begin(), range.const_pair_end(), my_h, tracking() ? adj : 0 );
[ + - ][ + - ]
[ + - ]
1016 : : else
1017 : : rval = range_tool< Range::const_pair_iterator >::vector_insert_entities(
1018 [ + - ][ + + ]: 188 : count, contentList, range.const_pair_begin(), range.const_pair_end(), my_h, tracking() ? adj : 0 );
[ + - ][ + - ]
[ + - ]
1019 : 19052 : mContentCount = count;
1020 : 19052 : return rval;
1021 : : }
1022 : :
1023 : 23 : ErrorCode MeshSet::remove_entity_ranges( const EntityHandle* range_vect, size_t len, EntityHandle my_h,
1024 : : AEntityFactory* adj )
1025 : : {
1026 : : ErrorCode rval;
1027 : 23 : MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
1028 [ + - ][ + + ]: 23 : if( vector_based() )
1029 [ + - ][ + + ]: 8 : rval = vector_remove_ranges( count, contentList, range_vect, len / 2, my_h, tracking() ? adj : 0 );
[ + - ]
1030 : : else
1031 : : {
1032 : : typedef const std::pair< EntityHandle, EntityHandle >* pair_vect_t;
1033 : 15 : pair_vect_t pair_vect = reinterpret_cast< pair_vect_t >( range_vect );
1034 : 15 : rval = range_tool< pair_vect_t >::ranged_remove_entities( count, contentList, pair_vect, pair_vect + len / 2,
1035 [ + - ][ + + ]: 15 : my_h, tracking() ? adj : 0 );
[ + - ]
1036 : : }
1037 : 23 : mContentCount = count;
1038 : 23 : return rval;
1039 : : }
1040 : :
1041 : 198 : ErrorCode MeshSet::remove_entity_ranges( const Range& range, EntityHandle my_h, AEntityFactory* adj )
1042 : : {
1043 : : ErrorCode rval;
1044 : 198 : MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
1045 [ + - ][ + + ]: 198 : if( vector_based() )
1046 [ + - ][ + + ]: 61 : rval = vector_remove_range( count, contentList, range, my_h, tracking() ? adj : 0 );
[ + - ]
1047 : : else
1048 : : rval = range_tool< Range::const_pair_iterator >::ranged_remove_entities(
1049 [ + - ][ + + ]: 137 : count, contentList, range.const_pair_begin(), range.const_pair_end(), my_h, tracking() ? adj : 0 );
[ + - ][ + - ]
[ + - ]
1050 : 198 : mContentCount = count;
1051 : 198 : return rval;
1052 : : }
1053 : :
1054 : 37 : ErrorCode MeshSet::intersect( const MeshSet* other, EntityHandle my_handle, AEntityFactory* adj )
1055 : : {
1056 : : ErrorCode rval;
1057 [ + + ][ + + ]: 37 : if( !vector_based() && !other->vector_based() )
[ + + ]
1058 : : {
1059 : 11 : size_t other_count = 0;
1060 [ + - ]: 11 : const EntityHandle* other_vect = other->get_contents( other_count );
1061 [ + + ][ + - ]: 11 : if( !other_count ) return clear( my_handle, adj );
1062 [ - + ]: 5 : assert( 0 == other_count % 2 );
1063 : :
1064 [ + - ]: 5 : std::vector< EntityHandle > compliment;
1065 [ + - ]: 5 : compliment.reserve( other_count + 4 );
1066 [ + - ]: 5 : if( *other_vect > 0 )
1067 : : {
1068 [ + - ]: 5 : compliment.push_back( 0 );
1069 [ + - ]: 5 : compliment.push_back( *other_vect - 1 );
1070 : : }
1071 : 5 : ++other_vect;
1072 : 5 : const EntityHandle* const other_end = other_vect + other_count - 2;
1073 [ + + ]: 17 : for( ; other_vect < other_end; other_vect += 2 )
1074 : : {
1075 [ + - ]: 12 : compliment.push_back( other_vect[0] + 1 );
1076 [ + - ]: 12 : compliment.push_back( other_vect[1] - 1 );
1077 : : }
1078 [ + - ]: 5 : if( *other_vect < ~(EntityHandle)0 )
1079 : : {
1080 [ + - ]: 5 : compliment.push_back( *other_vect + 1 );
1081 [ + - ]: 5 : compliment.push_back( ~(EntityHandle)0 );
1082 : : }
1083 : :
1084 [ + - ][ + - ]: 11 : return remove_entity_ranges( &compliment[0], compliment.size(), my_handle, adj );
1085 : : }
1086 : : else
1087 : : {
1088 [ + - ][ + - ]: 52 : Range my_ents, other_ents;
1089 [ + - ]: 26 : rval = get_entities( my_ents );
1090 [ - + ]: 26 : if( MB_SUCCESS != rval ) return rval;
1091 [ + - ]: 26 : rval = other->get_entities( other_ents );
1092 [ + - ][ + - ]: 63 : return remove_entities( moab::subtract( my_ents, other_ents ), my_handle, adj );
1093 : : }
1094 : : }
1095 : :
1096 : 11208 : static void convert_to_ranges( const EntityHandle* vect_in, size_t vect_in_len, std::vector< EntityHandle >& vect_out )
1097 : : {
1098 [ + - ]: 11208 : vect_out.reserve( 2 * vect_in_len );
1099 [ + - ]: 11208 : vect_out.resize( vect_in_len );
1100 [ + - ]: 11208 : std::copy( vect_in, vect_in + vect_in_len, vect_out.begin() );
1101 [ + - ]: 11208 : std::sort( vect_out.begin(), vect_out.end() );
1102 [ + - ][ + - ]: 11208 : vect_out.erase( std::unique( vect_out.begin(), vect_out.end() ), vect_out.end() );
1103 : :
1104 : : // duplicate all entries
1105 [ + - ]: 11208 : vect_out.resize( vect_out.size() * 2 );
1106 [ + + ]: 67212 : for( long i = vect_out.size() - 1; i >= 0; --i )
1107 [ + - ][ + - ]: 56004 : vect_out[i] = vect_out[i / 2];
1108 : :
1109 : : // compact adjacent ranges
1110 : 11208 : std::vector< EntityHandle >::iterator r = vect_out.begin(), w = vect_out.begin();
1111 [ + - ][ + + ]: 24779 : while( r != vect_out.end() )
1112 : : {
1113 [ + - ][ + - ]: 13571 : *w = *r;
1114 [ + - ]: 13571 : ++w;
1115 [ + - ]: 13571 : ++r;
1116 [ + - ][ + - ]: 13571 : *w = *r;
1117 [ + - ]: 13571 : ++r;
1118 : :
1119 [ + - ][ + + ]: 28002 : while( r != vect_out.end() && *w + 1 == *r )
[ + - ][ + - ]
[ + + ][ + - ]
[ + + # # ]
1120 : : {
1121 [ + - ]: 14431 : ++r;
1122 [ + - ][ + - ]: 14431 : *w = *r;
1123 [ + - ]: 14431 : ++r;
1124 : : }
1125 [ + - ]: 13571 : ++w;
1126 : : }
1127 : :
1128 : : // remove extra space
1129 [ + - ]: 11208 : vect_out.erase( w, vect_out.end() );
1130 : 11208 : }
1131 : :
1132 : 11593 : ErrorCode MeshSet::insert_entity_vector( const EntityHandle* vect, size_t len, EntityHandle my_h, AEntityFactory* adj )
1133 : : {
1134 : 11593 : MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
1135 : : ErrorCode rval;
1136 [ + - ][ + + ]: 11593 : if( vector_based() )
1137 [ + - ][ + + ]: 576 : rval = vector_insert_vector( count, contentList, vect, len, my_h, tracking() ? adj : 0 );
[ + - ]
1138 : : else
1139 : : {
1140 [ + - ]: 11017 : std::vector< EntityHandle > rangevect;
1141 [ + - ]: 11017 : convert_to_ranges( vect, len, rangevect );
1142 : : typedef const std::pair< EntityHandle, EntityHandle >* pair_vect_t;
1143 [ + + ][ + - ]: 11017 : pair_vect_t pair_vect = ( rangevect.empty() ) ? NULL : reinterpret_cast< pair_vect_t >( &rangevect[0] );
1144 : : rval = range_tool< pair_vect_t >::ranged_insert_entities(
1145 [ + - ][ + + ]: 11017 : count, contentList, pair_vect, pair_vect + rangevect.size() / 2, my_h, tracking() ? adj : 0 );
[ + - ]
1146 : : }
1147 : 11593 : mContentCount = count;
1148 : 11593 : return rval;
1149 : : }
1150 : :
1151 : 221 : ErrorCode MeshSet::remove_entity_vector( const EntityHandle* vect, size_t len, EntityHandle my_h, AEntityFactory* adj )
1152 : : {
1153 : 221 : MeshSet::Count count = static_cast< MeshSet::Count >( mContentCount );
1154 : : ErrorCode rval;
1155 [ + - ][ + + ]: 221 : if( vector_based() )
1156 [ + - ][ + + ]: 31 : rval = vector_remove_vector( count, contentList, vect, len, my_h, tracking() ? adj : 0 );
[ + - ]
1157 : : else
1158 : : {
1159 [ + - ]: 190 : std::vector< EntityHandle > rangevect;
1160 [ + - ]: 190 : convert_to_ranges( vect, len, rangevect );
1161 : : typedef const std::pair< EntityHandle, EntityHandle >* pair_vect_t;
1162 [ + + ][ + - ]: 190 : pair_vect_t pair_vect = ( rangevect.empty() ) ? NULL : reinterpret_cast< pair_vect_t >( &rangevect[0] );
1163 : : rval = range_tool< pair_vect_t >::ranged_remove_entities(
1164 [ + - ][ + + ]: 190 : count, contentList, pair_vect, pair_vect + rangevect.size() / 2, my_h, tracking() ? adj : 0 );
[ + - ]
1165 : : }
1166 : 221 : mContentCount = count;
1167 : 221 : return rval;
1168 : : }
1169 : :
1170 : 6 : ErrorCode MeshSet::replace_entities( EntityHandle my_handle, const EntityHandle* old_entities,
1171 : : const EntityHandle* new_entities, size_t num_ents, AEntityFactory* adjfact )
1172 : : {
1173 [ + + ]: 6 : if( vector_based() )
1174 : : {
1175 : 5 : ErrorCode result = MB_SUCCESS;
1176 : : size_t count;
1177 [ + - ]: 5 : EntityHandle* vect = get_contents( count );
1178 : 5 : EntityHandle* const vect_end = vect + count;
1179 [ + + ]: 12 : for( size_t i = 0; i < num_ents; ++i )
1180 : : {
1181 [ + - ]: 7 : EntityHandle* p = std::find( vect, vect_end, old_entities[i] );
1182 [ - + ]: 7 : if( p == vect_end ) { result = MB_ENTITY_NOT_FOUND; }
1183 : : else
1184 [ + + ]: 8 : do
1185 : : {
1186 [ + - ][ + + ]: 8 : if( tracking() )
1187 : : {
1188 [ + - ]: 3 : adjfact->remove_adjacency( *p, my_handle );
1189 [ + - ]: 3 : adjfact->add_adjacency( new_entities[i], my_handle, false );
1190 : : }
1191 : 8 : *p = new_entities[i];
1192 [ + - ]: 8 : p = std::find( p + 1, vect_end, old_entities[i] );
1193 : : } while( p != vect_end );
1194 : : }
1195 : 5 : return result;
1196 : : }
1197 : : else
1198 : : {
1199 : 1 : ErrorCode r1 = remove_entities( old_entities, num_ents, my_handle, adjfact );
1200 : 1 : ErrorCode r2 = add_entities( new_entities, num_ents, my_handle, adjfact );
1201 [ + - ]: 6 : return ( MB_SUCCESS == r2 ) ? r1 : r2;
1202 : : }
1203 : : }
1204 : :
1205 : : /*****************************************************************************************
1206 : : * Misc. Methods *
1207 : : *****************************************************************************************/
1208 : :
1209 : 0 : unsigned long MeshSet::get_memory_use() const
1210 : : {
1211 : 0 : unsigned long result = 0;
1212 [ # # ]: 0 : if( mParentCount == MANY ) result += parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
1213 [ # # ]: 0 : if( mChildCount == MANY ) result += childMeshSets.ptr[1] - childMeshSets.ptr[0];
1214 [ # # ]: 0 : if( mContentCount == MANY ) result += contentList.ptr[1] - contentList.ptr[0];
1215 : 0 : return sizeof( EntityHandle ) * result;
1216 : : }
1217 : :
1218 [ + - ][ + - ]: 228 : } // namespace moab
|