![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #ifndef __smoab_MixedCellConnectivity_h
00002 #define __smoab_MixedCellConnectivity_h
00003
00004 #include "CellTypeToType.h"
00005 #include "ContinousCellInfo.h"
00006
00007 #include
00008 #include
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