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