1 #ifndef MB_MESHSET_HPP
2 #define MB_MESHSET_HPP
3
4 #ifndef IS_BUILDING_MB
5 #error "MB_MeshSet.hpp isn't supposed to be included into an application"
6 #endif
7
8 #include "moab/Interface.hpp"
9 #include "Internals.hpp"
10 #include "moab/Range.hpp"
11 #include "moab/CN.hpp"
12
13 #include <assert.h>
14 #include <vector>
15 #include <algorithm>
16 #include <iterator>
17
18 namespace moab {
19
20 class AEntityFactory;
21
22 /** \brief Class to implement entity set functionality
23 * \author Jason Kraftcheck <kraftche@cae.wisc.edu>
24 */
25 class MeshSet
26 {
27 public:
28
29 //! create an empty meshset
30 inline MeshSet();
31 inline MeshSet(unsigned flags);
32
33 //! destructor
34 inline ~MeshSet();
35
36 inline ErrorCode set_flags( unsigned flags, EntityHandle my_handle, AEntityFactory* adjacencies );
37
38
39 //! get all children pointed to by this meshset
40 inline const EntityHandle* get_children( int& count_out ) const ;
41
42 //! get all parents pointed to by this meshset
43 inline const EntityHandle* get_parents( int& count_out ) const;
44
45 //! return the number of children pointed to by this meshset
46 inline int num_children() const ;
47
48 //! return the number of parents pointed to by this meshset
49 inline int num_parents() const;
50
51 //! add a parent to this meshset; returns true if parent was added, 0 if it was
52 //! already a parent of this meshset
53 int add_parent(EntityHandle parent);
54
55 //! add a child to this meshset; returns true if child was added, 0 if it was
56 //! already a child of this meshset
57 int add_child(EntityHandle child);
58
59 //! remove a parent from this meshset; returns true if parent was removed, 0 if it was
60 //! not a parent of this meshset
61 int remove_parent(EntityHandle parent);
62
63 //! remove a child from this meshset; returns true if child was removed, 0 if it was
64 //! not a child of this meshset
65 int remove_child(EntityHandle child);
66
flags() const67 unsigned flags() const { return mFlags; }
68 //! returns whether entities of meshsets know this meshset
tracking() const69 int tracking() const { return mFlags & MESHSET_TRACK_OWNER; }
set() const70 int set() const { return mFlags & MESHSET_SET; }
ordered() const71 int ordered() const { return mFlags & MESHSET_ORDERED; }
vector_based() const72 int vector_based() const { return ordered(); }
73
74 //! replace one entity with another in the set (contents and parent/child
75 //! lists); returns whether it was replaced or not
76 ErrorCode replace_entities(EntityHandle my_handle,
77 const EntityHandle *old_entities,
78 const EntityHandle *new_entities,
79 size_t num_entities,
80 AEntityFactory* mAdjFact);
81
82 /** Clear *contents* of set (not parents or children) */
83 inline ErrorCode clear( EntityHandle myhandle, AEntityFactory* adjacencies );
84
85 /** Clear all set lists (contents, parents, and children) */
86 inline ErrorCode clear_all( EntityHandle myhandle, AEntityFactory* adjacencies );
87
88 /** Get contents data array. NOTE: this may not contain what you expect if not vector_based */
89 inline const EntityHandle* get_contents( size_t& count_out ) const;
90 /** Get contents data array. NOTE: this may not contain what you expect if not vector_based */
91 inline EntityHandle* get_contents( size_t& count_out );
92
93 /** Get entities contained in set */
94 inline ErrorCode get_entities(std::vector<EntityHandle>& entities) const;
95
96 /** Get entities contained in set */
97 inline ErrorCode get_entities( Range& entities ) const;
98
99 //! get all entities in this MeshSet with the specified type
100 inline ErrorCode get_entities_by_type(EntityType entity_type, std::vector<EntityHandle> &entity_list) const;
101
102 inline ErrorCode get_entities_by_type( EntityType type, Range& entity_list) const;
103
104 //! return the number of entities with the given type contained in this meshset
105 inline unsigned int num_entities_by_type(EntityType type) const;
106
107 inline ErrorCode get_entities_by_dimension( int dimension, std::vector<EntityHandle> &entity_list) const;
108
109 inline ErrorCode get_entities_by_dimension( int dimension, Range& entity_list) const;
110
111 //! return the number of entities with the given type contained in this meshset
112 inline unsigned int num_entities_by_dimension(int dimension) const;
113
114 inline ErrorCode get_non_set_entities( Range& range ) const;
115
116 /** Test of meshset contains some or all of passed entities
117 *
118 *\param entities Array of entities
119 *\param num_entities Length of array of entities.
120 *\param op - Interface::UNION : Test if set contains any of the input entities
121 * - Interface::INTERSECT : Test if set contains all of the input entities
122 */
123 inline bool contains_entities(const EntityHandle *entities, int num_entities, const int op) const;
124
125
126 //! subtract/intersect/unite meshset_2 from/with/into meshset_1; modifies meshset_1
127 inline ErrorCode subtract(const MeshSet *meshset_2,
128 EntityHandle my_handle,
129 AEntityFactory* adjacencies);
130
131 ErrorCode intersect(const MeshSet *meshset_2,
132 EntityHandle my_handle,
133 AEntityFactory* adjacencies);
134
135 inline ErrorCode unite(const MeshSet *meshset_2,
136 EntityHandle my_handle,
137 AEntityFactory* adjacencies);
138
139 //! add these entities to this meshset
140 inline ErrorCode add_entities(const EntityHandle *entity_handles,
141 const int num_entities,
142 EntityHandle my_handle,
143 AEntityFactory* adjacencies);
144
145 //! add these entities to this meshset
146 inline ErrorCode add_entities(const Range &entities,
147 EntityHandle my_handle,
148 AEntityFactory* adjacencies);
149
150 //! add these entities to this meshset
151 inline ErrorCode remove_entities(const Range& entities,
152 EntityHandle my_handle,
153 AEntityFactory* adjacencies);
154
155
156 //! remove these entities from this meshset
157 inline ErrorCode remove_entities(const EntityHandle *entities,
158 const int num_entities,
159 EntityHandle my_handle,
160 AEntityFactory* adjacencies);
161
162 //! return the number of entities contained in this meshset
163 inline unsigned int num_entities() const;
164
empty() const165 inline bool empty() const { return mContentCount == ZERO; }
166
167 unsigned long get_memory_use() const;
168
169 protected:
170
171 /** Convert for changing flag values */
172 ErrorCode convert( unsigned flags, EntityHandle my_handle, AEntityFactory* adj );
173
174 /** Add explicit adjacencies from all contained entities to this (i.e. convert to tracking) */
175 ErrorCode create_adjacencies( EntityHandle myhandle, AEntityFactory* adjacencies );
176
177 /** Remvoe explicit adjacencies from all contained entities to this (i.e. convert from tracking) */
178 ErrorCode remove_adjacencies( EntityHandle myhandle, AEntityFactory* adjacencies );
179
180 /** Insert vector of handles into MeshSet */
181 ErrorCode insert_entity_vector( const EntityHandle* vect, size_t len, EntityHandle my_h, AEntityFactory* adj );
182
183 /** Insert vector of handle range pairs into MeshSet */
184 ErrorCode insert_entity_ranges( const EntityHandle* range_vect, size_t len, EntityHandle my_h, AEntityFactory* adj );
185
186 /** Insert Range of handles into MeshSet */
187 ErrorCode insert_entity_ranges( const Range& range, EntityHandle my_h, AEntityFactory* adj );
188
189 /** Remove vector of handles from MeshSet */
190 ErrorCode remove_entity_vector( const EntityHandle* vect, size_t len, EntityHandle my_h, AEntityFactory* adj );
191
192 /** Remove vector of handle range pairs from MeshSet */
193 ErrorCode remove_entity_ranges( const EntityHandle* range_vect, size_t len, EntityHandle my_h, AEntityFactory* adj );
194
195 /** Remove Range of handles from MeshSet */
196 ErrorCode remove_entity_ranges( const Range& range, EntityHandle my_h, AEntityFactory* adj );
197
198 public:
199 //! Possible values of mParentCount and mChildCount
200 enum Count { ZERO=0, ONE=1, TWO=2, MANY=3 };
201 //! If the number of entities is less than 3, store
202 //! the handles directly in the hnd member. Otherwise
203 //! use the ptr member to hold the beginning and end
204 //! of a dynamically allocated array.
205 union CompactList {
206 EntityHandle hnd[2]; //!< Two handles
207 EntityHandle* ptr[2]; //!< begin and end pointers for array
208 };
209
210 private:
211 //!Meshset propery flags
212 unsigned char mFlags;
213 //! If less than MANY, the number of parents stored inline in
214 //! parentMeshSets.hnd. If MANY, then parentMeshSets.ptr contains
215 //! array begin and end pointers for a dynamically allocated array
216 //! of parent handles.
217 unsigned mParentCount : 2;
218 //! If less than MANY, the number of children stored inline in
219 //! childMeshSets.hnd. If MANY, then childMeshSets.ptr contains
220 //! array begin and end pointers for a dynamically allocated array
221 //! of child handles.
222 unsigned mChildCount : 2;
223 //! If less than MANY, the number of children stored inline in
224 //! contentList.hnd. If MANY, then contentList.ptr contains
225 //! array begin and end pointers for a dynamically allocated array..
226 unsigned mContentCount : 2;
227 //! Storage for data lists
228 CompactList parentMeshSets, childMeshSets, contentList;
229
230 public:
231 /** get dimension of enity */
DIM_FROM_HANDLE(EntityHandle h)232 static inline int DIM_FROM_HANDLE( EntityHandle h )
233 { return CN::Dimension( TYPE_FROM_HANDLE( h ) ); }
234
235 /** Get smallest possible handle with specified dimension (first handle for first type of dimension) */
FIRST_OF_DIM(int dim)236 static inline EntityHandle FIRST_OF_DIM( int dim )
237 { return FIRST_HANDLE( CN::TypeDimensionMap[dim].first ); }
238
239 /** Get largest possible handle with specified dimension (largest handle for last type of dimension) */
LAST_OF_DIM(int dim)240 static inline EntityHandle LAST_OF_DIM( int dim )
241 { return LAST_HANDLE( CN::TypeDimensionMap[dim].second ); }
242
243 /** functor: test if handle is not of type */
244 struct not_type_test {
not_type_testmoab::MeshSet::not_type_test245 inline not_type_test( EntityType type ) : mType(type) {}
operator ()moab::MeshSet::not_type_test246 inline bool operator()( EntityHandle handle )
247 { return TYPE_FROM_HANDLE(handle) != mType; }
248 EntityType mType;
249 };
250
251 /** functor: test if handle is of type */
252 struct type_test {
type_testmoab::MeshSet::type_test253 inline type_test( EntityType type ) : mType(type) {}
operator ()moab::MeshSet::type_test254 inline bool operator()( EntityHandle handle )
255 { return TYPE_FROM_HANDLE(handle) == mType; }
256 EntityType mType;
257 };
258
259 /** functor: test if handle is not of dimension */
260 struct not_dim_test {
not_dim_testmoab::MeshSet::not_dim_test261 inline not_dim_test( int dimension ) : mDim(dimension) {}
operator ()moab::MeshSet::not_dim_test262 inline bool operator()( EntityHandle handle ) const
263 { return DIM_FROM_HANDLE(handle) != mDim; }
264 int mDim;
265 };
266
267 /** functor: test if handle is of dimension */
268 struct dim_test {
dim_testmoab::MeshSet::dim_test269 inline dim_test( int dimension ) : mDim(dimension) {}
operator ()moab::MeshSet::dim_test270 inline bool operator()( EntityHandle handle ) const
271 { return DIM_FROM_HANDLE(handle) == mDim; }
272 int mDim;
273 };
274
275 /** Iterate over range of handles. That is, given [first_handle,last_handle],
276 * step through all contained values.
277 */
278 struct hdl_iter {
279 EntityHandle h;
hdl_itermoab::MeshSet::hdl_iter280 hdl_iter( EntityHandle val ) : h(val) {}
operator ++moab::MeshSet::hdl_iter281 hdl_iter& operator++() { ++h; return *this; }
operator --moab::MeshSet::hdl_iter282 hdl_iter& operator--() { --h; return *this; }
operator ++moab::MeshSet::hdl_iter283 hdl_iter operator++(int) { return hdl_iter(h++); }
operator --moab::MeshSet::hdl_iter284 hdl_iter operator--(int) { return hdl_iter(h--); }
operator +=moab::MeshSet::hdl_iter285 hdl_iter& operator+=(size_t s) { h += s; return *this; }
operator -=moab::MeshSet::hdl_iter286 hdl_iter& operator-=(size_t s) { h -= s; return *this; }
operator *moab::MeshSet::hdl_iter287 EntityHandle operator*() const { return h; }
operator ==moab::MeshSet::hdl_iter288 bool operator==(hdl_iter other) const { return h == other.h; }
operator !=moab::MeshSet::hdl_iter289 bool operator!=(hdl_iter other) const { return h != other.h; }
operator <moab::MeshSet::hdl_iter290 bool operator< (hdl_iter other) const { return h < other.h; }
operator >moab::MeshSet::hdl_iter291 bool operator> (hdl_iter other) const { return h > other.h; }
operator <=moab::MeshSet::hdl_iter292 bool operator<=(hdl_iter other) const { return h <= other.h; }
operator >=moab::MeshSet::hdl_iter293 bool operator>=(hdl_iter other) const { return h >= other.h; }
294
295 struct iterator_category : public std::random_access_iterator_tag { };
296 typedef EntityID difference_type;
297 typedef EntityHandle value_type;
298 typedef EntityHandle* pointer;
299 typedef EntityHandle& reference;
300 };
301
302 };
303
304 inline MeshSet::hdl_iter::difference_type
operator -(const MeshSet::hdl_iter & a,const MeshSet::hdl_iter & b)305 operator-( const MeshSet::hdl_iter &a, const MeshSet::hdl_iter &b )
306 { return (MeshSet::hdl_iter::difference_type)a.h
307 - (MeshSet::hdl_iter::difference_type)b.h; }
308
309
310 //! create an empty meshset
MeshSet()311 MeshSet::MeshSet()
312 : mFlags(0), mParentCount(ZERO), mChildCount(ZERO), mContentCount(ZERO)
313 { }
314
315 //! create an empty meshset
MeshSet(unsigned flg)316 MeshSet::MeshSet(unsigned flg)
317 : mFlags((unsigned char)flg), mParentCount(ZERO), mChildCount(ZERO), mContentCount(ZERO)
318 { }
319
320 //! destructor
~MeshSet()321 MeshSet::~MeshSet()
322 {
323 if (mChildCount == MANY)
324 free( childMeshSets.ptr[0] );
325 if (mParentCount == MANY)
326 free( parentMeshSets.ptr[0] );
327 if (mContentCount == MANY)
328 free( contentList.ptr[0] );
329 mChildCount = mParentCount = mContentCount = ZERO;
330 }
331
set_flags(unsigned flg,EntityHandle my_handle,AEntityFactory * adjacencies)332 ErrorCode MeshSet::set_flags( unsigned flg, EntityHandle my_handle, AEntityFactory* adjacencies )
333 {
334 if(ZERO != mContentCount) {
335 ErrorCode result = convert(flg, my_handle, adjacencies);
336 if(MB_SUCCESS != result) return result;
337 }
338 mFlags = (unsigned char)flg;
339 return MB_SUCCESS;
340 }
341
342
343 //! get all children pointed to by this meshset
get_children(int & count_out) const344 const EntityHandle* MeshSet::get_children( int& count_out ) const
345 {
346 count_out = mChildCount;
347 if (count_out < MANY)
348 return childMeshSets.hnd;
349
350 count_out = childMeshSets.ptr[1] - childMeshSets.ptr[0];
351 return childMeshSets.ptr[0];
352 }
353
354 //! get all parents pointed to by this meshset
get_parents(int & count_out) const355 const EntityHandle* MeshSet::get_parents( int& count_out ) const
356 {
357 count_out = mParentCount;
358 if (count_out < MANY)
359 return parentMeshSets.hnd;
360
361 count_out = parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
362 return parentMeshSets.ptr[0];
363 }
364
365 //! return the number of children pointed to by this meshset
num_children() const366 int MeshSet::num_children() const
367 {
368 if (mChildCount < MANY)
369 return mChildCount;
370 else
371 return childMeshSets.ptr[1] - childMeshSets.ptr[0];
372 }
373
374 //! return the number of parents pointed to by this meshset
num_parents() const375 int MeshSet::num_parents() const
376 {
377 if (mParentCount < MANY)
378 return mParentCount;
379 else
380 return parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
381 }
382
clear(EntityHandle myhandle,AEntityFactory * adjacencies)383 inline ErrorCode MeshSet::clear( EntityHandle myhandle, AEntityFactory* adjacencies )
384 {
385 if (tracking())
386 remove_adjacencies( myhandle, adjacencies );
387 if (mContentCount == MANY)
388 free( contentList.ptr[0] );
389 mContentCount = ZERO;
390 return MB_SUCCESS;
391 }
392
clear_all(EntityHandle myhandle,AEntityFactory * adjacencies)393 inline ErrorCode MeshSet::clear_all( EntityHandle myhandle, AEntityFactory* adjacencies )
394 {
395 ErrorCode rval = clear( myhandle, adjacencies );
396 if (mChildCount == MANY)
397 free( childMeshSets.ptr[0] );
398 mChildCount = ZERO;
399 if (mParentCount == MANY)
400 free( parentMeshSets.ptr[0] );
401 mParentCount = ZERO;
402 return rval;
403 }
404
get_contents(size_t & count_out) const405 inline const EntityHandle* MeshSet::get_contents( size_t& count_out ) const
406 {
407 if (mContentCount == MANY) {
408 count_out = contentList.ptr[1] - contentList.ptr[0];
409 return contentList.ptr[0];
410 }
411 else {
412 count_out = mContentCount;
413 return contentList.hnd;
414 }
415 }
416
get_contents(size_t & count_out)417 inline EntityHandle* MeshSet::get_contents( size_t& count_out )
418 {
419 if (mContentCount == MANY) {
420 count_out = contentList.ptr[1] - contentList.ptr[0];
421 return contentList.ptr[0];
422 }
423 else {
424 count_out = mContentCount;
425 return contentList.hnd;
426 }
427 }
428
get_entities(std::vector<EntityHandle> & entities) const429 inline ErrorCode MeshSet::get_entities(std::vector<EntityHandle>& entities) const
430 {
431 size_t count;
432 const EntityHandle* ptr = get_contents( count );
433 if (vector_based()) {
434 size_t old_size = entities.size();
435 entities.resize( count+old_size );
436 std::copy( ptr, ptr+count, entities.begin()+old_size );
437 }
438 else {
439 assert(count%2 == 0);
440 for (size_t i = 0; i < count; i += 2)
441 std::copy( hdl_iter(ptr[i]), hdl_iter(ptr[i+1]+1), std::back_inserter(entities) );
442 }
443 return MB_SUCCESS;
444 }
445
get_entities(Range & entities) const446 inline ErrorCode MeshSet::get_entities(Range& entities) const
447 {
448 size_t count;
449 const EntityHandle* ptr = get_contents( count );
450 if (vector_based()) {
451 std::copy( ptr, ptr+count, range_inserter(entities) );
452 }
453 else {
454 assert(count%2 == 0);
455 Range::iterator in = entities.begin();
456 for (size_t i = 0; i < count; i += 2)
457 in = entities.insert( in, ptr[i], ptr[i+1] );
458 }
459 return MB_SUCCESS;
460 }
461
462
463 //! get all entities in this MeshSet with the specified type
get_entities_by_type(EntityType type,std::vector<EntityHandle> & entity_list) const464 inline ErrorCode MeshSet::get_entities_by_type(EntityType type,
465 std::vector<EntityHandle> &entity_list
466 ) const
467 {
468 size_t count;
469 const EntityHandle* ptr = get_contents( count );
470 if (MBMAXTYPE == type) {
471 return get_entities( entity_list);
472 }
473 else if (vector_based()) {
474 std::remove_copy_if( ptr, ptr+count,
475 std::back_inserter( entity_list ),
476 not_type_test(type) );
477 }
478 else {
479 size_t idx = std::lower_bound( ptr, ptr+count, FIRST_HANDLE(type) ) - ptr;
480 if (idx < count && TYPE_FROM_HANDLE(ptr[idx]) == type) {
481 if (idx % 2) { // only part of first block is of type
482 std::copy( hdl_iter(FIRST_HANDLE(type)), hdl_iter(ptr[idx]+1), std::back_inserter( entity_list ) );
483 ++idx;
484 }
485 for (; idx < count; idx += 2) {
486 if (TYPE_FROM_HANDLE(ptr[idx+1]) == type) // whole block is of type
487 std::copy( hdl_iter(ptr[idx]), hdl_iter(ptr[idx+1]+1), std::back_inserter( entity_list ) );
488 else {
489 if (TYPE_FROM_HANDLE(ptr[idx]) == type) // part of last block is of type
490 std::copy( hdl_iter(ptr[idx]), hdl_iter(LAST_HANDLE(type)), std::back_inserter( entity_list ) );
491 break;
492 }
493 }
494 }
495 }
496
497 return MB_SUCCESS;
498 }
499
500
get_entities_by_type(EntityType type,Range & entity_list) const501 inline ErrorCode MeshSet::get_entities_by_type( EntityType type,
502 Range& entity_list) const
503 {
504 size_t count;
505 const EntityHandle* ptr = get_contents( count );
506 if (MBMAXTYPE == type) {
507 return get_entities( entity_list );
508 }
509 else if (vector_based()) {
510 std::remove_copy_if( ptr, ptr+count,
511 range_inserter( entity_list ),
512 not_type_test(type) );
513 }
514 else {
515 size_t idx = std::lower_bound( ptr, ptr+count, FIRST_HANDLE(type) ) - ptr;
516 Range::iterator in = entity_list.begin();
517 if (idx < count && TYPE_FROM_HANDLE(ptr[idx]) == type) {
518 if (idx % 2) { // only part of first block is of type
519 in = entity_list.insert( in, FIRST_HANDLE(type), ptr[idx] );
520 ++idx;
521 }
522 for (; idx < count; idx += 2) {
523 if (TYPE_FROM_HANDLE(ptr[idx+1]) == type) // whole block is of type
524 in = entity_list.insert( in, ptr[idx], ptr[idx+1] );
525 else {
526 if (TYPE_FROM_HANDLE(ptr[idx]) == type) // part of last block is of type
527 entity_list.insert( in, ptr[idx], LAST_HANDLE(type) );
528 break;
529 }
530 }
531 }
532 }
533
534 return MB_SUCCESS;
535 }
536
537 //! return the number of entities with the given type contained in this meshset
num_entities_by_type(EntityType type) const538 inline unsigned int MeshSet::num_entities_by_type(EntityType type) const
539 {
540 unsigned int result;
541 size_t count;
542 const EntityHandle* ptr = get_contents( count );
543 if (MBMAXTYPE == type) {
544 return num_entities( );
545 }
546 else if (vector_based()) {
547 #ifndef __SUNPRO_CC
548 result = std::count_if( ptr, ptr+count, type_test(type) );
549 #else
550 std::count_if( ptr, ptr+count, type_test(type), result );
551 #endif
552 }
553 else {
554 result = 0;
555 size_t idx = std::lower_bound( ptr, ptr+count, FIRST_HANDLE(type) ) - ptr;
556 if (idx < count && TYPE_FROM_HANDLE(ptr[idx]) == type) {
557 if (idx % 2) { // only part of first block is of type
558 result += ptr[idx] - FIRST_HANDLE(type) + 1;
559 ++idx;
560 }
561 for (; idx < count; idx += 2) {
562 if (TYPE_FROM_HANDLE(ptr[idx+1]) == type) // whole block is of type
563 result += ptr[idx+1] - ptr[idx] + 1;
564 else {
565 if (TYPE_FROM_HANDLE(ptr[idx]) == type) // part of last block is of type
566 result += LAST_HANDLE(type) - ptr[idx] + 1;
567 break;
568 }
569 }
570 }
571 }
572
573 return result;
574 }
575
get_entities_by_dimension(int dimension,std::vector<EntityHandle> & entity_list) const576 inline ErrorCode MeshSet::get_entities_by_dimension( int dimension,
577 std::vector<EntityHandle> &entity_list
578 ) const
579 {
580 size_t count;
581 const EntityHandle* ptr = get_contents( count );
582 if (vector_based()) {
583 std::remove_copy_if( ptr, ptr+count,
584 std::back_inserter( entity_list ),
585 not_dim_test(dimension) );
586 }
587 else {
588 size_t idx = std::lower_bound( ptr, ptr+count, FIRST_OF_DIM(dimension) ) - ptr;
589 if (idx < count && DIM_FROM_HANDLE(ptr[idx]) == dimension) {
590 if (idx % 2) { // only part of first block is of type
591 std::copy( hdl_iter(FIRST_OF_DIM(dimension)), hdl_iter(ptr[idx]+1), std::back_inserter( entity_list ) );
592 ++idx;
593 }
594 for (; idx < count; idx += 2) {
595 if (DIM_FROM_HANDLE(ptr[idx+1]) == dimension) // whole block is of type
596 std::copy( hdl_iter(ptr[idx]), hdl_iter(ptr[idx+1]+1), std::back_inserter( entity_list ) );
597 else {
598 if (DIM_FROM_HANDLE(ptr[idx]) == dimension) // part of last block is of type
599 std::copy( hdl_iter(ptr[idx]), hdl_iter(LAST_OF_DIM(dimension)), std::back_inserter( entity_list ) );
600 break;
601 }
602 }
603 }
604 }
605
606 return MB_SUCCESS;
607 }
608
609
get_entities_by_dimension(int dimension,Range & entity_list) const610 inline ErrorCode MeshSet::get_entities_by_dimension( int dimension,
611 Range& entity_list) const
612 {
613 size_t count;
614 const EntityHandle* ptr = get_contents( count );
615 if (vector_based()) {
616 std::remove_copy_if( ptr, ptr+count,
617 range_inserter( entity_list ),
618 not_dim_test(dimension) );
619 }
620 else {
621 size_t idx = std::lower_bound( ptr, ptr+count, FIRST_OF_DIM(dimension) ) - ptr;
622 Range::iterator in = entity_list.begin();
623 if (idx < count && DIM_FROM_HANDLE(ptr[idx]) == dimension) {
624 if (idx % 2) { // only part of first block is of type
625 in = entity_list.insert( in, FIRST_OF_DIM(dimension), ptr[idx] );
626 ++idx;
627 }
628 for (; idx < count; idx += 2) {
629 if (DIM_FROM_HANDLE(ptr[idx+1]) == dimension) // whole block is of type
630 in = entity_list.insert( in, ptr[idx], ptr[idx+1] );
631 else {
632 if (DIM_FROM_HANDLE(ptr[idx]) == dimension) // part of last block is of type
633 entity_list.insert( in, ptr[idx], LAST_OF_DIM(dimension) );
634 break;
635 }
636 }
637 }
638 }
639
640 return MB_SUCCESS;
641 }
642
643 //! return the number of entities with the given type contained in this meshset
num_entities_by_dimension(int dimension) const644 inline unsigned int MeshSet::num_entities_by_dimension(int dimension) const
645 {
646 unsigned int result;
647 size_t count;
648 const EntityHandle* ptr = get_contents( count );
649 if (vector_based()) {
650 #ifndef __SUNPRO_CC
651 result = std::count_if( ptr, ptr+count, dim_test(dimension) );
652 #else
653 std::count_if( ptr, ptr+count, dim_test(dimension), result );
654 #endif
655 }
656 else {
657 result = 0;
658 size_t idx = std::lower_bound( ptr, ptr+count, FIRST_OF_DIM(dimension) ) - ptr;
659 if (idx < count && DIM_FROM_HANDLE(ptr[idx]) == dimension) {
660 if (idx % 2) { // only part of first block is of type
661 result += ptr[idx] - FIRST_OF_DIM(dimension) + 1;
662 ++idx;
663 }
664 for (; idx < count; idx += 2) {
665 if (DIM_FROM_HANDLE(ptr[idx+1]) == dimension) // whole block is of type
666 result += ptr[idx+1] - ptr[idx] + 1;
667 else {
668 if (DIM_FROM_HANDLE(ptr[idx]) == dimension) // part of last block is of type
669 result += LAST_OF_DIM(dimension) - ptr[idx] + 1;
670 break;
671 }
672 }
673 }
674 }
675
676 return result;
677 }
678
get_non_set_entities(Range & range) const679 inline ErrorCode MeshSet::get_non_set_entities( Range& range ) const
680 {
681 size_t count;
682 const EntityHandle* ptr = get_contents( count );
683 if (vector_based()) {
684 std::remove_copy_if( ptr, ptr+count,
685 range_inserter( range ),
686 type_test(MBENTITYSET) );
687 }
688 else {
689 Range::iterator in = range.begin();
690 for (size_t idx = 0; idx < count; idx += 2) {
691 if (TYPE_FROM_HANDLE(ptr[idx+1]) != MBENTITYSET)
692 in = range.insert( in, ptr[idx], ptr[idx+1] );
693 else {
694 if (TYPE_FROM_HANDLE(ptr[idx]) != MBENTITYSET)
695 in = range.insert( in, ptr[idx], LAST_HANDLE( MBENTITYSET - 1 ) );
696 break;
697 }
698 }
699 }
700
701 return MB_SUCCESS;
702 }
703
contains_entities(const EntityHandle * entities,int num_ents,const int op) const704 inline bool MeshSet::contains_entities(const EntityHandle *entities,
705 int num_ents,
706 const int op) const
707 {
708 size_t count;
709 const EntityHandle* const ptr = get_contents( count );
710 const EntityHandle* const end = ptr + count;
711 size_t found_count = 0;
712 if (vector_based()) {
713 for (int i = 0; i < num_ents; ++i)
714 if (std::find( ptr, end, entities[i] ) < end)
715 ++found_count;
716 }
717 else {
718 assert(0 == count % 2);
719 for (int i = 0; i < num_ents; ++i) {
720 const unsigned long idx = std::lower_bound( ptr, end, entities[i] ) - ptr;
721 if (idx < count && (idx%2 != 0 || ptr[idx] == entities[i]))
722 ++found_count;
723 }
724 }
725
726 return found_count >= ((Interface::INTERSECT == op) ? (unsigned)num_ents : 1u);
727 }
728
729
730
731 //! subtract/intersect/unite meshset_2 from/with/into meshset_1; modifies meshset_1
subtract(const MeshSet * meshset_2,EntityHandle my_handle,AEntityFactory * adjacencies)732 inline ErrorCode MeshSet::subtract(const MeshSet *meshset_2,
733 EntityHandle my_handle,
734 AEntityFactory* adjacencies)
735 {
736 size_t count;
737 const EntityHandle* const ptr = meshset_2->get_contents( count );
738 if (meshset_2->vector_based())
739 return remove_entity_vector( ptr, count, my_handle, adjacencies );
740 else
741 return remove_entity_ranges( ptr, count, my_handle, adjacencies );
742 }
743
unite(const MeshSet * meshset_2,EntityHandle my_handle,AEntityFactory * adjacencies)744 inline ErrorCode MeshSet::unite(const MeshSet *meshset_2,
745 EntityHandle my_handle,
746 AEntityFactory* adjacencies)
747 {
748 size_t count;
749 const EntityHandle* const ptr = meshset_2->get_contents( count );
750 if (meshset_2->vector_based())
751 return insert_entity_vector( ptr, count, my_handle, adjacencies );
752 else
753 return insert_entity_ranges( ptr, count, my_handle, adjacencies );
754 }
755
756 //! add these entities to this meshset
add_entities(const EntityHandle * entity_handles,const int num_ents,EntityHandle my_handle,AEntityFactory * adjacencies)757 inline ErrorCode MeshSet::add_entities(const EntityHandle *entity_handles,
758 const int num_ents,
759 EntityHandle my_handle,
760 AEntityFactory* adjacencies)
761 {
762 return insert_entity_vector( entity_handles, num_ents, my_handle, adjacencies );
763 }
764
765 //! add these entities to this meshset
add_entities(const Range & entities,EntityHandle my_handle,AEntityFactory * adjacencies)766 inline ErrorCode MeshSet::add_entities(const Range &entities,
767 EntityHandle my_handle,
768 AEntityFactory* adjacencies)
769 {
770 return insert_entity_ranges( entities, my_handle, adjacencies );
771 }
772
773 //! add these entities to this meshset
remove_entities(const Range & entities,EntityHandle my_handle,AEntityFactory * adjacencies)774 inline ErrorCode MeshSet::remove_entities(const Range& entities,
775 EntityHandle my_handle,
776 AEntityFactory* adjacencies)
777 {
778 return remove_entity_ranges( entities, my_handle, adjacencies );
779 }
780
781
782 //! remove these entities from this meshset
remove_entities(const EntityHandle * entities,const int num_ents,EntityHandle my_handle,AEntityFactory * adjacencies)783 inline ErrorCode MeshSet::remove_entities(const EntityHandle *entities,
784 const int num_ents,
785 EntityHandle my_handle,
786 AEntityFactory* adjacencies)
787 {
788 return remove_entity_vector( entities, num_ents, my_handle, adjacencies );
789 }
790
791 //! return the number of entities contained in this meshset
num_entities() const792 unsigned int MeshSet::num_entities() const
793 {
794 size_t count;
795 const EntityHandle* list = get_contents( count );
796 if (vector_based())
797 return count;
798
799 int result = 0;
800 const EntityHandle *const end = list + count;
801 for (; list < end; list += 2)
802 result += list[1] - list[0] + 1;
803 return result;
804 }
805
806 } // namespace moab
807
808 #endif
809