MOAB: Mesh Oriented datABase  (version 5.4.1)
MeshSet.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines