MOAB: Mesh Oriented datABase  (version 5.4.0)
MixedCellConnectivity.h
Go to the documentation of this file.
00001 #ifndef __smoab_MixedCellConnectivity_h
00002 #define __smoab_MixedCellConnectivity_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     class MixedCellConnectivity
00016     {
00017       public:
00018         MixedCellConnectivity( smoab::Range const& cells, moab::Interface* moab )
00019             : Connectivity(), UniquePoints(), Info()
00020         {
00021             int count                  = 0;
00022             const std::size_t cellSize = cells.size();
00023             while( count != cellSize )
00024             {
00025                 EntityHandle* connectivity;
00026                 int numVerts = 0, iterationCount = 0;
00027                 //use the highly efficent calls, since we know that are of the same dimension
00028                 moab->connect_iterate( cells.begin() + count, cells.end(), connectivity, numVerts, iterationCount );
00029                 //if we didn't read anything, break!
00030                 if( iterationCount == 0 )
00031                 {
00032                     break;
00033                 }
00034 
00035                 //identify the cell type that we currently have,
00036                 //store that along with the connectivity in a temp storage vector
00037                 const moab::EntityType type = moab->type_from_handle( *cells.begin() + count );
00038 
00039                 //while all these cells are contiously of the same type,
00040                 //quadric hexs in vtk have 20 points, but moab has 21 so we
00041                 //need to store this difference
00042                 int numVTKVerts = numVerts;
00043                 int vtkCellType = smoab::detail::vtkCellType( type, numVTKVerts );
00044 
00045                 ContinousCellInfo info = { vtkCellType, numVerts, ( numVerts - numVTKVerts ), iterationCount };
00046                 this->Info.push_back( info );
00047                 this->Connectivity.push_back( connectivity );
00048 
00049                 count += iterationCount;
00050             }
00051         }
00052 
00053         //----------------------------------------------------------------------------
00054         void compactIds( vtkIdType& numCells, vtkIdType& connectivityLength )
00055         {
00056             //converts all the ids to be ordered starting at zero, and also
00057             //keeping the orginal logical ordering. Stores the result of this
00058             //operation in the unstrucutred grid that is passed in
00059 
00060             //lets determine the total length of the connectivity
00061             connectivityLength = 0;
00062             numCells           = 0;
00063             for( InfoConstIterator i = this->Info.begin(); i != this->Info.end(); ++i )
00064             {
00065                 connectivityLength += ( *i ).numCells * ( *i ).numVerts;
00066                 numCells += ( *i ).numCells;
00067             }
00068 
00069             this->UniquePoints.reserve( connectivityLength );
00070 
00071             this->copyConnectivity( this->UniquePoints );
00072             std::sort( this->UniquePoints.begin(), this->UniquePoints.end() );
00073 
00074             typedef std::vector< EntityHandle >::iterator EntityIterator;
00075             EntityIterator newEnd = std::unique( this->UniquePoints.begin(), this->UniquePoints.end() );
00076 
00077             const std::size_t newSize = std::distance( this->UniquePoints.begin(), newEnd );
00078             this->UniquePoints.resize( newSize );
00079         }
00080 
00081         //----------------------------------------------------------------------------
00082         void moabPoints( smoab::Range& range ) const
00083         {
00084             //from the documentation a reverse iterator is the fastest way
00085             //to insert into a range.
00086             std::copy( this->UniquePoints.rbegin(), this->UniquePoints.rend(), moab::range_inserter( range ) );
00087         }
00088 
00089         //----------------------------------------------------------------------------
00090         //copy the connectivity from the moab held arrays to the user input vector
00091         void copyConnectivity( std::vector< EntityHandle >& output ) const
00092         {
00093             //walk the info to find the length of each sub connectivity array,
00094             //and insert them into the vector, ordering is implied by the order
00095             //the connecitivy sub array are added to this class
00096             ConnConstIterator c = this->Connectivity.begin();
00097             for( InfoConstIterator i = this->Info.begin(); i != this->Info.end(); ++i, ++c )
00098             {
00099                 //remember our Connectivity is a vector of pointers whose
00100                 //length is held in the info vector.
00101                 const int numUnusedPoints = ( *i ).numUnusedVerts;
00102                 if( numUnusedPoints == 0 )
00103                 {
00104                     const int connLength = ( *i ).numCells * ( *i ).numVerts;
00105                     std::copy( *c, *c + connLength, std::back_inserter( output ) );
00106                 }
00107                 else
00108                 {
00109                     //we have cell connectivity that we need to skip,
00110                     //so we have to manual copy each cells connectivity
00111                     const int size      = ( *i ).numCells;
00112                     const int numPoints = ( *i ).numVerts;
00113                     for( int j = 0; j < size; ++j )
00114                     {
00115                         std::copy( *c, *c + numPoints, std::back_inserter( output ) );
00116                     }
00117                     c += numPoints + ( *i ).numUnusedVerts;
00118                 }
00119             }
00120         }
00121 
00122         //copy the information from this contianer to a vtk cell array, and
00123         //related lookup information
00124         void copyToVtkCellInfo( vtkIdType* cellArray, vtkIdType* cellLocations, unsigned char* cellTypes ) const
00125         {
00126             vtkIdType currentVtkConnectivityIndex = 0;
00127             ConnConstIterator c                   = this->Connectivity.begin();
00128             for( InfoConstIterator i = this->Info.begin(); i != this->Info.end(); ++i, ++c )
00129             {
00130                 //for this group of the same cell type we need to fill the cellTypes
00131                 const int numCells = ( *i ).numCells;
00132                 const int numVerts = ( *i ).numVerts;
00133 
00134                 std::fill_n( cellTypes, numCells, static_cast< unsigned char >( ( *i ).type ) );
00135 
00136                 //for each cell in this collection that have the same type
00137                 //grab the raw array now, so we can properly increment for each vert in each cell
00138                 EntityHandle* moabConnectivity = *c;
00139                 for( int j = 0; j < numCells; ++j )
00140                 {
00141                     cellLocations[j] = currentVtkConnectivityIndex;
00142 
00143                     //cell arrays start and end are different, since we
00144                     //have to account for element that states the length of each cell
00145                     cellArray[0] = numVerts;
00146 
00147                     for( int k = 0; k < numVerts; ++k, ++moabConnectivity )
00148                     {
00149                         //this is going to be a root of some failures when we start
00150                         //reading really large datasets under 32bit.
00151 
00152                         //fyi, don't use a range ds for unique points, distance
00153                         //function is horribly slow they need to override it
00154                         EntityConstIterator result =
00155                             std::lower_bound( this->UniquePoints.begin(), this->UniquePoints.end(), *moabConnectivity );
00156                         std::size_t newId = std::distance( this->UniquePoints.begin(), result );
00157                         cellArray[k + 1]  = static_cast< vtkIdType >( newId );
00158                     }
00159 
00160                     //skip any extra unused points, which is currnetly only
00161                     //the extra center point in moab quadratic hex
00162                     moabConnectivity += ( *i ).numUnusedVerts;
00163 
00164                     currentVtkConnectivityIndex += numVerts + 1;
00165                     cellArray += numVerts + 1;
00166                 }
00167 
00168                 //For Tri-Quadratic-Hex and Quadratric-Wedge Moab and VTK
00169                 //Differ on the order of the edge ids. For wedge we need to swap
00170                 //indices 9,10,11 with 12,13,14 for each cell. For Hex we sawp
00171                 //12,13,14,15 with 16,17,18,19
00172                 int vtkCellType         = ( *i ).type;
00173                 vtkIdType* connectivity = cellArray - ( numCells * ( numVerts + 1 ) );
00174                 if( vtkCellType == VTK_TRIQUADRATIC_HEXAHEDRON )
00175                 {
00176                     smoab::detail::QuadratricOrdering< VTK_TRIQUADRATIC_HEXAHEDRON > newOrdering;
00177                     smoab::detail::FixQuadraticIdOrdering( connectivity, numCells, newOrdering );
00178                 }
00179                 else if( vtkCellType == VTK_QUADRATIC_WEDGE )
00180                 {
00181                     smoab::detail::QuadratricOrdering< VTK_QUADRATIC_WEDGE > newOrdering;
00182                     smoab::detail::FixQuadraticIdOrdering( connectivity, numCells, newOrdering );
00183                 }
00184 
00185                 cellLocations += numCells;
00186                 cellTypes += numCells;
00187             }
00188         }
00189 
00190       private:
00191         std::vector< EntityHandle* > Connectivity;
00192         std::vector< EntityHandle > UniquePoints;
00193 
00194         std::vector< detail::ContinousCellInfo > Info;
00195 
00196         typedef std::vector< EntityHandle >::const_iterator EntityConstIterator;
00197         typedef std::vector< EntityHandle* >::const_iterator ConnConstIterator;
00198         typedef std::vector< detail::ContinousCellInfo >::const_iterator InfoConstIterator;
00199     };
00200 }  // namespace detail
00201 }  // namespace smoab
00202 
00203 #endif  // __smoab_MixedCellConnectivity_h
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines