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 <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