Branch data Line data Source code
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 : :
21 : : class AEntityFactory;
22 : :
23 : : /** \brief Class to implement entity set functionality
24 : : * \author Jason Kraftcheck <[email protected]>
25 : : */
26 : : class MeshSet
27 : : {
28 : : public:
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 : : //! get all children pointed to by this meshset
39 : : inline const EntityHandle* get_children( int& count_out ) const;
40 : :
41 : : //! get all parents pointed to by this meshset
42 : : inline const EntityHandle* get_parents( int& count_out ) const;
43 : :
44 : : //! return the number of children pointed to by this meshset
45 : : inline int num_children() const;
46 : :
47 : : //! return the number of parents pointed to by this meshset
48 : : inline int num_parents() const;
49 : :
50 : : //! add a parent to this meshset; returns true if parent was added, 0 if it was
51 : : //! already a parent of this meshset
52 : : int add_parent( EntityHandle parent );
53 : :
54 : : //! add a child to this meshset; returns true if child was added, 0 if it was
55 : : //! already a child of this meshset
56 : : int add_child( EntityHandle child );
57 : :
58 : : //! remove a parent from this meshset; returns true if parent was removed, 0 if it was
59 : : //! not a parent of this meshset
60 : : int remove_parent( EntityHandle parent );
61 : :
62 : : //! remove a child from this meshset; returns true if child was removed, 0 if it was
63 : : //! not a child of this meshset
64 : : int remove_child( EntityHandle child );
65 : :
66 : 2546 : unsigned flags() const
67 : : {
68 : 2546 : return mFlags;
69 : : }
70 : : //! returns whether entities of meshsets know this meshset
71 : 93624 : int tracking() const
72 : : {
73 : 93624 : return mFlags & MESHSET_TRACK_OWNER;
74 : : }
75 : : int set() const
76 : : {
77 : : return mFlags & MESHSET_SET;
78 : : }
79 : 135193 : int ordered() const
80 : : {
81 : 135193 : return mFlags & MESHSET_ORDERED;
82 : : }
83 : 135193 : int vector_based() const
84 : : {
85 : 135193 : return ordered();
86 : : }
87 : :
88 : : //! replace one entity with another in the set (contents and parent/child
89 : : //! lists); returns whether it was replaced or not
90 : : ErrorCode replace_entities( EntityHandle my_handle, const EntityHandle* old_entities,
91 : : const EntityHandle* new_entities, size_t num_entities, AEntityFactory* mAdjFact );
92 : :
93 : : /** Clear *contents* of set (not parents or children) */
94 : : inline ErrorCode clear( EntityHandle myhandle, AEntityFactory* adjacencies );
95 : :
96 : : /** Clear all set lists (contents, parents, and children) */
97 : : inline ErrorCode clear_all( EntityHandle myhandle, AEntityFactory* adjacencies );
98 : :
99 : : /** Get contents data array. NOTE: this may not contain what you expect if not vector_based */
100 : : inline const EntityHandle* get_contents( size_t& count_out ) const;
101 : : /** Get contents data array. NOTE: this may not contain what you expect if not vector_based */
102 : : inline EntityHandle* get_contents( size_t& count_out );
103 : :
104 : : /** Get entities contained in set */
105 : : inline ErrorCode get_entities( std::vector< EntityHandle >& entities ) const;
106 : :
107 : : /** Get entities contained in set */
108 : : inline ErrorCode get_entities( Range& entities ) const;
109 : :
110 : : //! get all entities in this MeshSet with the specified type
111 : : inline ErrorCode get_entities_by_type( EntityType entity_type, std::vector< EntityHandle >& entity_list ) const;
112 : :
113 : : inline ErrorCode get_entities_by_type( EntityType type, Range& entity_list ) const;
114 : :
115 : : //! return the number of entities with the given type contained in this meshset
116 : : inline unsigned int num_entities_by_type( EntityType type ) const;
117 : :
118 : : inline ErrorCode get_entities_by_dimension( int dimension, std::vector< EntityHandle >& entity_list ) const;
119 : :
120 : : inline ErrorCode get_entities_by_dimension( int dimension, Range& entity_list ) const;
121 : :
122 : : //! return the number of entities with the given type contained in this meshset
123 : : inline unsigned int num_entities_by_dimension( int dimension ) const;
124 : :
125 : : inline ErrorCode get_non_set_entities( Range& range ) const;
126 : :
127 : : /** Test of meshset contains some or all of passed entities
128 : : *
129 : : *\param entities Array of entities
130 : : *\param num_entities Length of array of entities.
131 : : *\param op - Interface::UNION : Test if set contains any of the input entities
132 : : * - Interface::INTERSECT : Test if set contains all of the input entities
133 : : */
134 : : inline bool contains_entities( const EntityHandle* entities, int num_entities, const int op ) const;
135 : :
136 : : //! subtract/intersect/unite meshset_2 from/with/into meshset_1; modifies meshset_1
137 : : inline ErrorCode subtract( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies );
138 : :
139 : : ErrorCode intersect( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies );
140 : :
141 : : inline ErrorCode unite( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies );
142 : :
143 : : //! add these entities to this meshset
144 : : inline ErrorCode add_entities( const EntityHandle* entity_handles, const int num_entities, EntityHandle my_handle,
145 : : AEntityFactory* adjacencies );
146 : :
147 : : //! add these entities to this meshset
148 : : inline ErrorCode add_entities( const Range& entities, EntityHandle my_handle, AEntityFactory* adjacencies );
149 : :
150 : : //! add these entities to this meshset
151 : : inline ErrorCode remove_entities( const Range& entities, EntityHandle my_handle, AEntityFactory* adjacencies );
152 : :
153 : : //! remove these entities from this meshset
154 : : inline ErrorCode remove_entities( const EntityHandle* entities, const int num_entities, EntityHandle my_handle,
155 : : AEntityFactory* adjacencies );
156 : :
157 : : //! return the number of entities contained in this meshset
158 : : inline unsigned int num_entities() const;
159 : :
160 : : inline bool empty() const
161 : : {
162 : : return mContentCount == ZERO;
163 : : }
164 : :
165 : : unsigned long get_memory_use() const;
166 : :
167 : : protected:
168 : : /** Convert for changing flag values */
169 : : ErrorCode convert( unsigned flags, EntityHandle my_handle, AEntityFactory* adj );
170 : :
171 : : /** Add explicit adjacencies from all contained entities to this (i.e. convert to tracking) */
172 : : ErrorCode create_adjacencies( EntityHandle myhandle, AEntityFactory* adjacencies );
173 : :
174 : : /** Remvoe explicit adjacencies from all contained entities to this (i.e. convert from tracking)
175 : : */
176 : : ErrorCode remove_adjacencies( EntityHandle myhandle, AEntityFactory* adjacencies );
177 : :
178 : : /** Insert vector of handles into MeshSet */
179 : : ErrorCode insert_entity_vector( const EntityHandle* vect, size_t len, EntityHandle my_h, AEntityFactory* adj );
180 : :
181 : : /** Insert vector of handle range pairs into MeshSet */
182 : : ErrorCode insert_entity_ranges( const EntityHandle* range_vect, size_t len, EntityHandle my_h,
183 : : AEntityFactory* adj );
184 : :
185 : : /** Insert Range of handles into MeshSet */
186 : : ErrorCode insert_entity_ranges( const Range& range, EntityHandle my_h, AEntityFactory* adj );
187 : :
188 : : /** Remove vector of handles from MeshSet */
189 : : ErrorCode remove_entity_vector( const EntityHandle* vect, size_t len, EntityHandle my_h, AEntityFactory* adj );
190 : :
191 : : /** Remove vector of handle range pairs from MeshSet */
192 : : ErrorCode remove_entity_ranges( const EntityHandle* range_vect, size_t len, EntityHandle my_h,
193 : : 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
201 : : {
202 : : ZERO = 0,
203 : : ONE = 1,
204 : : TWO = 2,
205 : : MANY = 3
206 : : };
207 : : //! If the number of entities is less than 3, store
208 : : //! the handles directly in the hnd member. Otherwise
209 : : //! use the ptr member to hold the beginning and end
210 : : //! of a dynamically allocated array.
211 : : union CompactList
212 : : {
213 : : EntityHandle hnd[2]; //!< Two handles
214 : : EntityHandle* ptr[2]; //!< begin and end pointers for array
215 : : };
216 : :
217 : : private:
218 : : //! Meshset propery flags
219 : : unsigned char mFlags;
220 : : //! If less than MANY, the number of parents stored inline in
221 : : //! parentMeshSets.hnd. If MANY, then parentMeshSets.ptr contains
222 : : //! array begin and end pointers for a dynamically allocated array
223 : : //! of parent handles.
224 : : unsigned mParentCount : 2;
225 : : //! If less than MANY, the number of children stored inline in
226 : : //! childMeshSets.hnd. If MANY, then childMeshSets.ptr contains
227 : : //! array begin and end pointers for a dynamically allocated array
228 : : //! of child handles.
229 : : unsigned mChildCount : 2;
230 : : //! If less than MANY, the number of children stored inline in
231 : : //! contentList.hnd. If MANY, then contentList.ptr contains
232 : : //! array begin and end pointers for a dynamically allocated array..
233 : : unsigned mContentCount : 2;
234 : : //! Storage for data lists
235 : : CompactList parentMeshSets, childMeshSets, contentList;
236 : :
237 : : public:
238 : : /** get dimension of enity */
239 : 290265 : static inline int DIM_FROM_HANDLE( EntityHandle h )
240 : : {
241 : 290265 : return CN::Dimension( TYPE_FROM_HANDLE( h ) );
242 : : }
243 : :
244 : : /** Get smallest possible handle with specified dimension (first handle for first type of
245 : : * dimension) */
246 : 19796 : static inline EntityHandle FIRST_OF_DIM( int dim )
247 : : {
248 : 19796 : return FIRST_HANDLE( CN::TypeDimensionMap[dim].first );
249 : : }
250 : :
251 : : /** Get largest possible handle with specified dimension (largest handle for last type of
252 : : * dimension) */
253 : 0 : static inline EntityHandle LAST_OF_DIM( int dim )
254 : : {
255 : 0 : return LAST_HANDLE( CN::TypeDimensionMap[dim].second );
256 : : }
257 : :
258 : : /** functor: test if handle is not of type */
259 : : struct not_type_test
260 : : {
261 : 1107 : inline not_type_test( EntityType type ) : mType( type ) {}
262 : 363348 : inline bool operator()( EntityHandle handle )
263 : : {
264 : 363348 : return TYPE_FROM_HANDLE( handle ) != mType;
265 : : }
266 : : EntityType mType;
267 : : };
268 : :
269 : : /** functor: test if handle is of type */
270 : : struct type_test
271 : : {
272 : 84 : inline type_test( EntityType type ) : mType( type ) {}
273 : 1164 : inline bool operator()( EntityHandle handle )
274 : : {
275 : 1164 : return TYPE_FROM_HANDLE( handle ) == mType;
276 : : }
277 : : EntityType mType;
278 : : };
279 : :
280 : : /** functor: test if handle is not of dimension */
281 : : struct not_dim_test
282 : : {
283 : 289 : inline not_dim_test( int dimension ) : mDim( dimension ) {}
284 : 150499 : inline bool operator()( EntityHandle handle ) const
285 : : {
286 : 150499 : return DIM_FROM_HANDLE( handle ) != mDim;
287 : : }
288 : : int mDim;
289 : : };
290 : :
291 : : /** functor: test if handle is of dimension */
292 : : struct dim_test
293 : : {
294 : 35 : inline dim_test( int dimension ) : mDim( dimension ) {}
295 : 10051 : inline bool operator()( EntityHandle handle ) const
296 : : {
297 : 10051 : return DIM_FROM_HANDLE( handle ) == mDim;
298 : : }
299 : : int mDim;
300 : : };
301 : :
302 : : /** Iterate over range of handles. That is, given [first_handle,last_handle],
303 : : * step through all contained values.
304 : : */
305 : : struct hdl_iter
306 : : {
307 : : EntityHandle h;
308 : 41246 : hdl_iter( EntityHandle val ) : h( val ) {}
309 : 79163 : hdl_iter& operator++()
310 : : {
311 : 79163 : ++h;
312 : 79163 : return *this;
313 : : }
314 : : hdl_iter& operator--()
315 : : {
316 : : --h;
317 : : return *this;
318 : : }
319 : : hdl_iter operator++( int )
320 : : {
321 : : return hdl_iter( h++ );
322 : : }
323 : : hdl_iter operator--( int )
324 : : {
325 : : return hdl_iter( h-- );
326 : : }
327 : : hdl_iter& operator+=( size_t s )
328 : : {
329 : : h += s;
330 : : return *this;
331 : : }
332 : : hdl_iter& operator-=( size_t s )
333 : : {
334 : : h -= s;
335 : : return *this;
336 : : }
337 : 79163 : EntityHandle operator*() const
338 : : {
339 : 79163 : return h;
340 : : }
341 : : bool operator==( hdl_iter other ) const
342 : : {
343 : : return h == other.h;
344 : : }
345 : 99786 : bool operator!=( hdl_iter other ) const
346 : : {
347 : 99786 : return h != other.h;
348 : : }
349 : : bool operator<( hdl_iter other ) const
350 : : {
351 : : return h < other.h;
352 : : }
353 : : bool operator>( hdl_iter other ) const
354 : : {
355 : : return h > other.h;
356 : : }
357 : : bool operator<=( hdl_iter other ) const
358 : : {
359 : : return h <= other.h;
360 : : }
361 : : bool operator>=( hdl_iter other ) const
362 : : {
363 : : return h >= other.h;
364 : : }
365 : :
366 : : struct iterator_category : public std::random_access_iterator_tag
367 : : {
368 : : };
369 : : typedef EntityID difference_type;
370 : : typedef EntityHandle value_type;
371 : : typedef EntityHandle* pointer;
372 : : typedef EntityHandle& reference;
373 : : };
374 : : };
375 : :
376 : : inline MeshSet::hdl_iter::difference_type operator-( const MeshSet::hdl_iter& a, const MeshSet::hdl_iter& b )
377 : : {
378 : : return (MeshSet::hdl_iter::difference_type)a.h - (MeshSet::hdl_iter::difference_type)b.h;
379 : : }
380 : :
381 : : //! create an empty meshset
382 : : MeshSet::MeshSet() : mFlags( 0 ), mParentCount( ZERO ), mChildCount( ZERO ), mContentCount( ZERO ) {}
383 : :
384 : : //! create an empty meshset
385 : 32599 : MeshSet::MeshSet( unsigned flg )
386 : 32599 : : mFlags( (unsigned char)flg ), mParentCount( ZERO ), mChildCount( ZERO ), mContentCount( ZERO )
387 : : {
388 : 32599 : }
389 : :
390 : : //! destructor
391 : 32413 : MeshSet::~MeshSet()
392 : : {
393 [ + + ]: 32413 : if( mChildCount == MANY ) free( childMeshSets.ptr[0] );
394 [ + + ]: 32413 : if( mParentCount == MANY ) free( parentMeshSets.ptr[0] );
395 [ + + ]: 32413 : if( mContentCount == MANY ) free( contentList.ptr[0] );
396 : 32413 : mChildCount = mParentCount = mContentCount = ZERO;
397 : 32413 : }
398 : :
399 : 4 : ErrorCode MeshSet::set_flags( unsigned flg, EntityHandle my_handle, AEntityFactory* adjacencies )
400 : : {
401 [ + - ]: 4 : if( ZERO != mContentCount )
402 : : {
403 : 4 : ErrorCode result = convert( flg, my_handle, adjacencies );
404 [ - + ]: 4 : if( MB_SUCCESS != result ) return result;
405 : : }
406 : 4 : mFlags = (unsigned char)flg;
407 : 4 : return MB_SUCCESS;
408 : : }
409 : :
410 : : //! get all children pointed to by this meshset
411 : 247525 : const EntityHandle* MeshSet::get_children( int& count_out ) const
412 : : {
413 : 247525 : count_out = mChildCount;
414 [ + + ]: 247525 : if( count_out < MANY ) return childMeshSets.hnd;
415 : :
416 : 297 : count_out = childMeshSets.ptr[1] - childMeshSets.ptr[0];
417 : 297 : return childMeshSets.ptr[0];
418 : : }
419 : :
420 : : //! get all parents pointed to by this meshset
421 : 30451 : const EntityHandle* MeshSet::get_parents( int& count_out ) const
422 : : {
423 : 30451 : count_out = mParentCount;
424 [ + + ]: 30451 : if( count_out < MANY ) return parentMeshSets.hnd;
425 : :
426 : 108 : count_out = parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
427 : 108 : return parentMeshSets.ptr[0];
428 : : }
429 : :
430 : : //! return the number of children pointed to by this meshset
431 : 1060 : int MeshSet::num_children() const
432 : : {
433 [ + + ]: 1060 : if( mChildCount < MANY )
434 : 960 : return mChildCount;
435 : : else
436 : 100 : return childMeshSets.ptr[1] - childMeshSets.ptr[0];
437 : : }
438 : :
439 : : //! return the number of parents pointed to by this meshset
440 : 972 : int MeshSet::num_parents() const
441 : : {
442 [ + + ]: 972 : if( mParentCount < MANY )
443 : 876 : return mParentCount;
444 : : else
445 : 96 : return parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
446 : : }
447 : :
448 : 62509 : inline ErrorCode MeshSet::clear( EntityHandle myhandle, AEntityFactory* adjacencies )
449 : : {
450 [ + + ]: 62509 : if( tracking() ) remove_adjacencies( myhandle, adjacencies );
451 [ + + ]: 62509 : if( mContentCount == MANY ) free( contentList.ptr[0] );
452 : 62509 : mContentCount = ZERO;
453 : 62509 : return MB_SUCCESS;
454 : : }
455 : :
456 : : inline ErrorCode MeshSet::clear_all( EntityHandle myhandle, AEntityFactory* adjacencies )
457 : : {
458 : : ErrorCode rval = clear( myhandle, adjacencies );
459 : : if( mChildCount == MANY ) free( childMeshSets.ptr[0] );
460 : : mChildCount = ZERO;
461 : : if( mParentCount == MANY ) free( parentMeshSets.ptr[0] );
462 : : mParentCount = ZERO;
463 : : return rval;
464 : : }
465 : :
466 : 105174 : inline const EntityHandle* MeshSet::get_contents( size_t& count_out ) const
467 : : {
468 [ + + ]: 105174 : if( mContentCount == MANY )
469 : : {
470 : 80206 : count_out = contentList.ptr[1] - contentList.ptr[0];
471 : 80206 : return contentList.ptr[0];
472 : : }
473 : : else
474 : : {
475 : 24968 : count_out = mContentCount;
476 : 24968 : return contentList.hnd;
477 : : }
478 : : }
479 : :
480 : 16 : inline EntityHandle* MeshSet::get_contents( size_t& count_out )
481 : : {
482 [ + + ]: 16 : if( mContentCount == MANY )
483 : : {
484 : 10 : count_out = contentList.ptr[1] - contentList.ptr[0];
485 : 10 : return contentList.ptr[0];
486 : : }
487 : : else
488 : : {
489 : 6 : count_out = mContentCount;
490 : 6 : return contentList.hnd;
491 : : }
492 : : }
493 : :
494 : 3986 : inline ErrorCode MeshSet::get_entities( std::vector< EntityHandle >& entities ) const
495 : : {
496 : : size_t count;
497 [ + - ]: 3986 : const EntityHandle* ptr = get_contents( count );
498 [ + - ][ + + ]: 3986 : if( vector_based() )
499 : : {
500 : 216 : size_t old_size = entities.size();
501 [ + - ]: 216 : entities.resize( count + old_size );
502 [ + - ][ + - ]: 216 : std::copy( ptr, ptr + count, entities.begin() + old_size );
503 : : }
504 : : else
505 : : {
506 [ - + ]: 3770 : assert( count % 2 == 0 );
507 [ + + ]: 15702 : for( size_t i = 0; i < count; i += 2 )
508 [ + - ][ + - ]: 11932 : std::copy( hdl_iter( ptr[i] ), hdl_iter( ptr[i + 1] + 1 ), std::back_inserter( entities ) );
[ + - ][ + - ]
509 : : }
510 : 3986 : return MB_SUCCESS;
511 : : }
512 : :
513 : 11284 : inline ErrorCode MeshSet::get_entities( Range& entities ) const
514 : : {
515 : : size_t count;
516 [ + - ]: 11284 : const EntityHandle* ptr = get_contents( count );
517 [ + - ][ + + ]: 11284 : if( vector_based() ) { std::copy( ptr, ptr + count, range_inserter( entities ) ); }
[ + - ][ + - ]
518 : : else
519 : : {
520 [ - + ]: 11063 : assert( count % 2 == 0 );
521 [ + - ]: 11063 : Range::iterator in = entities.begin();
522 [ + + ]: 60139 : for( size_t i = 0; i < count; i += 2 )
523 [ + - ]: 49076 : in = entities.insert( in, ptr[i], ptr[i + 1] );
524 : : }
525 : 11284 : return MB_SUCCESS;
526 : : }
527 : :
528 : : //! get all entities in this MeshSet with the specified type
529 : 325 : inline ErrorCode MeshSet::get_entities_by_type( EntityType type, std::vector< EntityHandle >& entity_list ) const
530 : : {
531 : : size_t count;
532 [ + - ]: 325 : const EntityHandle* ptr = get_contents( count );
533 [ + + ][ + - ]: 325 : if( MBMAXTYPE == type ) { return get_entities( entity_list ); }
534 [ + - ][ + + ]: 323 : else if( vector_based() )
535 : : {
536 [ + - ][ + - ]: 263 : std::remove_copy_if( ptr, ptr + count, std::back_inserter( entity_list ), not_type_test( type ) );
[ + - ]
537 : : }
538 : : else
539 : : {
540 [ + - ][ + - ]: 60 : size_t idx = std::lower_bound( ptr, ptr + count, FIRST_HANDLE( type ) ) - ptr;
541 [ + + ][ + - ]: 60 : if( idx < count && TYPE_FROM_HANDLE( ptr[idx] ) == type )
[ + + ][ + + ]
542 : : {
543 [ - + ]: 46 : if( idx % 2 )
544 : : { // only part of first block is of type
545 : 0 : std::copy( hdl_iter( FIRST_HANDLE( type ) ), hdl_iter( ptr[idx] + 1 ),
546 [ # # ][ # # ]: 0 : std::back_inserter( entity_list ) );
[ # # ][ # # ]
[ # # ]
547 : 0 : ++idx;
548 : : }
549 [ + + ]: 4230 : for( ; idx < count; idx += 2 )
550 : : {
551 [ + - ][ + + ]: 4184 : if( TYPE_FROM_HANDLE( ptr[idx + 1] ) == type ) // whole block is of type
552 [ + - ][ + - ]: 4174 : std::copy( hdl_iter( ptr[idx] ), hdl_iter( ptr[idx + 1] + 1 ), std::back_inserter( entity_list ) );
[ + - ][ + - ]
553 : : else
554 : : {
555 [ + - ][ - + ]: 10 : if( TYPE_FROM_HANDLE( ptr[idx] ) == type ) // part of last block is of type
556 : 0 : std::copy( hdl_iter( ptr[idx] ), hdl_iter( LAST_HANDLE( type ) ),
557 [ # # ][ # # ]: 0 : std::back_inserter( entity_list ) );
[ # # ][ # # ]
[ # # ]
558 : 10 : break;
559 : : }
560 : : }
561 : : }
562 : : }
563 : :
564 : 325 : return MB_SUCCESS;
565 : : }
566 : :
567 : 32582 : inline ErrorCode MeshSet::get_entities_by_type( EntityType type, Range& entity_list ) const
568 : : {
569 : : size_t count;
570 [ + - ]: 32582 : const EntityHandle* ptr = get_contents( count );
571 [ + + ][ + - ]: 32582 : if( MBMAXTYPE == type ) { return get_entities( entity_list ); }
572 [ + - ][ + + ]: 32560 : else if( vector_based() )
573 : : {
574 [ + - ][ + - ]: 844 : std::remove_copy_if( ptr, ptr + count, range_inserter( entity_list ), not_type_test( type ) );
[ + - ]
575 : : }
576 : : else
577 : : {
578 [ + - ][ + - ]: 31716 : size_t idx = std::lower_bound( ptr, ptr + count, FIRST_HANDLE( type ) ) - ptr;
579 [ + - ]: 31716 : Range::iterator in = entity_list.begin();
580 [ + + ][ + - ]: 31716 : if( idx < count && TYPE_FROM_HANDLE( ptr[idx] ) == type )
[ + + ][ + + ]
581 : : {
582 [ - + ]: 7906 : if( idx % 2 )
583 : : { // only part of first block is of type
584 [ # # ][ # # ]: 0 : in = entity_list.insert( in, FIRST_HANDLE( type ), ptr[idx] );
585 : 0 : ++idx;
586 : : }
587 [ + + ]: 52667 : for( ; idx < count; idx += 2 )
588 : : {
589 [ + - ][ + + ]: 20951 : if( TYPE_FROM_HANDLE( ptr[idx + 1] ) == type ) // whole block is of type
590 [ + - ]: 20899 : in = entity_list.insert( in, ptr[idx], ptr[idx + 1] );
591 : : else
592 : : {
593 [ + - ][ - + ]: 52 : if( TYPE_FROM_HANDLE( ptr[idx] ) == type ) // part of last block is of type
594 [ # # ][ # # ]: 0 : entity_list.insert( in, ptr[idx], LAST_HANDLE( type ) );
595 : 52 : break;
596 : : }
597 : : }
598 : : }
599 : : }
600 : :
601 : 32582 : return MB_SUCCESS;
602 : : }
603 : :
604 : : //! return the number of entities with the given type contained in this meshset
605 : 73 : inline unsigned int MeshSet::num_entities_by_type( EntityType type ) const
606 : : {
607 : : unsigned int result;
608 : : size_t count;
609 [ + - ]: 73 : const EntityHandle* ptr = get_contents( count );
610 [ + + ][ + - ]: 73 : if( MBMAXTYPE == type ) { return num_entities(); }
611 [ + - ][ + + ]: 71 : else if( vector_based() )
612 : : {
613 : : #ifndef __SUNPRO_CC
614 [ + - ][ + - ]: 27 : result = std::count_if( ptr, ptr + count, type_test( type ) );
615 : : #else
616 : : std::count_if( ptr, ptr + count, type_test( type ), result );
617 : : #endif
618 : : }
619 : : else
620 : : {
621 : 44 : result = 0;
622 [ + - ][ + - ]: 44 : size_t idx = std::lower_bound( ptr, ptr + count, FIRST_HANDLE( type ) ) - ptr;
623 [ + + ][ + - ]: 44 : if( idx < count && TYPE_FROM_HANDLE( ptr[idx] ) == type )
[ + + ][ + + ]
624 : : {
625 [ - + ]: 7 : if( idx % 2 )
626 : : { // only part of first block is of type
627 [ # # ]: 0 : result += ptr[idx] - FIRST_HANDLE( type ) + 1;
628 : 0 : ++idx;
629 : : }
630 [ + + ]: 16 : for( ; idx < count; idx += 2 )
631 : : {
632 [ + - ][ + + ]: 9 : if( TYPE_FROM_HANDLE( ptr[idx + 1] ) == type ) // whole block is of type
633 : 8 : result += ptr[idx + 1] - ptr[idx] + 1;
634 : : else
635 : : {
636 [ + - ][ - + ]: 1 : if( TYPE_FROM_HANDLE( ptr[idx] ) == type ) // part of last block is of type
637 [ # # ]: 0 : result += LAST_HANDLE( type ) - ptr[idx] + 1;
638 : 1 : break;
639 : : }
640 : : }
641 : : }
642 : : }
643 : :
644 : 73 : return result;
645 : : }
646 : :
647 : 66 : inline ErrorCode MeshSet::get_entities_by_dimension( int dimension, std::vector< EntityHandle >& entity_list ) const
648 : : {
649 : : size_t count;
650 [ + - ]: 66 : const EntityHandle* ptr = get_contents( count );
651 [ + - ][ + + ]: 66 : if( vector_based() )
652 [ + - ][ + - ]: 45 : { std::remove_copy_if( ptr, ptr + count, std::back_inserter( entity_list ), not_dim_test( dimension ) ); }
[ + - ]
653 : : else
654 : : {
655 [ + - ][ + - ]: 21 : size_t idx = std::lower_bound( ptr, ptr + count, FIRST_OF_DIM( dimension ) ) - ptr;
656 [ + + ][ + - ]: 21 : if( idx < count && DIM_FROM_HANDLE( ptr[idx] ) == dimension )
[ + - ][ + + ]
657 : : {
658 [ - + ]: 16 : if( idx % 2 )
659 : : { // only part of first block is of type
660 : 0 : std::copy( hdl_iter( FIRST_OF_DIM( dimension ) ), hdl_iter( ptr[idx] + 1 ),
661 [ # # ][ # # ]: 0 : std::back_inserter( entity_list ) );
[ # # ][ # # ]
[ # # ]
662 : 0 : ++idx;
663 : : }
664 [ + + ]: 4170 : for( ; idx < count; idx += 2 )
665 : : {
666 [ + - ][ + + ]: 4154 : if( DIM_FROM_HANDLE( ptr[idx + 1] ) == dimension ) // whole block is of type
667 [ + - ][ + - ]: 4144 : std::copy( hdl_iter( ptr[idx] ), hdl_iter( ptr[idx + 1] + 1 ), std::back_inserter( entity_list ) );
[ + - ][ + - ]
668 : : else
669 : : {
670 [ + - ][ - + ]: 10 : if( DIM_FROM_HANDLE( ptr[idx] ) == dimension ) // part of last block is of type
671 : 0 : std::copy( hdl_iter( ptr[idx] ), hdl_iter( LAST_OF_DIM( dimension ) ),
672 [ # # ][ # # ]: 0 : std::back_inserter( entity_list ) );
[ # # ][ # # ]
[ # # ]
673 : 10 : break;
674 : : }
675 : : }
676 : : }
677 : : }
678 : :
679 : 66 : return MB_SUCCESS;
680 : : }
681 : :
682 : 19982 : inline ErrorCode MeshSet::get_entities_by_dimension( int dimension, Range& entity_list ) const
683 : : {
684 : : size_t count;
685 [ + - ]: 19982 : const EntityHandle* ptr = get_contents( count );
686 [ + - ][ + + ]: 19982 : if( vector_based() )
687 [ + - ][ + - ]: 244 : { std::remove_copy_if( ptr, ptr + count, range_inserter( entity_list ), not_dim_test( dimension ) ); }
[ + - ]
688 : : else
689 : : {
690 [ + - ][ + - ]: 19738 : size_t idx = std::lower_bound( ptr, ptr + count, FIRST_OF_DIM( dimension ) ) - ptr;
691 [ + - ]: 19738 : Range::iterator in = entity_list.begin();
692 [ + + ][ + - ]: 19738 : if( idx < count && DIM_FROM_HANDLE( ptr[idx] ) == dimension )
[ + + ][ + + ]
693 : : {
694 [ - + ]: 18819 : if( idx % 2 )
695 : : { // only part of first block is of type
696 [ # # ][ # # ]: 0 : in = entity_list.insert( in, FIRST_OF_DIM( dimension ), ptr[idx] );
697 : 0 : ++idx;
698 : : }
699 [ + + ]: 123604 : for( ; idx < count; idx += 2 )
700 : : {
701 [ + - ][ + + ]: 103866 : if( DIM_FROM_HANDLE( ptr[idx + 1] ) == dimension ) // whole block is of type
702 [ + - ]: 101619 : in = entity_list.insert( in, ptr[idx], ptr[idx + 1] );
703 : : else
704 : : {
705 [ + - ][ - + ]: 2247 : if( DIM_FROM_HANDLE( ptr[idx] ) == dimension ) // part of last block is of type
706 [ # # ][ # # ]: 0 : entity_list.insert( in, ptr[idx], LAST_OF_DIM( dimension ) );
707 : 2247 : break;
708 : : }
709 : : }
710 : : }
711 : : }
712 : :
713 : 19982 : return MB_SUCCESS;
714 : : }
715 : :
716 : : //! return the number of entities with the given type contained in this meshset
717 : 72 : inline unsigned int MeshSet::num_entities_by_dimension( int dimension ) const
718 : : {
719 : : unsigned int result;
720 : : size_t count;
721 [ + - ]: 72 : const EntityHandle* ptr = get_contents( count );
722 [ + - ][ + + ]: 72 : if( vector_based() )
723 : : {
724 : : #ifndef __SUNPRO_CC
725 [ + - ][ + - ]: 35 : result = std::count_if( ptr, ptr + count, dim_test( dimension ) );
726 : : #else
727 : : std::count_if( ptr, ptr + count, dim_test( dimension ), result );
728 : : #endif
729 : : }
730 : : else
731 : : {
732 : 37 : result = 0;
733 [ + - ][ + - ]: 37 : size_t idx = std::lower_bound( ptr, ptr + count, FIRST_OF_DIM( dimension ) ) - ptr;
734 [ + + ][ + - ]: 37 : if( idx < count && DIM_FROM_HANDLE( ptr[idx] ) == dimension )
[ + + ][ + + ]
735 : : {
736 [ - + ]: 11 : if( idx % 2 )
737 : : { // only part of first block is of type
738 [ # # ]: 0 : result += ptr[idx] - FIRST_OF_DIM( dimension ) + 1;
739 : 0 : ++idx;
740 : : }
741 [ + + ]: 24 : for( ; idx < count; idx += 2 )
742 : : {
743 [ + - ][ + + ]: 13 : if( DIM_FROM_HANDLE( ptr[idx + 1] ) == dimension ) // whole block is of type
744 : 12 : result += ptr[idx + 1] - ptr[idx] + 1;
745 : : else
746 : : {
747 [ + - ][ - + ]: 1 : if( DIM_FROM_HANDLE( ptr[idx] ) == dimension ) // part of last block is of type
748 [ # # ]: 0 : result += LAST_OF_DIM( dimension ) - ptr[idx] + 1;
749 : 1 : break;
750 : : }
751 : : }
752 : : }
753 : : }
754 : :
755 : 72 : return result;
756 : : }
757 : :
758 : 4372 : inline ErrorCode MeshSet::get_non_set_entities( Range& range ) const
759 : : {
760 : : size_t count;
761 [ + - ]: 4372 : const EntityHandle* ptr = get_contents( count );
762 [ + - ][ + + ]: 4372 : if( vector_based() ) { std::remove_copy_if( ptr, ptr + count, range_inserter( range ), type_test( MBENTITYSET ) ); }
[ + - ][ + - ]
[ + - ]
763 : : else
764 : : {
765 [ + - ]: 4315 : Range::iterator in = range.begin();
766 [ + + ]: 35623 : for( size_t idx = 0; idx < count; idx += 2 )
767 : : {
768 [ + - ][ + + ]: 31308 : if( TYPE_FROM_HANDLE( ptr[idx + 1] ) != MBENTITYSET )
769 [ + - ]: 31243 : in = range.insert( in, ptr[idx], ptr[idx + 1] );
770 : : else
771 : : {
772 [ + - ][ - + ]: 65 : if( TYPE_FROM_HANDLE( ptr[idx] ) != MBENTITYSET )
773 [ # # ][ # # ]: 0 : in = range.insert( in, ptr[idx], LAST_HANDLE( MBENTITYSET - 1 ) );
774 : 65 : break;
775 : : }
776 : : }
777 : : }
778 : :
779 : 4372 : return MB_SUCCESS;
780 : : }
781 : :
782 : 23259 : inline bool MeshSet::contains_entities( const EntityHandle* entities, int num_ents, const int op ) const
783 : : {
784 : : size_t count;
785 [ + - ]: 23259 : const EntityHandle* const ptr = get_contents( count );
786 : 23259 : const EntityHandle* const end = ptr + count;
787 : 23259 : size_t found_count = 0;
788 [ + - ][ + + ]: 23259 : if( vector_based() )
789 : : {
790 [ + + ]: 30 : for( int i = 0; i < num_ents; ++i )
791 [ + - ][ + + ]: 24 : if( std::find( ptr, end, entities[i] ) < end ) ++found_count;
792 : : }
793 : : else
794 : : {
795 [ - + ]: 23253 : assert( 0 == count % 2 );
796 [ + + ]: 46524 : for( int i = 0; i < num_ents; ++i )
797 : : {
798 [ + - ]: 23271 : const unsigned long idx = std::lower_bound( ptr, end, entities[i] ) - ptr;
799 [ + + ][ + + ]: 23271 : if( idx < count && ( idx % 2 != 0 || ptr[idx] == entities[i] ) ) ++found_count;
[ + + ]
800 : : }
801 : : }
802 : :
803 [ + + ]: 23259 : return found_count >= ( ( Interface::INTERSECT == op ) ? (unsigned)num_ents : 1u );
804 : : }
805 : :
806 : : //! subtract/intersect/unite meshset_2 from/with/into meshset_1; modifies meshset_1
807 : 36 : inline ErrorCode MeshSet::subtract( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies )
808 : : {
809 : : size_t count;
810 [ + - ]: 36 : const EntityHandle* const ptr = meshset_2->get_contents( count );
811 [ + - ][ + + ]: 36 : if( meshset_2->vector_based() )
812 [ + - ]: 18 : return remove_entity_vector( ptr, count, my_handle, adjacencies );
813 : : else
814 [ + - ]: 36 : return remove_entity_ranges( ptr, count, my_handle, adjacencies );
815 : : }
816 : :
817 : 39 : inline ErrorCode MeshSet::unite( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies )
818 : : {
819 : : size_t count;
820 [ + - ]: 39 : const EntityHandle* const ptr = meshset_2->get_contents( count );
821 [ + - ][ + + ]: 39 : if( meshset_2->vector_based() )
822 [ + - ]: 19 : return insert_entity_vector( ptr, count, my_handle, adjacencies );
823 : : else
824 [ + - ]: 39 : return insert_entity_ranges( ptr, count, my_handle, adjacencies );
825 : : }
826 : :
827 : : //! add these entities to this meshset
828 : 11574 : inline ErrorCode MeshSet::add_entities( const EntityHandle* entity_handles, const int num_ents, EntityHandle my_handle,
829 : : AEntityFactory* adjacencies )
830 : : {
831 : 11574 : return insert_entity_vector( entity_handles, num_ents, my_handle, adjacencies );
832 : : }
833 : :
834 : : //! add these entities to this meshset
835 : 19052 : inline ErrorCode MeshSet::add_entities( const Range& entities, EntityHandle my_handle, AEntityFactory* adjacencies )
836 : : {
837 : 19052 : return insert_entity_ranges( entities, my_handle, adjacencies );
838 : : }
839 : :
840 : : //! add these entities to this meshset
841 : 198 : inline ErrorCode MeshSet::remove_entities( const Range& entities, EntityHandle my_handle, AEntityFactory* adjacencies )
842 : : {
843 : 198 : return remove_entity_ranges( entities, my_handle, adjacencies );
844 : : }
845 : :
846 : : //! remove these entities from this meshset
847 : 203 : inline ErrorCode MeshSet::remove_entities( const EntityHandle* entities, const int num_ents, EntityHandle my_handle,
848 : : AEntityFactory* adjacencies )
849 : : {
850 : 203 : return remove_entity_vector( entities, num_ents, my_handle, adjacencies );
851 : : }
852 : :
853 : : //! return the number of entities contained in this meshset
854 : 7965 : unsigned int MeshSet::num_entities() const
855 : : {
856 : : size_t count;
857 [ + - ]: 7965 : const EntityHandle* list = get_contents( count );
858 [ + - ][ + + ]: 7965 : if( vector_based() ) return count;
859 : :
860 : 7620 : int result = 0;
861 : 7620 : const EntityHandle* const end = list + count;
862 [ + + ]: 44554 : for( ; list < end; list += 2 )
863 : 36934 : result += list[1] - list[0] + 1;
864 : 7965 : return result;
865 : : }
866 : :
867 : : } // namespace moab
868 : :
869 : : #endif
|