MOAB: Mesh Oriented datABase  (version 5.2.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 <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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines