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