MOAB: Mesh Oriented datABase  (version 5.3.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 <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     {
00653         std::remove_copy_if( ptr, ptr + count, std::back_inserter( entity_list ), not_dim_test( dimension ) );
00654     }
00655     else
00656     {
00657         size_t idx = std::lower_bound( ptr, ptr + count, FIRST_OF_DIM( dimension ) ) - ptr;
00658         if( idx < count && DIM_FROM_HANDLE( ptr[idx] ) == dimension )
00659         {
00660             if( idx % 2 )
00661             {  // only part of first block is of type
00662                 std::copy( hdl_iter( FIRST_OF_DIM( dimension ) ), hdl_iter( ptr[idx] + 1 ),
00663                            std::back_inserter( entity_list ) );
00664                 ++idx;
00665             }
00666             for( ; idx < count; idx += 2 )
00667             {
00668                 if( DIM_FROM_HANDLE( ptr[idx + 1] ) == dimension )  // whole block is of type
00669                     std::copy( hdl_iter( ptr[idx] ), hdl_iter( ptr[idx + 1] + 1 ), std::back_inserter( entity_list ) );
00670                 else
00671                 {
00672                     if( DIM_FROM_HANDLE( ptr[idx] ) == dimension )  // part of last block is of type
00673                         std::copy( hdl_iter( ptr[idx] ), hdl_iter( LAST_OF_DIM( dimension ) ),
00674                                    std::back_inserter( entity_list ) );
00675                     break;
00676                 }
00677             }
00678         }
00679     }
00680 
00681     return MB_SUCCESS;
00682 }
00683 
00684 inline ErrorCode MeshSet::get_entities_by_dimension( int dimension, Range& entity_list ) const
00685 {
00686     size_t count;
00687     const EntityHandle* ptr = get_contents( count );
00688     if( vector_based() )
00689     {
00690         std::remove_copy_if( ptr, ptr + count, range_inserter( entity_list ), not_dim_test( dimension ) );
00691     }
00692     else
00693     {
00694         size_t idx         = std::lower_bound( ptr, ptr + count, FIRST_OF_DIM( dimension ) ) - ptr;
00695         Range::iterator in = entity_list.begin();
00696         if( idx < count && DIM_FROM_HANDLE( ptr[idx] ) == dimension )
00697         {
00698             if( idx % 2 )
00699             {  // only part of first block is of type
00700                 in = entity_list.insert( in, FIRST_OF_DIM( dimension ), ptr[idx] );
00701                 ++idx;
00702             }
00703             for( ; idx < count; idx += 2 )
00704             {
00705                 if( DIM_FROM_HANDLE( ptr[idx + 1] ) == dimension )  // whole block is of type
00706                     in = entity_list.insert( in, ptr[idx], ptr[idx + 1] );
00707                 else
00708                 {
00709                     if( DIM_FROM_HANDLE( ptr[idx] ) == dimension )  // part of last block is of type
00710                         entity_list.insert( in, ptr[idx], LAST_OF_DIM( dimension ) );
00711                     break;
00712                 }
00713             }
00714         }
00715     }
00716 
00717     return MB_SUCCESS;
00718 }
00719 
00720 //! return the number of entities with the given type contained in this meshset
00721 inline unsigned int MeshSet::num_entities_by_dimension( int dimension ) const
00722 {
00723     unsigned int result;
00724     size_t count;
00725     const EntityHandle* ptr = get_contents( count );
00726     if( vector_based() )
00727     {
00728 #ifndef __SUNPRO_CC
00729         result = std::count_if( ptr, ptr + count, dim_test( dimension ) );
00730 #else
00731         std::count_if( ptr, ptr + count, dim_test( dimension ), result );
00732 #endif
00733     }
00734     else
00735     {
00736         result     = 0;
00737         size_t idx = std::lower_bound( ptr, ptr + count, FIRST_OF_DIM( dimension ) ) - ptr;
00738         if( idx < count && DIM_FROM_HANDLE( ptr[idx] ) == dimension )
00739         {
00740             if( idx % 2 )
00741             {  // only part of first block is of type
00742                 result += ptr[idx] - FIRST_OF_DIM( dimension ) + 1;
00743                 ++idx;
00744             }
00745             for( ; idx < count; idx += 2 )
00746             {
00747                 if( DIM_FROM_HANDLE( ptr[idx + 1] ) == dimension )  // whole block is of type
00748                     result += ptr[idx + 1] - ptr[idx] + 1;
00749                 else
00750                 {
00751                     if( DIM_FROM_HANDLE( ptr[idx] ) == dimension )  // part of last block is of type
00752                         result += LAST_OF_DIM( dimension ) - ptr[idx] + 1;
00753                     break;
00754                 }
00755             }
00756         }
00757     }
00758 
00759     return result;
00760 }
00761 
00762 inline ErrorCode MeshSet::get_non_set_entities( Range& range ) const
00763 {
00764     size_t count;
00765     const EntityHandle* ptr = get_contents( count );
00766     if( vector_based() ) { std::remove_copy_if( ptr, ptr + count, range_inserter( range ), type_test( MBENTITYSET ) ); }
00767     else
00768     {
00769         Range::iterator in = range.begin();
00770         for( size_t idx = 0; idx < count; idx += 2 )
00771         {
00772             if( TYPE_FROM_HANDLE( ptr[idx + 1] ) != MBENTITYSET )
00773                 in = range.insert( in, ptr[idx], ptr[idx + 1] );
00774             else
00775             {
00776                 if( TYPE_FROM_HANDLE( ptr[idx] ) != MBENTITYSET )
00777                     in = range.insert( in, ptr[idx], LAST_HANDLE( MBENTITYSET - 1 ) );
00778                 break;
00779             }
00780         }
00781     }
00782 
00783     return MB_SUCCESS;
00784 }
00785 
00786 inline bool MeshSet::contains_entities( const EntityHandle* entities, int num_ents, const int op ) const
00787 {
00788     size_t count;
00789     const EntityHandle* const ptr = get_contents( count );
00790     const EntityHandle* const end = ptr + count;
00791     size_t found_count            = 0;
00792     if( vector_based() )
00793     {
00794         for( int i = 0; i < num_ents; ++i )
00795             if( std::find( ptr, end, entities[i] ) < end ) ++found_count;
00796     }
00797     else
00798     {
00799         assert( 0 == count % 2 );
00800         for( int i = 0; i < num_ents; ++i )
00801         {
00802             const unsigned long idx = std::lower_bound( ptr, end, entities[i] ) - ptr;
00803             if( idx < count && ( idx % 2 != 0 || ptr[idx] == entities[i] ) ) ++found_count;
00804         }
00805     }
00806 
00807     return found_count >= ( ( Interface::INTERSECT == op ) ? (unsigned)num_ents : 1u );
00808 }
00809 
00810 //! subtract/intersect/unite meshset_2 from/with/into meshset_1; modifies meshset_1
00811 inline ErrorCode MeshSet::subtract( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies )
00812 {
00813     size_t count;
00814     const EntityHandle* const ptr = meshset_2->get_contents( count );
00815     if( meshset_2->vector_based() )
00816         return remove_entity_vector( ptr, count, my_handle, adjacencies );
00817     else
00818         return remove_entity_ranges( ptr, count, my_handle, adjacencies );
00819 }
00820 
00821 inline ErrorCode MeshSet::unite( const MeshSet* meshset_2, EntityHandle my_handle, AEntityFactory* adjacencies )
00822 {
00823     size_t count;
00824     const EntityHandle* const ptr = meshset_2->get_contents( count );
00825     if( meshset_2->vector_based() )
00826         return insert_entity_vector( ptr, count, my_handle, adjacencies );
00827     else
00828         return insert_entity_ranges( ptr, count, my_handle, adjacencies );
00829 }
00830 
00831 //! add these entities to this meshset
00832 inline ErrorCode MeshSet::add_entities( const EntityHandle* entity_handles, const int num_ents, EntityHandle my_handle,
00833                                         AEntityFactory* adjacencies )
00834 {
00835     return insert_entity_vector( entity_handles, num_ents, my_handle, adjacencies );
00836 }
00837 
00838 //! add these entities to this meshset
00839 inline ErrorCode MeshSet::add_entities( const Range& entities, EntityHandle my_handle, AEntityFactory* adjacencies )
00840 {
00841     return insert_entity_ranges( entities, my_handle, adjacencies );
00842 }
00843 
00844 //! add these entities to this meshset
00845 inline ErrorCode MeshSet::remove_entities( const Range& entities, EntityHandle my_handle, AEntityFactory* adjacencies )
00846 {
00847     return remove_entity_ranges( entities, my_handle, adjacencies );
00848 }
00849 
00850 //! remove these entities from this meshset
00851 inline ErrorCode MeshSet::remove_entities( const EntityHandle* entities, const int num_ents, EntityHandle my_handle,
00852                                            AEntityFactory* adjacencies )
00853 {
00854     return remove_entity_vector( entities, num_ents, my_handle, adjacencies );
00855 }
00856 
00857 //! return the number of entities contained in this meshset
00858 unsigned int MeshSet::num_entities() const
00859 {
00860     size_t count;
00861     const EntityHandle* list = get_contents( count );
00862     if( vector_based() ) return count;
00863 
00864     int result                    = 0;
00865     const EntityHandle* const end = list + count;
00866     for( ; list < end; list += 2 )
00867         result += list[1] - list[0] + 1;
00868     return result;
00869 }
00870 
00871 }  // namespace moab
00872 
00873 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines