moab
SetIterator.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines