Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
MBIter.hpp
Go to the documentation of this file.
00001 #ifndef MOAB_MB_ITER_HPP
00002 #define MOAB_MB_ITER_HPP
00003 
00004 #define IS_BUILDING_MB
00005 #include "Internals.hpp"
00006 #include "moab/Range.hpp"
00007 #include "moab/Core.hpp"
00008 #include <vector>
00009 #include <algorithm>
00010 
00011 struct iBase_EntityArrIterator_Private
00012 {
00013   protected:
00014     iBase_EntityType entType;
00015     iMesh_EntityTopology entTopo;
00016     EntityHandle entSet;
00017     int arrSize;
00018     bool isRecursive;
00019 
00020   public:
00021     iBase_EntityArrIterator_Private( iBase_EntityType type,
00022                                      iMesh_EntityTopology topology,
00023                                      EntityHandle set,
00024                                      int array_sz,
00025                                      bool recursive = false )
00026         : entType( type ), entTopo( topology ), entSet( set ), arrSize( array_sz ), isRecursive( recursive )
00027     {
00028     }
00029 
00030     virtual ~iBase_EntityArrIterator_Private() {}
00031 
00032     int array_size() const
00033     {
00034         return arrSize;
00035     }
00036 
00037     virtual ErrorCode step( int num_steps, bool& at_end ) = 0;
00038 
00039     // NOTE: input array must be at least arrLen long
00040     virtual void get_entities( Core* mb, EntityHandle* array, int& count_out ) = 0;
00041 
00042     virtual ErrorCode reset( Interface* mb ) = 0;
00043 
00044     class IsType
00045     {
00046       private:
00047         EntityType type;
00048 
00049       public:
00050         IsType( EntityType t ) : type( t ) {}
00051         bool operator()( EntityHandle h )
00052         {
00053             return TYPE_FROM_HANDLE( h ) == type;
00054         }
00055     };
00056 
00057     void remove_type( std::vector< EntityHandle >& vect, EntityType t )
00058     {
00059         vect.erase( std::remove_if( vect.begin(), vect.end(), IsType( t ) ), vect.end() );
00060     }
00061 
00062     void remove_type( Range& range, EntityType t )
00063     {
00064         std::pair< Range::iterator, Range::iterator > p = range.equal_range( t );
00065         range.erase( p.first, p.second );
00066     }
00067 };
00068 
00069 // step_iterator will safely step forward N steps in a iterator. We specialize
00070 // for random-access iterators (vectors and Ranges) so that they perform better.
00071 
00072 template < typename T >
00073 inline ErrorCode step_iterator( T& curr, const T& end, int num_steps, bool& at_end )
00074 {
00075     if( 0 > num_steps ) return MB_FAILURE;
00076 
00077     while( num_steps && curr != end )
00078     {
00079         num_steps--;
00080         curr++;
00081     }
00082     at_end = ( curr == end );
00083     return MB_SUCCESS;
00084 }
00085 
00086 template < typename T >
00087 inline ErrorCode step_iterator( typename std::vector< T >::const_iterator& curr,
00088                                 const typename std::vector< T >::const_iterator& end,
00089                                 int num_steps,
00090                                 bool& at_end )
00091 {
00092     if( 0 > num_steps ) return MB_FAILURE;
00093 
00094     assert( curr <= end );  // Sanity check
00095     at_end = ( end - curr <= num_steps );
00096 
00097     if( at_end )
00098         curr = end;
00099     else
00100         curr += num_steps;
00101     return MB_SUCCESS;
00102 }
00103 
00104 inline ErrorCode step_iterator( Range::const_iterator& curr,
00105                                 const Range::const_iterator& end,
00106                                 int num_steps,
00107                                 bool& at_end )
00108 {
00109     if( 0 > num_steps ) return MB_FAILURE;
00110 
00111     at_end = ( end - curr <= num_steps );
00112 
00113     if( at_end )
00114         curr = end;
00115     else
00116         curr += num_steps;
00117     return MB_SUCCESS;
00118 }
00119 
00120 template < class Container >
00121 class MBIter : public iBase_EntityArrIterator_Private
00122 {
00123   protected:
00124     Container iterData;
00125     typename Container::const_iterator iterPos;
00126 
00127   public:
00128     MBIter( iBase_EntityType type,
00129             iMesh_EntityTopology topology,
00130             EntityHandle set,
00131             int arr_size,
00132             bool recursive = false )
00133         : iBase_EntityArrIterator_Private( type, topology, set, arr_size, recursive ), iterPos( iterData.end() )
00134     {
00135     }
00136 
00137     ~MBIter() {}
00138 
00139     typename Container::const_iterator position() const
00140     {
00141         return iterPos;
00142     };
00143 
00144     typename Container::const_iterator end() const
00145     {
00146         return iterData.end();
00147     };
00148 
00149     ErrorCode step( int num_steps, bool& at_end )
00150     {
00151         return step_iterator( iterPos, end(), num_steps, at_end );
00152     }
00153 
00154     void get_entities( Core* mb, EntityHandle* array, int& count )
00155     {
00156         for( count = 0; count < arrSize && iterPos != iterData.end(); ++iterPos )
00157             if( mb->is_valid( *iterPos ) ) array[count++] = *iterPos;
00158     }
00159 
00160     virtual ErrorCode reset( Interface* mb )
00161     {
00162         ErrorCode result;
00163         iterData.clear();
00164         if( entTopo != iMesh_ALL_TOPOLOGIES )
00165         {
00166             if( entTopo == iMesh_SEPTAHEDRON )
00167                 result = MB_SUCCESS;
00168             else
00169                 result = mb->get_entities_by_type( entSet, mb_topology_table[entTopo], iterData, isRecursive );
00170         }
00171         else if( entType != iBase_ALL_TYPES )
00172         {
00173             result = mb->get_entities_by_dimension( entSet, entType, iterData, isRecursive );
00174             if( entType == iBase_REGION ) remove_type( iterData, MBKNIFE );
00175         }
00176         else
00177         {
00178             result = mb->get_entities_by_handle( entSet, iterData, isRecursive );
00179             remove_type( iterData, MBENTITYSET );
00180             remove_type( iterData, MBKNIFE );
00181         }
00182         iterPos = iterData.begin();
00183         return result;
00184     }
00185 };
00186 
00187 typedef MBIter< std::vector< EntityHandle > > MBListIter;
00188 typedef MBIter< moab::Range > MBRangeIter;
00189 
00190 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines