MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 #ifndef __smoab_detail_ReadSparseTag_h 00002 #define __smoab_detail_ReadSparseTag_h 00003 00004 #include "SimpleMoab.h" 00005 00006 #include <vtkIntArray.h> 00007 00008 #include <string> 00009 #include <algorithm> 00010 #include <vector> 00011 00012 namespace smoab { namespace detail { 00013 00014 00015 struct ReadSparseTag 00016 { 00017 00018 ReadSparseTag(const smoab::CellSets& mSets, 00019 const smoab::Range& cells, 00020 const smoab::Interface& interface): 00021 Interface(interface), 00022 MeshSets(mSets), 00023 Cells(cells) 00024 { 00025 } 00026 00027 //the cellTag describes the tag mapping between the cells 00028 //and meshsets. 00029 void fill(vtkIntArray* array, const Tag* cellTag) const; 00030 void fill(vtkIdTypeArray* array, const Tag* cellTag) const; 00031 00032 private: 00033 template<typename T> 00034 void fillRawArray(T* sparseTagArray, std::size_t length, 00035 const Tag* cellTag) const; 00036 00037 template<typename T> 00038 void singleSetRead(T *sparseTagArray, 00039 const std::vector<int>& values, 00040 std::size_t length) const; 00041 00042 template<typename T> 00043 void multiSetRead(T *sparseTagArray, 00044 const std::vector<int>& values, 00045 std::size_t length, 00046 int defaultTagValue) const; 00047 00048 const smoab::Interface& Interface; 00049 const smoab::CellSets& MeshSets; 00050 const smoab::Range& Cells; 00051 }; 00052 00053 //---------------------------------------------------------------------------- 00054 void ReadSparseTag::fill(vtkIntArray* array, const Tag* cellTag) const 00055 { 00056 const std::size_t length = this->Cells.size(); 00057 array->SetNumberOfValues(length); 00058 int *raw = static_cast<int*>(array->GetVoidPointer(0)); 00059 this->fillRawArray(raw,length,cellTag); 00060 } 00061 00062 //---------------------------------------------------------------------------- 00063 void ReadSparseTag::fill(vtkIdTypeArray* array, const Tag* cellTag) const 00064 { 00065 const std::size_t length = this->Cells.size(); 00066 array->SetNumberOfValues(length); 00067 vtkIdType *raw = static_cast<vtkIdType*>(array->GetVoidPointer(0)); 00068 this->fillRawArray(raw,length,cellTag); 00069 } 00070 00071 //---------------------------------------------------------------------------- 00072 template<typename T> 00073 void ReadSparseTag::fillRawArray(T *sparseTagArray, 00074 std::size_t length, 00075 const smoab::Tag* sparseTag) const 00076 { 00077 00078 typedef std::vector<int>::const_iterator IdConstIterator; 00079 typedef std::vector<int>::iterator IdIterator; 00080 typedef smoab::CellSets::const_iterator CellSetIterator; 00081 00082 std::vector<int> sparseTagValues(this->MeshSets.size()); 00083 //first off iterate the entities and determine which ones 00084 //have moab material ids 00085 00086 //todo get proper default value from moab 00087 //wrap this area with scope, to remove local variables 00088 00089 { 00090 const moab::Tag stag = this->Interface.getMoabTag(*sparseTag); 00091 IdIterator tagIds = sparseTagValues.begin(); 00092 for(CellSetIterator i=this->MeshSets.begin(); 00093 i != this->MeshSets.end(); 00094 ++i, ++tagIds) 00095 { 00096 //getTagData clobbers defaultValue 00097 int defaultValue = this->Interface.getDefaultTagVaue<int>(stag); 00098 *tagIds = this->Interface.getTagData(stag,i->entity(),defaultValue); 00099 } 00100 00101 //now determine ids for all entities that don't have materials 00102 IdConstIterator maxPos = std::max_element(sparseTagValues.begin(), 00103 sparseTagValues.end()); 00104 int maxValue = *maxPos; 00105 for(IdIterator i=sparseTagValues.begin(); i!= sparseTagValues.end(); ++i) 00106 { 00107 if(*i==-1) 00108 { 00109 *i = ++maxValue; 00110 } 00111 } 00112 } 00113 if(this->MeshSets.size() == 1) 00114 { 00115 this->singleSetRead(sparseTagArray,sparseTagValues,length); 00116 } 00117 else 00118 { 00119 int defaultValue = this->Interface.getDefaultTagVaue<int>(*sparseTag); 00120 this->multiSetRead(sparseTagArray,sparseTagValues,length,defaultValue); 00121 } 00122 } 00123 00124 //---------------------------------------------------------------------------- 00125 template<typename T> 00126 void ReadSparseTag::singleSetRead(T *sparseTagArray, 00127 const std::vector<int>& values, 00128 std::size_t length) const 00129 { 00130 00131 //now we set all the values as this has a single meshset so we 00132 //have no complicated logic for mapping each cell to a meshset 00133 T value = static_cast<T>(values[0]); 00134 std::fill(sparseTagArray,sparseTagArray+length,value); 00135 } 00136 00137 //---------------------------------------------------------------------------- 00138 template<typename T> 00139 void ReadSparseTag::multiSetRead(T *sparseTagArray, 00140 const std::vector<int>& sparseTagValues, 00141 std::size_t numCells, 00142 int defaultTagValue) const 00143 { 00144 typedef std::vector<smoab::EntityHandle>::const_iterator EntityHandleIterator; 00145 typedef std::vector<int>::const_iterator IdConstIterator; 00146 typedef smoab::CellSets::const_iterator CellSetIterator; 00147 typedef smoab::Range::const_iterator RangeIterator; 00148 00149 //create the search structure as a range is really slow to search with 00150 //lower_bounds 00151 std::vector<smoab::EntityHandle> searchableCells; 00152 smoab::RangeToVector(this->Cells,searchableCells); 00153 00154 00155 //pre fill with -1 to mark cells we don't touch, since some cells 00156 //might no have a default tag 00157 T defaultValue = T(defaultTagValue); 00158 std::fill(sparseTagArray,sparseTagArray+numCells,defaultValue); 00159 00160 EntityHandleIterator s_begin = searchableCells.begin(); 00161 EntityHandleIterator s_end = searchableCells.end(); 00162 00163 IdConstIterator currentTagValue = sparseTagValues.begin(); 00164 for(CellSetIterator i=this->MeshSets.begin(); 00165 i!=this->MeshSets.end(); ++i, ++currentTagValue) 00166 { 00167 T value = static_cast<T>(*currentTagValue); 00168 00169 const smoab::Range& entitiesCells = i->cells(); 00170 for(RangeIterator j=entitiesCells.begin(); j != entitiesCells.end();++j) 00171 { 00172 EntityHandleIterator result = std::lower_bound(s_begin, 00173 s_end, 00174 *j); 00175 std::size_t newId = std::distance(s_begin,result); 00176 sparseTagArray[newId] = value; 00177 } 00178 } 00179 00180 } 00181 00182 } 00183 } 00184 00185 #endif // __smoab_detail_ReadSparseTag_h