moab
|
00001 #ifndef IS_BUILDING_MB 00002 #error "SetIterator.hpp isn't supposed to be included into an application" 00003 #endif 00004 00005 #include "moab/SetIterator.hpp" 00006 #include "moab/Core.hpp" 00007 #include "moab/WriteUtilIface.hpp" 00008 #include "MeshSet.hpp" 00009 #include "Internals.hpp" 00010 #include "moab/CN.hpp" 00011 #include "moab/Error.hpp" 00012 00013 namespace moab 00014 { 00015 00016 SetIterator::~SetIterator() 00017 { 00018 myCore->remove_set_iterator(this); 00019 } 00020 00021 RangeSetIterator::RangeSetIterator(Core *core, EntityHandle eset, int chunk_sz, 00022 EntityType ent_tp, int ent_dim, bool check_valid) 00023 : SetIterator(core, eset, chunk_sz, ent_tp, ent_dim, check_valid), 00024 iterPos(0), pairPtr(NULL), numPairs(0) 00025 { 00026 if (!eset) { 00027 // special case for the root set, have to keep a local array 00028 ErrorCode rval = build_pair_vec(); 00029 assert(MB_SUCCESS == rval); 00030 00031 // empty statement to avoid warning 00032 (void)(rval); 00033 } 00034 } 00035 00036 RangeSetIterator::~RangeSetIterator() 00037 { 00038 if (pairPtr) delete [] pairPtr; 00039 numPairs = 0; 00040 } 00041 00042 ErrorCode RangeSetIterator::build_pair_vec() 00043 { 00044 // shouldn't be here unless we're iterating the root set 00045 assert(!entSet); 00046 00047 Range all_ents; 00048 ErrorCode rval = myCore->get_entities_by_handle(0, all_ents); 00049 if (MB_SUCCESS != rval) return rval; 00050 00051 if (pairPtr) delete [] pairPtr; 00052 pairPtr = new EntityHandle[2*all_ents.psize()]; 00053 Range::const_pair_iterator pi; 00054 int i; 00055 for (pi = all_ents.const_pair_begin(), i = 0; 00056 pi != all_ents.const_pair_end(); pi++, i+=2) { 00057 pairPtr[i] = (*pi).first; 00058 pairPtr[i+1] = (*pi).second; 00059 } 00060 numPairs = all_ents.psize(); 00061 00062 return MB_SUCCESS; 00063 } 00064 00065 ErrorCode RangeSetIterator::get_next_arr(std::vector<EntityHandle> &arr, 00066 bool &atend) 00067 { 00068 atend = false; 00069 00070 int count; 00071 const EntityHandle *ptr; 00072 WriteUtilIface *iface; 00073 std::vector<EntityHandle> tmp_arr; 00074 std::vector<EntityHandle> *tmp_ptr = &arr; 00075 if (checkValid) tmp_ptr = &tmp_arr; 00076 ErrorCode rval; 00077 if (!pairPtr) { 00078 Interface *mbImpl = dynamic_cast<Interface*>(myCore); 00079 rval = mbImpl->query_interface(iface); 00080 if (MB_SUCCESS != rval) return rval; 00081 00082 rval = iface->get_entity_list_pointers( &entSet, 1, &ptr, WriteUtilIface::CONTENTS, &count); 00083 if (MB_SUCCESS != rval) return rval; 00084 mbImpl->release_interface(iface); 00085 } 00086 else { 00087 if (checkValid) { 00088 rval = build_pair_vec(); 00089 if (MB_SUCCESS != rval) return rval; 00090 } 00091 ptr = pairPtr; 00092 count = 2*numPairs; 00093 } 00094 assert(!(count%2)); 00095 if (!count) { 00096 atend = true; 00097 return MB_SUCCESS; 00098 } 00099 00100 if (-1 == entDimension) rval = get_next_by_type(ptr, count, *tmp_ptr, atend); 00101 else rval = get_next_by_dimension(ptr, count, *tmp_ptr, atend); 00102 if (MB_SUCCESS != rval) return rval; 00103 00104 if (checkValid) { 00105 for (std::vector<EntityHandle>::iterator vit = tmp_ptr->begin(); vit != tmp_ptr->end(); vit++) { 00106 if (myCore->is_valid(*vit)) arr.push_back(*vit); 00107 } 00108 } 00109 00110 return MB_SUCCESS; 00111 } 00112 00113 ErrorCode RangeSetIterator::get_next_by_type(const EntityHandle *&ptr, int count, 00114 std::vector<EntityHandle> &arr, bool &atend) 00115 { 00116 unsigned int num_ret = 0; 00117 bool max_type = (entType == MBMAXTYPE); 00118 size_t idx = 0; 00119 // initialize to first relevant handle 00120 while ((int)idx < count && 00121 (iterPos > ptr[idx+1] || 00122 (!max_type && !iterPos && CREATE_HANDLE(entType, ID_FROM_HANDLE(iterPos)) > ptr[idx+1]))) 00123 idx += 2; 00124 if ((int)idx == count || TYPE_FROM_HANDLE(ptr[idx]) > entType) { 00125 atend = true; 00126 return MB_SUCCESS; 00127 } 00128 if (!iterPos && max_type) iterPos = ptr[idx]; 00129 else if (!iterPos && 00130 TYPE_FROM_HANDLE(ptr[idx]) <= entType && 00131 TYPE_FROM_HANDLE(ptr[idx+1]) >= entType) { 00132 iterPos = std::max(CREATE_HANDLE(entType,1), ptr[idx]); 00133 } 00134 00135 // idx points to start of subrange, iterPos in that subrange 00136 do { 00137 EntityHandle next = ptr[idx+1]; 00138 if (TYPE_FROM_HANDLE(next) != entType && !max_type) next = LAST_HANDLE(entType); 00139 unsigned int this_ret = chunkSize-num_ret; 00140 unsigned int to_end = next - iterPos + 1; 00141 if (to_end < this_ret) this_ret = to_end; 00142 std::copy(MeshSet::hdl_iter(iterPos), MeshSet::hdl_iter(iterPos + this_ret), 00143 std::back_inserter(arr)); 00144 if (this_ret == to_end) { 00145 idx += 2; 00146 iterPos = ((int)idx < count ? ptr[idx] : 0); 00147 } 00148 else iterPos += this_ret; 00149 00150 num_ret += this_ret; 00151 } 00152 while ((int)idx < count && num_ret < chunkSize && 00153 iterPos && (max_type || TYPE_FROM_HANDLE(iterPos) == entType)); 00154 00155 if (!iterPos || (!max_type && TYPE_FROM_HANDLE(iterPos) != entType)) atend = true; 00156 00157 return MB_SUCCESS; 00158 } 00159 00160 ErrorCode RangeSetIterator::get_next_by_dimension(const EntityHandle *&ptr, int count, 00161 std::vector<EntityHandle> &arr, bool &atend) 00162 { 00163 // iterating by dimension - type should be maxtype 00164 if (entType != MBMAXTYPE) { 00165 Error *error; 00166 dynamic_cast<Interface*>(myCore)->query_interface(error); 00167 error->set_last_error("Both dimension and type should not be set on an iterator."); 00168 return MB_FAILURE; 00169 } 00170 00171 unsigned int num_ret = 0; 00172 size_t idx = 0; 00173 // initialize to first relevant handle 00174 while ((int)idx < count && 00175 (iterPos > ptr[idx+1] || 00176 (!iterPos && entDimension > CN::Dimension(TYPE_FROM_HANDLE(ptr[idx+1]))))) 00177 idx += 2; 00178 if ((int)idx == count || CN::Dimension(TYPE_FROM_HANDLE(ptr[idx])) > entDimension) { 00179 atend = true; 00180 return MB_SUCCESS; 00181 } 00182 if (!iterPos) iterPos = ptr[idx]; 00183 else if (CN::Dimension(TYPE_FROM_HANDLE(ptr[idx])) < entDimension) 00184 iterPos = CREATE_HANDLE(CN::TypeDimensionMap[entDimension].first,1); 00185 00186 // idx points to start of subrange, iterPos in that subrange 00187 do { 00188 EntityHandle next = ptr[idx+1]; 00189 if (CN::Dimension(TYPE_FROM_HANDLE(next)) != entDimension) 00190 next = LAST_HANDLE(CN::TypeDimensionMap[entDimension].second); 00191 unsigned int this_ret = chunkSize-num_ret; 00192 unsigned int to_end = next - iterPos + 1; 00193 if (to_end < this_ret) this_ret = to_end; 00194 std::copy(MeshSet::hdl_iter(iterPos), MeshSet::hdl_iter(iterPos + this_ret), 00195 std::back_inserter(arr)); 00196 if (this_ret == to_end) { 00197 idx += 2; 00198 iterPos = ((int)idx < count ? ptr[idx] : 0); 00199 } 00200 else iterPos += this_ret; 00201 00202 num_ret += this_ret; 00203 } 00204 while ((int)idx < count && num_ret < chunkSize && 00205 iterPos && CN::Dimension(TYPE_FROM_HANDLE(iterPos)) == entDimension); 00206 00207 if (!iterPos || CN::Dimension(TYPE_FROM_HANDLE(iterPos)) != entDimension) atend = true; 00208 00209 return MB_SUCCESS; 00210 } 00211 00212 ErrorCode RangeSetIterator::reset() 00213 { 00214 iterPos = 0; 00215 return MB_SUCCESS; 00216 } 00217 00218 ErrorCode VectorSetIterator::get_next_arr(std::vector<EntityHandle> &arr, 00219 bool &atend) 00220 { 00221 int count; 00222 const EntityHandle *ptr; 00223 WriteUtilIface *iface; 00224 Interface *mbImpl = dynamic_cast<Interface*>(myCore); 00225 ErrorCode rval = mbImpl->query_interface(iface); 00226 if (MB_SUCCESS != rval) return rval; 00227 00228 rval = iface->get_entity_list_pointers( &entSet, 1, &ptr, WriteUtilIface::CONTENTS, &count); 00229 if (MB_SUCCESS != rval) return rval; 00230 mbImpl->release_interface(iface); 00231 00232 if (!count || iterPos >= count) { 00233 atend = true; 00234 return MB_SUCCESS; 00235 } 00236 00237 std::vector<EntityHandle> tmp_arr; 00238 std::vector<EntityHandle> *tmp_ptr = &arr; 00239 if (checkValid) tmp_ptr = &tmp_arr; 00240 00241 // just get the next chunkSize entities, or as many as you can 00242 int this_ct = 0; 00243 while (this_ct < (int)chunkSize && iterPos < count) { 00244 if ((MBMAXTYPE == entType || TYPE_FROM_HANDLE(ptr[iterPos]) == entType) && 00245 (-1 == entDimension || CN::Dimension(TYPE_FROM_HANDLE(ptr[iterPos])) == entDimension)) { 00246 arr.push_back(ptr[iterPos]); 00247 this_ct++; 00248 } 00249 iterPos++; 00250 } 00251 00252 atend = (iterPos == count); 00253 00254 if (checkValid) { 00255 for (std::vector<EntityHandle>::iterator vit = tmp_ptr->begin(); vit != tmp_ptr->end(); vit++) { 00256 if (myCore->is_valid(*vit)) arr.push_back(*vit); 00257 } 00258 } 00259 00260 // step along list, adding entities 00261 return MB_SUCCESS; 00262 } 00263 00264 ErrorCode VectorSetIterator::reset() 00265 { 00266 iterPos = 0; 00267 return MB_SUCCESS; 00268 } 00269 00270 }