moab
|
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 virtual ~iBase_EntityArrIterator_Private() {} 00030 00031 int array_size() const { return arrSize; } 00032 00033 virtual ErrorCode step(int num_steps, bool &at_end)=0; 00034 00035 // NOTE: input array must be at least arrLen long 00036 virtual void get_entities( Core* mb, 00037 EntityHandle* array, 00038 int& count_out ) = 0; 00039 00040 virtual ErrorCode reset( Interface* mb ) = 0; 00041 00042 class IsType { 00043 private: EntityType type; 00044 public: IsType( EntityType t ) : type(t) {} 00045 bool operator()( EntityHandle h ) 00046 { return TYPE_FROM_HANDLE(h) == type; } 00047 }; 00048 00049 void remove_type( std::vector<EntityHandle>& vect, EntityType t ) { 00050 vect.erase( std::remove_if( vect.begin(), vect.end(), IsType(t) ), vect.end() ); 00051 } 00052 00053 void remove_type( Range& range, EntityType t ) { 00054 std::pair<Range::iterator,Range::iterator> p = range.equal_range(t); 00055 range.erase( p.first, p.second ); 00056 } 00057 }; 00058 00059 // step_iterator will safely step forward N steps in a iterator. We specialize 00060 // for random-access iterators (vectors and Ranges) so that they perform better. 00061 00062 template <typename T> 00063 inline 00064 ErrorCode step_iterator(T &curr, const T &end, int num_steps, bool &at_end) 00065 { 00066 if (0 > num_steps) return MB_FAILURE; 00067 00068 while (num_steps && curr != end) { 00069 num_steps--; 00070 curr++; 00071 } 00072 at_end = (curr == end); 00073 return MB_SUCCESS; 00074 } 00075 00076 template <typename T> 00077 inline 00078 ErrorCode step_iterator(typename std::vector<T>::const_iterator &curr, 00079 const typename std::vector<T>::const_iterator &end, 00080 int num_steps, bool &at_end) 00081 { 00082 if (0 > num_steps) return MB_FAILURE; 00083 00084 assert(curr <= end); // Sanity check 00085 at_end = (end - curr <= num_steps); 00086 00087 if (at_end) 00088 curr = end; 00089 else 00090 curr += num_steps; 00091 return MB_SUCCESS; 00092 } 00093 00094 inline 00095 ErrorCode step_iterator(Range::const_iterator &curr, 00096 const Range::const_iterator &end, int num_steps, 00097 bool &at_end) 00098 { 00099 if (0 > num_steps) return MB_FAILURE; 00100 00101 at_end = (end - curr <= num_steps); 00102 00103 if (at_end) 00104 curr = end; 00105 else 00106 curr += num_steps; 00107 return MB_SUCCESS; 00108 } 00109 00110 template <class Container> class MBIter : public iBase_EntityArrIterator_Private 00111 { 00112 protected: 00113 Container iterData; 00114 typename Container::const_iterator iterPos; 00115 00116 public: 00117 MBIter( iBase_EntityType type, 00118 iMesh_EntityTopology topology, 00119 EntityHandle set, 00120 int arr_size, 00121 bool recursive = false) 00122 : iBase_EntityArrIterator_Private( type, topology, set, arr_size, recursive ), 00123 iterPos(iterData.end()) {} 00124 00125 ~MBIter() {} 00126 00127 typename Container::const_iterator position() const {return iterPos;}; 00128 00129 typename Container::const_iterator end() const {return iterData.end();}; 00130 00131 ErrorCode step(int num_steps, bool &at_end) 00132 { 00133 return step_iterator(iterPos, end(), num_steps, at_end); 00134 } 00135 00136 void get_entities( Core* mb, EntityHandle* array, int& count ) 00137 { 00138 for (count = 0; count < arrSize && iterPos != iterData.end(); ++iterPos) 00139 if (mb->is_valid(*iterPos)) 00140 array[count++] = *iterPos; 00141 } 00142 00143 virtual ErrorCode reset( Interface* mb ) { 00144 ErrorCode result; 00145 iterData.clear(); 00146 if (entTopo != iMesh_ALL_TOPOLOGIES) { 00147 if (entTopo == iMesh_SEPTAHEDRON) 00148 result = MB_SUCCESS; 00149 else 00150 result = mb->get_entities_by_type( entSet, mb_topology_table[entTopo], iterData, isRecursive ); 00151 } 00152 else if (entType != iBase_ALL_TYPES) { 00153 result = mb->get_entities_by_dimension( entSet, entType, iterData, isRecursive ); 00154 if (entType == iBase_REGION) 00155 remove_type( iterData, MBKNIFE ); 00156 } 00157 else { 00158 result = mb->get_entities_by_handle( entSet, iterData, isRecursive ); 00159 remove_type( iterData, MBENTITYSET ); 00160 remove_type( iterData, MBKNIFE ); 00161 } 00162 iterPos = iterData.begin(); 00163 return result; 00164 } 00165 }; 00166 00167 typedef MBIter< std::vector<EntityHandle> > MBListIter; 00168 typedef MBIter< moab::Range > MBRangeIter; 00169 00170 #endif