MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 #ifndef MB_MESHSET_HPP 00002 #define MB_MESHSET_HPP 00003 00004 #ifndef IS_BUILDING_MB 00005 #error "MB_MeshSet.hpp isn't supposed to be included into an application" 00006 #endif 00007 00008 #include "moab/Interface.hpp" 00009 #include "Internals.hpp" 00010 #include "moab/Range.hpp" 00011 #include "moab/CN.hpp" 00012 00013 #include <assert.h> 00014 #include <vector> 00015 #include <algorithm> 00016 #include <iterator> 00017 00018 namespace moab 00019 { 00020 00021 class AEntityFactory; 00022 00023 /** \brief Class to implement entity set functionality 00024 * \author Jason Kraftcheck <kraftche@cae.wisc.edu> 00025 */ 00026 class MeshSet 00027 { 00028 public: 00029 //! create an empty meshset 00030 inline MeshSet(); 00031 inline MeshSet( unsigned flags ); 00032 00033 //! destructor 00034 inline ~MeshSet(); 00035 00036 inline ErrorCode set_flags( unsigned flags, EntityHandle my_handle, AEntityFactory* adjacencies ); 00037 00038 //! get all children pointed to by this meshset 00039 inline const EntityHandle* get_children( int& count_out ) const; 00040 00041 //! get all parents pointed to by this meshset 00042 inline const EntityHandle* get_parents( int& count_out ) const; 00043 00044 //! return the number of children pointed to by this meshset 00045 inline int num_children() const; 00046 00047 //! return the number of parents pointed to by this meshset 00048 inline int num_parents() const; 00049 00050 //! add a parent to this meshset; returns true if parent was added, 0 if it was 00051 //! already a parent of this meshset 00052 int add_parent( EntityHandle parent ); 00053 00054 //! add a child to this meshset; returns true if child was added, 0 if it was 00055 //! already a child of this meshset 00056 int add_child( EntityHandle child ); 00057 00058 //! remove a parent from this meshset; returns true if parent was removed, 0 if it was 00059 //! not a parent of this meshset 00060 int remove_parent( EntityHandle parent ); 00061 00062 //! remove a child from this meshset; returns true if child was removed, 0 if it was 00063 //! not a child of this meshset 00064 int remove_child( EntityHandle child ); 00065 00066 unsigned flags() const 00067 { 00068 return mFlags; 00069 } 00070 //! returns whether entities of meshsets know this meshset 00071 int tracking() const 00072 { 00073 return mFlags & MESHSET_TRACK_OWNER; 00074 } 00075 int set() const 00076 { 00077 return mFlags & MESHSET_SET; 00078 } 00079 int ordered() const 00080 { 00081 return mFlags & MESHSET_ORDERED; 00082 } 00083 int vector_based() const 00084 { 00085 return ordered(); 00086 } 00087 00088 //! replace one entity with another in the set (contents and parent/child 00089 //! lists); returns whether it was replaced or not 00090 ErrorCode replace_entities( EntityHandle my_handle, const EntityHandle* old_entities, 00091 const EntityHandle* new_entities, size_t num_entities, AEntityFactory* mAdjFact ); 00092 00093 /** Clear *contents* of set (not parents or children) */ 00094 inline ErrorCode clear( EntityHandle myhandle, AEntityFactory* adjacencies ); 00095 00096 /** Clear all set lists (contents, parents, and children) */ 00097 inline ErrorCode clear_all( EntityHandle myhandle, AEntityFactory* adjacencies ); 00098 00099 /** Get contents data array. NOTE: this may not contain what you expect if not vector_based */ 00100 inline const EntityHandle* get_contents( size_t& count_out ) const; 00101 /** Get contents data array. NOTE: this may not contain what you expect if not vector_based */ 00102 inline EntityHandle* get_contents( size_t& count_out ); 00103 00104 /** Get entities contained in set */ 00105 inline ErrorCode get_entities( std::vector< EntityHandle >& entities ) const; 00106 00107 /** Get entities contained in set */ 00108 inline ErrorCode get_entities( Range& entities ) const; 00109 00110 //! get all entities in this MeshSet with the specified type 00111 inline ErrorCode get_entities_by_type( EntityType entity_type, std::vector< EntityHandle >& entity_list ) const; 00112 00113 inline ErrorCode get_entities_by_type( EntityType type, Range& entity_list ) const; 00114 00115 //! return the number of entities with the given type contained in this meshset 00116 inline unsigned int num_entities_by_type( EntityType type ) const; 00117 00118 inline ErrorCode get_entities_by_dimension( int dimension, std::vector< EntityHandle >& entity_list ) const; 00119 00120 inline ErrorCode get_entities_by_dimension( int dimension, Range& entity_list ) const; 00121 00122 //! return the number of entities with the given type contained in this meshset 00123 inline unsigned int num_entities_by_dimension( int dimension ) const; 00124 00125 inline ErrorCode get_non_set_entities( Range& range ) const; 00126 00127 /** Test of meshset contains some or all of passed entities 00128 * 00129 *\param entities Array of entities 00130 *\param num_entities Length of array of entities. 00131 *\param op - Interface::UNION : Test if set contains any of the input entities 00132 * - Interface::INTERSECT : Test if set contains all of the input entities 00133 */ 00134 inline bool contains_entities( const EntityHandle* entities, int num_entities, const int op ) const; 00135 00136 //! subtract/intersect/unite meshset_2 from/with/into meshset_1; modifies meshset_1 00137 inline ErrorCode subtract( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies ); 00138 00139 ErrorCode intersect( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies ); 00140 00141 inline ErrorCode unite( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies ); 00142 00143 //! add these entities to this meshset 00144 inline ErrorCode add_entities( const EntityHandle* entity_handles, const int num_entities, EntityHandle my_handle, 00145 AEntityFactory* adjacencies ); 00146 00147 //! add these entities to this meshset 00148 inline ErrorCode add_entities( const Range& entities, EntityHandle my_handle, AEntityFactory* adjacencies ); 00149 00150 //! add these entities to this meshset 00151 inline ErrorCode remove_entities( const Range& entities, EntityHandle my_handle, AEntityFactory* adjacencies ); 00152 00153 //! remove these entities from this meshset 00154 inline ErrorCode remove_entities( const EntityHandle* entities, const int num_entities, EntityHandle my_handle, 00155 AEntityFactory* adjacencies ); 00156 00157 //! return the number of entities contained in this meshset 00158 inline unsigned int num_entities() const; 00159 00160 inline bool empty() const 00161 { 00162 return mContentCount == ZERO; 00163 } 00164 00165 unsigned long get_memory_use() const; 00166 00167 protected: 00168 /** Convert for changing flag values */ 00169 ErrorCode convert( unsigned flags, EntityHandle my_handle, AEntityFactory* adj ); 00170 00171 /** Add explicit adjacencies from all contained entities to this (i.e. convert to tracking) */ 00172 ErrorCode create_adjacencies( EntityHandle myhandle, AEntityFactory* adjacencies ); 00173 00174 /** Remvoe explicit adjacencies from all contained entities to this (i.e. convert from tracking) 00175 */ 00176 ErrorCode remove_adjacencies( EntityHandle myhandle, AEntityFactory* adjacencies ); 00177 00178 /** Insert vector of handles into MeshSet */ 00179 ErrorCode insert_entity_vector( const EntityHandle* vect, size_t len, EntityHandle my_h, AEntityFactory* adj ); 00180 00181 /** Insert vector of handle range pairs into MeshSet */ 00182 ErrorCode insert_entity_ranges( const EntityHandle* range_vect, size_t len, EntityHandle my_h, 00183 AEntityFactory* adj ); 00184 00185 /** Insert Range of handles into MeshSet */ 00186 ErrorCode insert_entity_ranges( const Range& range, EntityHandle my_h, AEntityFactory* adj ); 00187 00188 /** Remove vector of handles from MeshSet */ 00189 ErrorCode remove_entity_vector( const EntityHandle* vect, size_t len, EntityHandle my_h, AEntityFactory* adj ); 00190 00191 /** Remove vector of handle range pairs from MeshSet */ 00192 ErrorCode remove_entity_ranges( const EntityHandle* range_vect, size_t len, EntityHandle my_h, 00193 AEntityFactory* adj ); 00194 00195 /** Remove Range of handles from MeshSet */ 00196 ErrorCode remove_entity_ranges( const Range& range, EntityHandle my_h, AEntityFactory* adj ); 00197 00198 public: 00199 //! Possible values of mParentCount and mChildCount 00200 enum Count 00201 { 00202 ZERO = 0, 00203 ONE = 1, 00204 TWO = 2, 00205 MANY = 3 00206 }; 00207 //! If the number of entities is less than 3, store 00208 //! the handles directly in the hnd member. Otherwise 00209 //! use the ptr member to hold the beginning and end 00210 //! of a dynamically allocated array. 00211 union CompactList 00212 { 00213 EntityHandle hnd[2]; //!< Two handles 00214 EntityHandle* ptr[2]; //!< begin and end pointers for array 00215 }; 00216 00217 private: 00218 //! Meshset propery flags 00219 unsigned char mFlags; 00220 //! If less than MANY, the number of parents stored inline in 00221 //! parentMeshSets.hnd. If MANY, then parentMeshSets.ptr contains 00222 //! array begin and end pointers for a dynamically allocated array 00223 //! of parent handles. 00224 unsigned mParentCount : 2; 00225 //! If less than MANY, the number of children stored inline in 00226 //! childMeshSets.hnd. If MANY, then childMeshSets.ptr contains 00227 //! array begin and end pointers for a dynamically allocated array 00228 //! of child handles. 00229 unsigned mChildCount : 2; 00230 //! If less than MANY, the number of children stored inline in 00231 //! contentList.hnd. If MANY, then contentList.ptr contains 00232 //! array begin and end pointers for a dynamically allocated array.. 00233 unsigned mContentCount : 2; 00234 //! Storage for data lists 00235 CompactList parentMeshSets, childMeshSets, contentList; 00236 00237 public: 00238 /** get dimension of enity */ 00239 static inline int DIM_FROM_HANDLE( EntityHandle h ) 00240 { 00241 return CN::Dimension( TYPE_FROM_HANDLE( h ) ); 00242 } 00243 00244 /** Get smallest possible handle with specified dimension (first handle for first type of 00245 * dimension) */ 00246 static inline EntityHandle FIRST_OF_DIM( int dim ) 00247 { 00248 return FIRST_HANDLE( CN::TypeDimensionMap[dim].first ); 00249 } 00250 00251 /** Get largest possible handle with specified dimension (largest handle for last type of 00252 * dimension) */ 00253 static inline EntityHandle LAST_OF_DIM( int dim ) 00254 { 00255 return LAST_HANDLE( CN::TypeDimensionMap[dim].second ); 00256 } 00257 00258 /** functor: test if handle is not of type */ 00259 struct not_type_test 00260 { 00261 inline not_type_test( EntityType type ) : mType( type ) {} 00262 inline bool operator()( EntityHandle handle ) 00263 { 00264 return TYPE_FROM_HANDLE( handle ) != mType; 00265 } 00266 EntityType mType; 00267 }; 00268 00269 /** functor: test if handle is of type */ 00270 struct type_test 00271 { 00272 inline type_test( EntityType type ) : mType( type ) {} 00273 inline bool operator()( EntityHandle handle ) 00274 { 00275 return TYPE_FROM_HANDLE( handle ) == mType; 00276 } 00277 EntityType mType; 00278 }; 00279 00280 /** functor: test if handle is not of dimension */ 00281 struct not_dim_test 00282 { 00283 inline not_dim_test( int dimension ) : mDim( dimension ) {} 00284 inline bool operator()( EntityHandle handle ) const 00285 { 00286 return DIM_FROM_HANDLE( handle ) != mDim; 00287 } 00288 int mDim; 00289 }; 00290 00291 /** functor: test if handle is of dimension */ 00292 struct dim_test 00293 { 00294 inline dim_test( int dimension ) : mDim( dimension ) {} 00295 inline bool operator()( EntityHandle handle ) const 00296 { 00297 return DIM_FROM_HANDLE( handle ) == mDim; 00298 } 00299 int mDim; 00300 }; 00301 00302 /** Iterate over range of handles. That is, given [first_handle,last_handle], 00303 * step through all contained values. 00304 */ 00305 struct hdl_iter 00306 { 00307 EntityHandle h; 00308 hdl_iter( EntityHandle val ) : h( val ) {} 00309 hdl_iter& operator++() 00310 { 00311 ++h; 00312 return *this; 00313 } 00314 hdl_iter& operator--() 00315 { 00316 --h; 00317 return *this; 00318 } 00319 hdl_iter operator++( int ) 00320 { 00321 return hdl_iter( h++ ); 00322 } 00323 hdl_iter operator--( int ) 00324 { 00325 return hdl_iter( h-- ); 00326 } 00327 hdl_iter& operator+=( size_t s ) 00328 { 00329 h += s; 00330 return *this; 00331 } 00332 hdl_iter& operator-=( size_t s ) 00333 { 00334 h -= s; 00335 return *this; 00336 } 00337 EntityHandle operator*() const 00338 { 00339 return h; 00340 } 00341 bool operator==( hdl_iter other ) const 00342 { 00343 return h == other.h; 00344 } 00345 bool operator!=( hdl_iter other ) const 00346 { 00347 return h != other.h; 00348 } 00349 bool operator<( hdl_iter other ) const 00350 { 00351 return h < other.h; 00352 } 00353 bool operator>( hdl_iter other ) const 00354 { 00355 return h > other.h; 00356 } 00357 bool operator<=( hdl_iter other ) const 00358 { 00359 return h <= other.h; 00360 } 00361 bool operator>=( hdl_iter other ) const 00362 { 00363 return h >= other.h; 00364 } 00365 00366 struct iterator_category : public std::random_access_iterator_tag 00367 { 00368 }; 00369 typedef EntityID difference_type; 00370 typedef EntityHandle value_type; 00371 typedef EntityHandle* pointer; 00372 typedef EntityHandle& reference; 00373 }; 00374 }; 00375 00376 inline MeshSet::hdl_iter::difference_type operator-( const MeshSet::hdl_iter& a, const MeshSet::hdl_iter& b ) 00377 { 00378 return (MeshSet::hdl_iter::difference_type)a.h - (MeshSet::hdl_iter::difference_type)b.h; 00379 } 00380 00381 //! create an empty meshset 00382 MeshSet::MeshSet() : mFlags( 0 ), mParentCount( ZERO ), mChildCount( ZERO ), mContentCount( ZERO ) {} 00383 00384 //! create an empty meshset 00385 MeshSet::MeshSet( unsigned flg ) 00386 : mFlags( (unsigned char)flg ), mParentCount( ZERO ), mChildCount( ZERO ), mContentCount( ZERO ) 00387 { 00388 } 00389 00390 //! destructor 00391 MeshSet::~MeshSet() 00392 { 00393 if( mChildCount == MANY ) free( childMeshSets.ptr[0] ); 00394 if( mParentCount == MANY ) free( parentMeshSets.ptr[0] ); 00395 if( mContentCount == MANY ) free( contentList.ptr[0] ); 00396 mChildCount = mParentCount = mContentCount = ZERO; 00397 } 00398 00399 ErrorCode MeshSet::set_flags( unsigned flg, EntityHandle my_handle, AEntityFactory* adjacencies ) 00400 { 00401 if( ZERO != mContentCount ) 00402 { 00403 ErrorCode result = convert( flg, my_handle, adjacencies ); 00404 if( MB_SUCCESS != result ) return result; 00405 } 00406 mFlags = (unsigned char)flg; 00407 return MB_SUCCESS; 00408 } 00409 00410 //! get all children pointed to by this meshset 00411 const EntityHandle* MeshSet::get_children( int& count_out ) const 00412 { 00413 count_out = mChildCount; 00414 if( count_out < MANY ) return childMeshSets.hnd; 00415 00416 count_out = childMeshSets.ptr[1] - childMeshSets.ptr[0]; 00417 return childMeshSets.ptr[0]; 00418 } 00419 00420 //! get all parents pointed to by this meshset 00421 const EntityHandle* MeshSet::get_parents( int& count_out ) const 00422 { 00423 count_out = mParentCount; 00424 if( count_out < MANY ) return parentMeshSets.hnd; 00425 00426 count_out = parentMeshSets.ptr[1] - parentMeshSets.ptr[0]; 00427 return parentMeshSets.ptr[0]; 00428 } 00429 00430 //! return the number of children pointed to by this meshset 00431 int MeshSet::num_children() const 00432 { 00433 if( mChildCount < MANY ) 00434 return mChildCount; 00435 else 00436 return childMeshSets.ptr[1] - childMeshSets.ptr[0]; 00437 } 00438 00439 //! return the number of parents pointed to by this meshset 00440 int MeshSet::num_parents() const 00441 { 00442 if( mParentCount < MANY ) 00443 return mParentCount; 00444 else 00445 return parentMeshSets.ptr[1] - parentMeshSets.ptr[0]; 00446 } 00447 00448 inline ErrorCode MeshSet::clear( EntityHandle myhandle, AEntityFactory* adjacencies ) 00449 { 00450 if( tracking() ) remove_adjacencies( myhandle, adjacencies ); 00451 if( mContentCount == MANY ) free( contentList.ptr[0] ); 00452 mContentCount = ZERO; 00453 return MB_SUCCESS; 00454 } 00455 00456 inline ErrorCode MeshSet::clear_all( EntityHandle myhandle, AEntityFactory* adjacencies ) 00457 { 00458 ErrorCode rval = clear( myhandle, adjacencies ); 00459 if( mChildCount == MANY ) free( childMeshSets.ptr[0] ); 00460 mChildCount = ZERO; 00461 if( mParentCount == MANY ) free( parentMeshSets.ptr[0] ); 00462 mParentCount = ZERO; 00463 return rval; 00464 } 00465 00466 inline const EntityHandle* MeshSet::get_contents( size_t& count_out ) const 00467 { 00468 if( mContentCount == MANY ) 00469 { 00470 count_out = contentList.ptr[1] - contentList.ptr[0]; 00471 return contentList.ptr[0]; 00472 } 00473 else 00474 { 00475 count_out = mContentCount; 00476 return contentList.hnd; 00477 } 00478 } 00479 00480 inline EntityHandle* MeshSet::get_contents( size_t& count_out ) 00481 { 00482 if( mContentCount == MANY ) 00483 { 00484 count_out = contentList.ptr[1] - contentList.ptr[0]; 00485 return contentList.ptr[0]; 00486 } 00487 else 00488 { 00489 count_out = mContentCount; 00490 return contentList.hnd; 00491 } 00492 } 00493 00494 inline ErrorCode MeshSet::get_entities( std::vector< EntityHandle >& entities ) const 00495 { 00496 size_t count; 00497 const EntityHandle* ptr = get_contents( count ); 00498 if( vector_based() ) 00499 { 00500 size_t old_size = entities.size(); 00501 entities.resize( count + old_size ); 00502 std::copy( ptr, ptr + count, entities.begin() + old_size ); 00503 } 00504 else 00505 { 00506 assert( count % 2 == 0 ); 00507 for( size_t i = 0; i < count; i += 2 ) 00508 std::copy( hdl_iter( ptr[i] ), hdl_iter( ptr[i + 1] + 1 ), std::back_inserter( entities ) ); 00509 } 00510 return MB_SUCCESS; 00511 } 00512 00513 inline ErrorCode MeshSet::get_entities( Range& entities ) const 00514 { 00515 size_t count; 00516 const EntityHandle* ptr = get_contents( count ); 00517 if( vector_based() ) { std::copy( ptr, ptr + count, range_inserter( entities ) ); } 00518 else 00519 { 00520 assert( count % 2 == 0 ); 00521 Range::iterator in = entities.begin(); 00522 for( size_t i = 0; i < count; i += 2 ) 00523 in = entities.insert( in, ptr[i], ptr[i + 1] ); 00524 } 00525 return MB_SUCCESS; 00526 } 00527 00528 //! get all entities in this MeshSet with the specified type 00529 inline ErrorCode MeshSet::get_entities_by_type( EntityType type, std::vector< EntityHandle >& entity_list ) const 00530 { 00531 size_t count; 00532 const EntityHandle* ptr = get_contents( count ); 00533 if( MBMAXTYPE == type ) { return get_entities( entity_list ); } 00534 else if( vector_based() ) 00535 { 00536 std::remove_copy_if( ptr, ptr + count, std::back_inserter( entity_list ), not_type_test( type ) ); 00537 } 00538 else 00539 { 00540 size_t idx = std::lower_bound( ptr, ptr + count, FIRST_HANDLE( type ) ) - ptr; 00541 if( idx < count && TYPE_FROM_HANDLE( ptr[idx] ) == type ) 00542 { 00543 if( idx % 2 ) 00544 { // only part of first block is of type 00545 std::copy( hdl_iter( FIRST_HANDLE( type ) ), hdl_iter( ptr[idx] + 1 ), 00546 std::back_inserter( entity_list ) ); 00547 ++idx; 00548 } 00549 for( ; idx < count; idx += 2 ) 00550 { 00551 if( TYPE_FROM_HANDLE( ptr[idx + 1] ) == type ) // whole block is of type 00552 std::copy( hdl_iter( ptr[idx] ), hdl_iter( ptr[idx + 1] + 1 ), std::back_inserter( entity_list ) ); 00553 else 00554 { 00555 if( TYPE_FROM_HANDLE( ptr[idx] ) == type ) // part of last block is of type 00556 std::copy( hdl_iter( ptr[idx] ), hdl_iter( LAST_HANDLE( type ) ), 00557 std::back_inserter( entity_list ) ); 00558 break; 00559 } 00560 } 00561 } 00562 } 00563 00564 return MB_SUCCESS; 00565 } 00566 00567 inline ErrorCode MeshSet::get_entities_by_type( EntityType type, Range& entity_list ) const 00568 { 00569 size_t count; 00570 const EntityHandle* ptr = get_contents( count ); 00571 if( MBMAXTYPE == type ) { return get_entities( entity_list ); } 00572 else if( vector_based() ) 00573 { 00574 std::remove_copy_if( ptr, ptr + count, range_inserter( entity_list ), not_type_test( type ) ); 00575 } 00576 else 00577 { 00578 size_t idx = std::lower_bound( ptr, ptr + count, FIRST_HANDLE( type ) ) - ptr; 00579 Range::iterator in = entity_list.begin(); 00580 if( idx < count && TYPE_FROM_HANDLE( ptr[idx] ) == type ) 00581 { 00582 if( idx % 2 ) 00583 { // only part of first block is of type 00584 in = entity_list.insert( in, FIRST_HANDLE( type ), ptr[idx] ); 00585 ++idx; 00586 } 00587 for( ; idx < count; idx += 2 ) 00588 { 00589 if( TYPE_FROM_HANDLE( ptr[idx + 1] ) == type ) // whole block is of type 00590 in = entity_list.insert( in, ptr[idx], ptr[idx + 1] ); 00591 else 00592 { 00593 if( TYPE_FROM_HANDLE( ptr[idx] ) == type ) // part of last block is of type 00594 entity_list.insert( in, ptr[idx], LAST_HANDLE( type ) ); 00595 break; 00596 } 00597 } 00598 } 00599 } 00600 00601 return MB_SUCCESS; 00602 } 00603 00604 //! return the number of entities with the given type contained in this meshset 00605 inline unsigned int MeshSet::num_entities_by_type( EntityType type ) const 00606 { 00607 unsigned int result; 00608 size_t count; 00609 const EntityHandle* ptr = get_contents( count ); 00610 if( MBMAXTYPE == type ) { return num_entities(); } 00611 else if( vector_based() ) 00612 { 00613 #ifndef __SUNPRO_CC 00614 result = std::count_if( ptr, ptr + count, type_test( type ) ); 00615 #else 00616 std::count_if( ptr, ptr + count, type_test( type ), result ); 00617 #endif 00618 } 00619 else 00620 { 00621 result = 0; 00622 size_t idx = std::lower_bound( ptr, ptr + count, FIRST_HANDLE( type ) ) - ptr; 00623 if( idx < count && TYPE_FROM_HANDLE( ptr[idx] ) == type ) 00624 { 00625 if( idx % 2 ) 00626 { // only part of first block is of type 00627 result += ptr[idx] - FIRST_HANDLE( type ) + 1; 00628 ++idx; 00629 } 00630 for( ; idx < count; idx += 2 ) 00631 { 00632 if( TYPE_FROM_HANDLE( ptr[idx + 1] ) == type ) // whole block is of type 00633 result += ptr[idx + 1] - ptr[idx] + 1; 00634 else 00635 { 00636 if( TYPE_FROM_HANDLE( ptr[idx] ) == type ) // part of last block is of type 00637 result += LAST_HANDLE( type ) - ptr[idx] + 1; 00638 break; 00639 } 00640 } 00641 } 00642 } 00643 00644 return result; 00645 } 00646 00647 inline ErrorCode MeshSet::get_entities_by_dimension( int dimension, std::vector< EntityHandle >& entity_list ) const 00648 { 00649 size_t count; 00650 const EntityHandle* ptr = get_contents( count ); 00651 if( vector_based() ) 00652 { std::remove_copy_if( ptr, ptr + count, std::back_inserter( entity_list ), not_dim_test( dimension ) ); } 00653 else 00654 { 00655 size_t idx = std::lower_bound( ptr, ptr + count, FIRST_OF_DIM( dimension ) ) - ptr; 00656 if( idx < count && DIM_FROM_HANDLE( ptr[idx] ) == dimension ) 00657 { 00658 if( idx % 2 ) 00659 { // only part of first block is of type 00660 std::copy( hdl_iter( FIRST_OF_DIM( dimension ) ), hdl_iter( ptr[idx] + 1 ), 00661 std::back_inserter( entity_list ) ); 00662 ++idx; 00663 } 00664 for( ; idx < count; idx += 2 ) 00665 { 00666 if( DIM_FROM_HANDLE( ptr[idx + 1] ) == dimension ) // whole block is of type 00667 std::copy( hdl_iter( ptr[idx] ), hdl_iter( ptr[idx + 1] + 1 ), std::back_inserter( entity_list ) ); 00668 else 00669 { 00670 if( DIM_FROM_HANDLE( ptr[idx] ) == dimension ) // part of last block is of type 00671 std::copy( hdl_iter( ptr[idx] ), hdl_iter( LAST_OF_DIM( dimension ) ), 00672 std::back_inserter( entity_list ) ); 00673 break; 00674 } 00675 } 00676 } 00677 } 00678 00679 return MB_SUCCESS; 00680 } 00681 00682 inline ErrorCode MeshSet::get_entities_by_dimension( int dimension, Range& entity_list ) const 00683 { 00684 size_t count; 00685 const EntityHandle* ptr = get_contents( count ); 00686 if( vector_based() ) 00687 { std::remove_copy_if( ptr, ptr + count, range_inserter( entity_list ), not_dim_test( dimension ) ); } 00688 else 00689 { 00690 size_t idx = std::lower_bound( ptr, ptr + count, FIRST_OF_DIM( dimension ) ) - ptr; 00691 Range::iterator in = entity_list.begin(); 00692 if( idx < count && DIM_FROM_HANDLE( ptr[idx] ) == dimension ) 00693 { 00694 if( idx % 2 ) 00695 { // only part of first block is of type 00696 in = entity_list.insert( in, FIRST_OF_DIM( dimension ), ptr[idx] ); 00697 ++idx; 00698 } 00699 for( ; idx < count; idx += 2 ) 00700 { 00701 if( DIM_FROM_HANDLE( ptr[idx + 1] ) == dimension ) // whole block is of type 00702 in = entity_list.insert( in, ptr[idx], ptr[idx + 1] ); 00703 else 00704 { 00705 if( DIM_FROM_HANDLE( ptr[idx] ) == dimension ) // part of last block is of type 00706 entity_list.insert( in, ptr[idx], LAST_OF_DIM( dimension ) ); 00707 break; 00708 } 00709 } 00710 } 00711 } 00712 00713 return MB_SUCCESS; 00714 } 00715 00716 //! return the number of entities with the given type contained in this meshset 00717 inline unsigned int MeshSet::num_entities_by_dimension( int dimension ) const 00718 { 00719 unsigned int result; 00720 size_t count; 00721 const EntityHandle* ptr = get_contents( count ); 00722 if( vector_based() ) 00723 { 00724 #ifndef __SUNPRO_CC 00725 result = std::count_if( ptr, ptr + count, dim_test( dimension ) ); 00726 #else 00727 std::count_if( ptr, ptr + count, dim_test( dimension ), result ); 00728 #endif 00729 } 00730 else 00731 { 00732 result = 0; 00733 size_t idx = std::lower_bound( ptr, ptr + count, FIRST_OF_DIM( dimension ) ) - ptr; 00734 if( idx < count && DIM_FROM_HANDLE( ptr[idx] ) == dimension ) 00735 { 00736 if( idx % 2 ) 00737 { // only part of first block is of type 00738 result += ptr[idx] - FIRST_OF_DIM( dimension ) + 1; 00739 ++idx; 00740 } 00741 for( ; idx < count; idx += 2 ) 00742 { 00743 if( DIM_FROM_HANDLE( ptr[idx + 1] ) == dimension ) // whole block is of type 00744 result += ptr[idx + 1] - ptr[idx] + 1; 00745 else 00746 { 00747 if( DIM_FROM_HANDLE( ptr[idx] ) == dimension ) // part of last block is of type 00748 result += LAST_OF_DIM( dimension ) - ptr[idx] + 1; 00749 break; 00750 } 00751 } 00752 } 00753 } 00754 00755 return result; 00756 } 00757 00758 inline ErrorCode MeshSet::get_non_set_entities( Range& range ) const 00759 { 00760 size_t count; 00761 const EntityHandle* ptr = get_contents( count ); 00762 if( vector_based() ) { std::remove_copy_if( ptr, ptr + count, range_inserter( range ), type_test( MBENTITYSET ) ); } 00763 else 00764 { 00765 Range::iterator in = range.begin(); 00766 for( size_t idx = 0; idx < count; idx += 2 ) 00767 { 00768 if( TYPE_FROM_HANDLE( ptr[idx + 1] ) != MBENTITYSET ) 00769 in = range.insert( in, ptr[idx], ptr[idx + 1] ); 00770 else 00771 { 00772 if( TYPE_FROM_HANDLE( ptr[idx] ) != MBENTITYSET ) 00773 in = range.insert( in, ptr[idx], LAST_HANDLE( MBENTITYSET - 1 ) ); 00774 break; 00775 } 00776 } 00777 } 00778 00779 return MB_SUCCESS; 00780 } 00781 00782 inline bool MeshSet::contains_entities( const EntityHandle* entities, int num_ents, const int op ) const 00783 { 00784 size_t count; 00785 const EntityHandle* const ptr = get_contents( count ); 00786 const EntityHandle* const end = ptr + count; 00787 size_t found_count = 0; 00788 if( vector_based() ) 00789 { 00790 for( int i = 0; i < num_ents; ++i ) 00791 if( std::find( ptr, end, entities[i] ) < end ) ++found_count; 00792 } 00793 else 00794 { 00795 assert( 0 == count % 2 ); 00796 for( int i = 0; i < num_ents; ++i ) 00797 { 00798 const unsigned long idx = std::lower_bound( ptr, end, entities[i] ) - ptr; 00799 if( idx < count && ( idx % 2 != 0 || ptr[idx] == entities[i] ) ) ++found_count; 00800 } 00801 } 00802 00803 return found_count >= ( ( Interface::INTERSECT == op ) ? (unsigned)num_ents : 1u ); 00804 } 00805 00806 //! subtract/intersect/unite meshset_2 from/with/into meshset_1; modifies meshset_1 00807 inline ErrorCode MeshSet::subtract( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies ) 00808 { 00809 size_t count; 00810 const EntityHandle* const ptr = meshset_2->get_contents( count ); 00811 if( meshset_2->vector_based() ) 00812 return remove_entity_vector( ptr, count, my_handle, adjacencies ); 00813 else 00814 return remove_entity_ranges( ptr, count, my_handle, adjacencies ); 00815 } 00816 00817 inline ErrorCode MeshSet::unite( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies ) 00818 { 00819 size_t count; 00820 const EntityHandle* const ptr = meshset_2->get_contents( count ); 00821 if( meshset_2->vector_based() ) 00822 return insert_entity_vector( ptr, count, my_handle, adjacencies ); 00823 else 00824 return insert_entity_ranges( ptr, count, my_handle, adjacencies ); 00825 } 00826 00827 //! add these entities to this meshset 00828 inline ErrorCode MeshSet::add_entities( const EntityHandle* entity_handles, const int num_ents, EntityHandle my_handle, 00829 AEntityFactory* adjacencies ) 00830 { 00831 return insert_entity_vector( entity_handles, num_ents, my_handle, adjacencies ); 00832 } 00833 00834 //! add these entities to this meshset 00835 inline ErrorCode MeshSet::add_entities( const Range& entities, EntityHandle my_handle, AEntityFactory* adjacencies ) 00836 { 00837 return insert_entity_ranges( entities, my_handle, adjacencies ); 00838 } 00839 00840 //! add these entities to this meshset 00841 inline ErrorCode MeshSet::remove_entities( const Range& entities, EntityHandle my_handle, AEntityFactory* adjacencies ) 00842 { 00843 return remove_entity_ranges( entities, my_handle, adjacencies ); 00844 } 00845 00846 //! remove these entities from this meshset 00847 inline ErrorCode MeshSet::remove_entities( const EntityHandle* entities, const int num_ents, EntityHandle my_handle, 00848 AEntityFactory* adjacencies ) 00849 { 00850 return remove_entity_vector( entities, num_ents, my_handle, adjacencies ); 00851 } 00852 00853 //! return the number of entities contained in this meshset 00854 unsigned int MeshSet::num_entities() const 00855 { 00856 size_t count; 00857 const EntityHandle* list = get_contents( count ); 00858 if( vector_based() ) return count; 00859 00860 int result = 0; 00861 const EntityHandle* const end = list + count; 00862 for( ; list < end; list += 2 ) 00863 result += list[1] - list[0] + 1; 00864 return result; 00865 } 00866 00867 } // namespace moab 00868 00869 #endif