1
15
16
20
21 #include "MeshSetSequence.hpp"
22 #include "SequenceManager.hpp"
23
24 namespace moab
25 {
26
27 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, const unsigned* flags, SequenceData* dat )
28 : EntitySequence( start, count, dat )
29 {
30 initialize( flags );
31 }
32
33 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, unsigned flags, SequenceData* dat )
34 : EntitySequence( start, count, dat )
35 {
36 std::vector< unsigned > vect( count, flags );
37 initialize( &vect[0] );
38 }
39
40 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, const unsigned* flags, EntityID data_size )
41 : EntitySequence( start, count, new SequenceData( 1, start, start + data_size - 1 ) )
42 {
43 initialize( flags );
44 }
45
46 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, unsigned flags, EntityID data_size )
47 : EntitySequence( start, count, new SequenceData( 1, start, start + data_size - 1 ) )
48 {
49 std::vector< unsigned > vect( count, flags );
50 initialize( &vect[0] );
51 }
52
53 void MeshSetSequence::initialize( const unsigned* flags )
54 {
55 if( !data()->get_sequence_data( 0 ) ) data()->create_sequence_data( 0, SET_SIZE );
56
57 EntityID offset = start_handle() - data()->start_handle();
58 for( EntityID i = 0; i < size(); ++i )
59 allocate_set( flags[i], i + offset );
60 }
61
62 MeshSetSequence::~MeshSetSequence()
63 {
64 EntityID offset = start_handle() - data()->start_handle();
65 EntityID count = size();
66 for( EntityID i = 0; i < count; ++i )
67 deallocate_set( i + offset );
68 }
69
70 EntitySequence* MeshSetSequence::split( EntityHandle here )
71 {
72 return new MeshSetSequence( *this, here );
73 }
74
75 ErrorCode MeshSetSequence::pop_back( EntityID count )
76 {
77 EntityID offset = end_handle() + 1 - count - data()->start_handle();
78 ErrorCode rval = EntitySequence::pop_back( count );
79 if( MB_SUCCESS == rval )
80 for( EntityID i = 0; i < count; ++i )
81 deallocate_set( i + offset );
82 return rval;
83 }
84
85 ErrorCode MeshSetSequence::pop_front( EntityID count )
86 {
87 EntityID offset = start_handle() - data()->start_handle();
88 ErrorCode rval = EntitySequence::pop_front( count );
89 if( MB_SUCCESS == rval )
90 for( EntityID i = 0; i < count; ++i )
91 deallocate_set( i + offset );
92 return rval;
93 }
94
95 ErrorCode MeshSetSequence::push_back( EntityID count, const unsigned* flags )
96 {
97 EntityID offset = end_handle() + 1 - data()->start_handle();
98 ErrorCode rval = EntitySequence::append_entities( count );
99 if( MB_SUCCESS == rval )
100 for( EntityID i = 0; i < count; ++i )
101 allocate_set( flags[i], i + offset );
102 return rval;
103 }
104
105 ErrorCode MeshSetSequence::push_front( EntityID count, const unsigned* flags )
106 {
107 EntityID offset = start_handle() - data()->start_handle() - count;
108 ErrorCode rval = EntitySequence::prepend_entities( count );
109 if( MB_SUCCESS == rval )
110 for( EntityID i = 0; i < count; ++i )
111 allocate_set( flags[i], i + offset );
112 return rval;
113 }
114
115 void MeshSetSequence::get_const_memory_use( unsigned long& per_ent, unsigned long& seq_size ) const
116 {
117 per_ent = SET_SIZE;
118 seq_size = sizeof( *this );
119 }
120
121 unsigned long MeshSetSequence::get_per_entity_memory_use( EntityHandle first, EntityHandle last ) const
122 {
123 if( first < start_handle() ) first = start_handle();
124 if( last > end_handle() ) last = end_handle();
125
126 unsigned long sum = 0;
127 for( EntityHandle h = first; h <= last; ++h )
128 sum += get_set( h )->get_memory_use();
129 return sum;
130 }
131
132 ErrorCode MeshSetSequence::get_entities( const SequenceManager* seqman,
133 EntityHandle handle,
134 Range& entities,
135 bool recursive ) const
136 {
137 if( !recursive )
138 {
139 get_set( handle )->get_entities( entities );
140 return MB_SUCCESS;
141 }
142 else
143 {
144 std::vector< const MeshSet* > list;
145 ErrorCode rval = recursive_get_sets( handle, seqman, &list );
146 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
147 ( *i )->get_non_set_entities( entities );
148 return rval;
149 }
150 }
151
152 ErrorCode MeshSetSequence::get_entities( EntityHandle handle, std::vector< EntityHandle >& entities ) const
153 {
154 get_set( handle )->get_entities( entities );
155 return MB_SUCCESS;
156 }
157
158 ErrorCode MeshSetSequence::get_dimension( const SequenceManager* seqman,
159 EntityHandle handle,
160 int dimension,
161 std::vector< EntityHandle >& entities,
162 bool recursive ) const
163 {
164 if( !recursive )
165 {
166 get_set( handle )->get_entities_by_dimension( dimension, entities );
167 return MB_SUCCESS;
168 }
169 else
170 {
171 std::vector< const MeshSet* > list;
172 ErrorCode rval = recursive_get_sets( handle, seqman, &list );
173 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
174 ( *i )->get_entities_by_dimension( dimension, entities );
175 return rval;
176 }
177 }
178
179 ErrorCode MeshSetSequence::get_dimension( const SequenceManager* seqman,
180 EntityHandle handle,
181 int dimension,
182 Range& entities,
183 bool recursive ) const
184 {
185 if( !recursive )
186 {
187 get_set( handle )->get_entities_by_dimension( dimension, entities );
188 return MB_SUCCESS;
189 }
190 else
191 {
192 std::vector< const MeshSet* > list;
193 ErrorCode rval = recursive_get_sets( handle, seqman, &list );
194 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
195 ( *i )->get_entities_by_dimension( dimension, entities );
196 return rval;
197 }
198 }
199
200 ErrorCode MeshSetSequence::get_type( const SequenceManager* seqman,
201 EntityHandle handle,
202 EntityType tp,
203 std::vector< EntityHandle >& entities,
204 bool recursive ) const
205 {
206 if( !recursive )
207 {
208 get_set( handle )->get_entities_by_type( tp, entities );
209 return MB_SUCCESS;
210 }
211 else if( tp == MBENTITYSET )
212 {
213 return recursive_get_sets( handle, seqman, 0, 0, &entities );
214 }
215 else if( tp == MBMAXTYPE )
216 {
217 Range tmp;
218 ErrorCode rval = get_entities( seqman, handle, tmp, recursive );
219 if( MB_SUCCESS == rval )
220 {
221 #ifdef MOAB_NO_VECTOR_TEMPLATE_INSERT
222 std::copy( tmp.begin(), tmp.end(), std::back_inserter( entities ) );
223 #else
224 entities.insert( entities.end(), tmp.begin(), tmp.end() );
225 #endif
226 }
227 return rval;
228 }
229 else
230 {
231 std::vector< const MeshSet* > list;
232 ErrorCode rval = recursive_get_sets( handle, seqman, &list );
233 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
234 ( *i )->get_entities_by_type( tp, entities );
235 return rval;
236 }
237 }
238
239 ErrorCode MeshSetSequence::get_type( const SequenceManager* seqman,
240 EntityHandle handle,
241 EntityType tp,
242 Range& entities,
243 bool recursive ) const
244 {
245 if( !recursive )
246 {
247 get_set( handle )->get_entities_by_type( tp, entities );
248 return MB_SUCCESS;
249 }
250 else if( tp == MBENTITYSET )
251 {
252 return recursive_get_sets( handle, seqman, 0, &entities );
253 }
254 else if( tp == MBMAXTYPE )
255 {
256 std::vector< const MeshSet* > list;
257 ErrorCode rval = recursive_get_sets( handle, seqman, &list );
258 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
259 ( *i )->get_non_set_entities( entities );
260 return rval;
261 }
262 else
263 {
264 std::vector< const MeshSet* > list;
265 ErrorCode rval = recursive_get_sets( handle, seqman, &list );
266 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
267 ( *i )->get_entities_by_type( tp, entities );
268 return rval;
269 }
270 }
271
272 ErrorCode MeshSetSequence::num_entities( const SequenceManager* seqman,
273 EntityHandle handle,
274 int& number,
275 bool recursive ) const
276 {
277 if( !recursive )
278 {
279 number = get_set( handle )->num_entities();
280 return MB_SUCCESS;
281 }
282 else
283 {
284 Range range;
285 ErrorCode result = get_entities( seqman, handle, range, true );
286 number = range.size();
287 return result;
288 }
289 }
290
291 ErrorCode MeshSetSequence::num_dimension( const SequenceManager* seqman,
292 EntityHandle handle,
293 int dimension,
294 int& number,
295 bool recursive ) const
296 {
297 if( !recursive )
298 {
299 number = get_set( handle )->num_entities_by_dimension( dimension );
300 return MB_SUCCESS;
301 }
302 else
303 {
304 Range range;
305 ErrorCode result = get_dimension( seqman, handle, dimension, range, true );
306 number = range.size();
307 return result;
308 }
309 }
310
311 ErrorCode MeshSetSequence::num_type( const SequenceManager* seqman,
312 EntityHandle handle,
313 EntityType tp,
314 int& number,
315 bool recursive ) const
316 {
317 if( !recursive )
318 {
319 number = get_set( handle )->num_entities_by_type( tp );
320 return MB_SUCCESS;
321 }
322 else
323 {
324 Range range;
325 ErrorCode result = get_type( seqman, handle, tp, range, true );
326 number = range.size();
327 return result;
328 }
329 }
330
331 ErrorCode MeshSetSequence::recursive_get_sets( EntityHandle start_set,
332 const SequenceManager* seq_sets,
333 std::vector< const MeshSet* >* sets,
334 Range* set_handles,
335 std::vector< EntityHandle >* set_vector )
336 {
337 std::set< EntityHandle > visited;
338 std::vector< EntityHandle > stack;
339 stack.push_back( start_set );
340 bool remove_start_set = true;
341 while( !stack.empty() )
342 {
343 EntityHandle handle = stack.back();
344 stack.pop_back();
345
346 if( !visited.insert( handle ).second )
347 {
348 if( handle == start_set ) remove_start_set = false;
349 continue;
350 }
351
352 const EntitySequence* seq;
353 ErrorCode rval = seq_sets->find( handle, seq );
354 if( MB_SUCCESS != rval ) return rval;
355
356 const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
357 const MeshSet* ms_ptr = mseq->get_set( handle );
358 if( sets ) sets->push_back( ms_ptr );
359
360 Range tmp_range;
361 ms_ptr->get_entities_by_type( MBENTITYSET, tmp_range );
362 std::copy( tmp_range.begin(), tmp_range.end(), std::back_inserter( stack ) );
363 }
364
365 if( set_handles )
366 {
367 if( remove_start_set ) visited.erase( start_set );
368 Range::iterator hint = set_handles->begin();
369 std::set< EntityHandle >::iterator it;
370 for( it = visited.begin(); it != visited.end(); ++it )
371 hint = set_handles->insert( hint, *it, *it );
372 }
373
374 if( set_vector )
375 {
376 if( remove_start_set ) visited.erase( start_set );
377 std::copy( visited.begin(), visited.end(), std::back_inserter( *set_vector ) );
378 }
379
380 return MB_SUCCESS;
381 }
382
383 ErrorCode MeshSetSequence::recursive_get_sets( EntityHandle start_set,
384 SequenceManager* seq_sets,
385 std::vector< MeshSet* >& sets )
386 {
387 std::set< EntityHandle > visited;
388 std::vector< EntityHandle > stack;
389 stack.push_back( start_set );
390 while( !stack.empty() )
391 {
392 EntityHandle handle = stack.back();
393 stack.pop_back();
394
395 if( !visited.insert( handle ).second ) continue;
396
397 EntitySequence* seq;
398 ErrorCode rval = seq_sets->find( handle, seq );
399 if( MB_SUCCESS != rval ) return rval;
400
401 MeshSetSequence* mseq = reinterpret_cast< MeshSetSequence* >( seq );
402 MeshSet* ms_ptr = mseq->get_set( handle );
403 sets.push_back( ms_ptr );
404
405 Range tmp_range;
406 ms_ptr->get_entities_by_type( MBENTITYSET, tmp_range );
407 std::copy( tmp_range.begin(), tmp_range.end(), std::back_inserter( stack ) );
408 }
409
410 return MB_SUCCESS;
411 }
412
413 ErrorCode MeshSetSequence::get_parent_child_meshsets( EntityHandle meshset,
414 const SequenceManager* seq_sets,
415 std::vector< EntityHandle >& results,
416 int num_hops,
417 SearchType link_type ) const
418 {
419 ErrorCode result = MB_SUCCESS;
420 std::vector< EntityHandle >::iterator i;
421 const EntityHandle *tmp_array = 0, *end;
422 EntityHandle s, e;
423 int count = 0;
424 size_t n;
425
426
427
428
429
430
431 std::set< EntityHandle > visited;
432 for( i = results.begin(); i != results.end(); ++i )
433 visited.insert( *i );
434
435
436 std::vector< EntityHandle > lists[2];
437 int index = 0;
438 lists[index].push_back( meshset );
439
440 for( ; num_hops && !lists[index].empty(); --num_hops )
441 {
442
443 for( i = lists[index].begin(); i != lists[index].end(); ++i )
444 {
445
446 const EntitySequence* seq;
447 ErrorCode rval = seq_sets->find( *i, seq );
448 if( MB_SUCCESS != rval ) return rval;
449 const MeshSet* ms_ptr = reinterpret_cast< const MeshSetSequence* >( seq )->get_set( *i );
450
451 switch( link_type )
452 {
453 case CONTAINED:
454 tmp_array = ms_ptr->get_contents( n );
455 end = tmp_array + n;
456 if( ms_ptr->vector_based() )
457 {
458 for( ; tmp_array != end; ++tmp_array )
459 if( MBENTITYSET == TYPE_FROM_HANDLE( *tmp_array ) && visited.insert( *tmp_array ).second )
460 lists[1 - index].push_back( *tmp_array );
461 }
462 else
463 {
464 assert( n % 2 == 0 );
465 tmp_array = std::lower_bound( tmp_array, tmp_array + n, FIRST_HANDLE( MBENTITYSET ) );
466
467 if( ( end - tmp_array ) % 2 )
468 {
469 ++tmp_array;
470 s = FIRST_HANDLE( MBENTITYSET );
471 e = *tmp_array;
472 for( ; s <= e; ++s )
473 if( visited.insert( s ).second ) lists[1 - index].push_back( s );
474 }
475 while( tmp_array < end )
476 {
477 s = *tmp_array++;
478 e = *tmp_array++;
479 for( ; s <= e; ++s )
480 if( visited.insert( s ).second ) lists[1 - index].push_back( s );
481 }
482 }
483 continue;
484 case PARENTS:
485 tmp_array = ms_ptr->get_parents( count );
486 break;
487 case CHILDREN:
488 tmp_array = ms_ptr->get_children( count );
489 break;
490 }
491
492
493 for( end = tmp_array + count; tmp_array != end; ++tmp_array )
494 if( visited.insert( *tmp_array ).second ) lists[1 - index].push_back( *tmp_array );
495 }
496
497
498 lists[index].clear();
499 index = 1 - index;
500
501
502
503
504
505 std::copy( lists[index].begin(), lists[index].end(), std::back_inserter( results ) );
506 }
507
508 return result;
509 }
510
511 ErrorCode MeshSetSequence::get_parents( const SequenceManager* seqman,
512 EntityHandle handle,
513 std::vector< EntityHandle >& parents,
514 int num_hops ) const
515 {
516 if( num_hops == 1 )
517 {
518 int count;
519 const EntityHandle* tmp_array = get_set( handle )->get_parents( count );
520 if( parents.empty() )
521 {
522 parents.resize( count );
523 std::copy( tmp_array, tmp_array + count, parents.begin() );
524 return MB_SUCCESS;
525 }
526 else if( !count )
527 {
528 return MB_SUCCESS;
529 }
530 }
531
532 if( num_hops > 0 )
533 return get_parent_child_meshsets( handle, seqman, parents, num_hops, PARENTS );
534 else
535 return get_parent_child_meshsets( handle, seqman, parents, -1, PARENTS );
536 }
537
538 ErrorCode MeshSetSequence::get_children( const SequenceManager* seqman,
539 EntityHandle handle,
540 std::vector< EntityHandle >& children,
541 int num_hops ) const
542 {
543 if( num_hops == 1 )
544 {
545 int count;
546 const EntityHandle* tmp_array = get_set( handle )->get_children( count );
547 if( children.empty() )
548 {
549 children.resize( count );
550 std::copy( tmp_array, tmp_array + count, children.begin() );
551 return MB_SUCCESS;
552 }
553 else if( !count )
554 {
555 return MB_SUCCESS;
556 }
557 }
558
559 if( num_hops > 0 )
560 return get_parent_child_meshsets( handle, seqman, children, num_hops, CHILDREN );
561 else
562 return get_parent_child_meshsets( handle, seqman, children, -1, CHILDREN );
563 }
564
565 ErrorCode MeshSetSequence::get_contained_sets( const SequenceManager* seqman,
566 EntityHandle handle,
567 std::vector< EntityHandle >& contained,
568 int num_hops ) const
569 {
570 if( num_hops == 1 && contained.empty() )
571 {
572 return get_set( handle )->get_entities_by_type( MBENTITYSET, contained );
573 }
574
575 if( num_hops > 0 )
576 return get_parent_child_meshsets( handle, seqman, contained, num_hops, CONTAINED );
577 else
578 return get_parent_child_meshsets( handle, seqman, contained, -1, CONTAINED );
579 }
580
581 ErrorCode MeshSetSequence::num_parents( const SequenceManager* seqman,
582 EntityHandle handle,
583 int& number,
584 int num_hops ) const
585 {
586 if( num_hops == 1 )
587 {
588 number = get_set( handle )->num_parents();
589 return MB_SUCCESS;
590 }
591
592 std::vector< EntityHandle > parents;
593 ErrorCode result = get_parents( seqman, handle, parents, num_hops );
594 number = parents.size();
595 return result;
596 }
597
598 ErrorCode MeshSetSequence::num_children( const SequenceManager* seqman,
599 EntityHandle handle,
600 int& number,
601 int num_hops ) const
602 {
603 if( num_hops == 1 )
604 {
605 number = get_set( handle )->num_children();
606 return MB_SUCCESS;
607 }
608
609 std::vector< EntityHandle > children;
610 ErrorCode result = get_children( seqman, handle, children, num_hops );
611 number = children.size();
612 return result;
613 }
614
615 ErrorCode MeshSetSequence::num_contained_sets( const SequenceManager* seqman,
616 EntityHandle handle,
617 int& number,
618 int num_hops ) const
619 {
620 if( num_hops == 1 )
621 {
622 number = get_set( handle )->num_entities_by_type( MBENTITYSET );
623 return MB_SUCCESS;
624 }
625
626 std::vector< EntityHandle > contained;
627 ErrorCode result = get_contained_sets( seqman, handle, contained, num_hops );
628 number = contained.size();
629 return result;
630 }
631
632 }