MOAB: Mesh Oriented datABase  (version 5.2.1)
LinearCellConnectivity.h
Go to the documentation of this file.
00001 #ifndef __smoab_LinearCellConnectivity_h
00002 #define __smoab_LinearCellConnectivity_h
00003 
00004 #include "CellTypeToType.h"
00005 #include "ContinousCellInfo.h"
00006 
00007 #include <algorithm>
00008 #include <vector>
00009 
00010 namespace smoab { namespace detail {
00011 
00012 namespace internal
00013 {
00014   //we want a subset of the real connetivity array,
00015   //this does that for use with a super easy wrapper
00016   struct SubsetArray
00017   {
00018     SubsetArray(EntityHandle* realConn,
00019                 int numCells,
00020                 int currentVertsPerCell,
00021                 int newVertsPerCell):
00022       Array()
00023     {
00024       const int size = numCells*newVertsPerCell;
00025       this->Array.reserve(size);
00026       if(currentVertsPerCell == newVertsPerCell)
00027         {
00028         std::copy(realConn,realConn+size, std::back_inserter(this->Array));
00029         }
00030       else
00031         {
00032         //skip copy only the first N points which we want
00033         //since moab stores linear points first per cell
00034         EntityHandle *pos = realConn;
00035         for(int i=0; i < numCells;++i)
00036           {
00037           std::copy(pos,pos+newVertsPerCell,std::back_inserter(this->Array));
00038           pos += currentVertsPerCell;
00039           }
00040         }
00041     }
00042     typedef std::vector<EntityHandle>::const_iterator const_iterator;
00043     typedef std::vector<EntityHandle>::iterator iterator;
00044 
00045     const_iterator begin() const { return this->Array.begin(); }
00046     iterator begin() { return this->Array.begin(); }
00047 
00048     const_iterator end() const { return this->Array.end(); }
00049     iterator end(){ return this->Array.end(); }
00050 
00051   private:
00052     std::vector<EntityHandle> Array;
00053   };
00054 }
00055 
00056 class LinearCellConnectivity
00057 {
00058 public:
00059 
00060   LinearCellConnectivity(smoab::Range const& cells, moab::Interface* moab):
00061     Connectivity(),
00062     UniquePoints(),
00063     Info()
00064     {
00065     int count = 0;
00066     const std::size_t cellSize=cells.size();
00067     while(count != cellSize)
00068       {
00069       EntityHandle* connectivity;
00070       int numVerts=0, iterationCount=0;
00071       //use the highly efficent calls, since we know that are of the same dimension
00072       moab->connect_iterate(cells.begin()+count,
00073                             cells.end(),
00074                             connectivity,
00075                             numVerts,
00076                             iterationCount);
00077       //if we didn't read anything, break!
00078       if(iterationCount == 0)
00079         {
00080         break;
00081         }
00082 
00083       //identify the cell type that we currently have,
00084       //store that along with the connectivity in a temp storage vector
00085       const moab::EntityType type = moab->type_from_handle(*cells.begin()+count);
00086 
00087       int vtkNumVerts;
00088       int vtkCellType = smoab::detail::vtkLinearCellType(type,vtkNumVerts);
00089 
00090       ContinousCellInfo info = { vtkCellType, vtkNumVerts, 0, iterationCount };
00091       this->Info.push_back(info);
00092 
00093 
00094       //we need to copy only a subset of the connectivity array
00095       internal::SubsetArray conn(connectivity,iterationCount,numVerts,vtkNumVerts);
00096       this->Connectivity.push_back(conn);
00097 
00098       count += iterationCount;
00099       }
00100     }
00101 
00102   //----------------------------------------------------------------------------
00103   void compactIds(vtkIdType& numCells, vtkIdType& connectivityLength)
00104     {
00105     //converts all the ids to be ordered starting at zero, and also
00106     //keeping the orginal logical ordering. Stores the result of this
00107     //operation in the unstrucutred grid that is passed in
00108 
00109     //lets determine the total length of the connectivity
00110     connectivityLength = 0;
00111     numCells = 0;
00112     for(InfoConstIterator i = this->Info.begin();
00113         i != this->Info.end();
00114         ++i)
00115       {
00116       connectivityLength += (*i).numCells * (*i).numVerts;
00117       numCells += (*i).numCells;
00118       }
00119 
00120     this->UniquePoints.reserve(connectivityLength);
00121 
00122     this->copyConnectivity(this->UniquePoints);
00123     std::sort(this->UniquePoints.begin(),this->UniquePoints.end());
00124 
00125     typedef std::vector<EntityHandle>::iterator EntityIterator;
00126     EntityIterator newEnd = std::unique(this->UniquePoints.begin(),
00127                                         this->UniquePoints.end());
00128 
00129     const std::size_t newSize = std::distance(this->UniquePoints.begin(),newEnd);
00130     this->UniquePoints.resize(newSize);
00131     }
00132 
00133   //----------------------------------------------------------------------------
00134   void moabPoints(smoab::Range& range) const
00135     {
00136     //from the documentation a reverse iterator is the fastest way
00137     //to insert into a range.
00138     std::copy(this->UniquePoints.rbegin(),
00139               this->UniquePoints.rend(),
00140               moab::range_inserter(range));
00141     }
00142 
00143   //----------------------------------------------------------------------------
00144   //copy the connectivity from the moab held arrays to the user input vector
00145   void copyConnectivity(std::vector<EntityHandle>& output) const
00146     {
00147     //walk the info to find the length of each sub connectivity array,
00148     //and insert them into the vector, ordering is implied by the order
00149     //the connecitivy sub array are added to this class
00150     ConnConstIterator c = this->Connectivity.begin();
00151     for(InfoConstIterator i = this->Info.begin();
00152         i != this->Info.end();
00153         ++i,++c)
00154       {
00155       //remember our Connectivity is a vector of pointers whose
00156       //length is held in the info vector.
00157       const int numUnusedPoints = (*i).numUnusedVerts;
00158       const int connLength = (*i).numCells * (*i).numVerts;
00159       std::copy(c->begin(),c->end(),std::back_inserter(output));
00160       }
00161     }
00162 
00163   //copy the information from this contianer to a vtk cell array, and
00164   //related lookup information
00165   void copyToVtkCellInfo(vtkIdType* cellArray) const
00166     {
00167     ConnConstIterator c = this->Connectivity.begin();
00168     for(InfoConstIterator i = this->Info.begin();
00169         i != this->Info.end();
00170         ++i, ++c)
00171       {
00172       //for this group of the same cell type we need to fill the cellTypes
00173       const int numCells = (*i).numCells;
00174       const int numVerts = (*i).numVerts;
00175 
00176       //for each cell in this collection that have the same type
00177       //grab the raw array now, so we can properly increment for each vert in each cell
00178       internal::SubsetArray::const_iterator moabConnectivity = c->begin();
00179       for(int j=0;j < numCells; ++j)
00180         {
00181         //cell arrays start and end are different, since we
00182         //have to account for element that states the length of each cell
00183         cellArray[0]=numVerts;
00184 
00185 
00186         for(int k=0; k < numVerts; ++k, ++moabConnectivity )
00187           {
00188           //this is going to be a root of some failures when we start
00189           //reading really large datasets under 32bit.
00190 
00191 
00192           //fyi, don't use a range ds for unique points, distance
00193           //function is horribly slow they need to override it
00194           EntityConstIterator result = std::lower_bound(
00195                                          this->UniquePoints.begin(),
00196                                          this->UniquePoints.end(),
00197                                          *moabConnectivity);
00198           std::size_t newId = std::distance(this->UniquePoints.begin(),
00199                                             result);
00200           cellArray[k+1] = static_cast<vtkIdType>(newId);
00201           }
00202         cellArray += numVerts+1;
00203         }
00204       }
00205     }
00206 
00207 private:
00208   std::vector<internal::SubsetArray> Connectivity;
00209   std::vector<EntityHandle> UniquePoints;
00210 
00211   std::vector<detail::ContinousCellInfo> Info;
00212 
00213   typedef std::vector<EntityHandle>::const_iterator EntityConstIterator;
00214   typedef std::vector<internal::SubsetArray>::const_iterator ConnConstIterator;
00215   typedef std::vector<detail::ContinousCellInfo>::const_iterator InfoConstIterator;
00216 };
00217 } }  //namespace smoab::detail
00218 
00219 #endif // __smoab_LinearCellConnectivity_h
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines