![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #ifndef __smoab_detail_LoadGeometry_h
00002 #define __smoab_detail_LoadGeometry_h
00003
00004 #include "SimpleMoab.h"
00005 #include "MixedCellConnectivity.h"
00006
00007 #include
00008 #include
00009 #include
00010 #include
00011 #include
00012 #include
00013 #include
00014 #include
00015 #include
00016 namespace smoab
00017 {
00018 namespace detail
00019 {
00020
00021 namespace
00022 {
00023
00024 //empty definition, only allow specializations to compile
00025 template < typename VTKGridType >
00026 struct setCells;
00027
00028 template <>
00029 struct setCells< vtkUnstructuredGrid >
00030 {
00031 typedef vtkUnstructuredGrid VTKGridType;
00032 void operator()( VTKGridType* grid,
00033 int,
00034 vtkUnsignedCharArray* types,
00035 vtkIdTypeArray* locations,
00036 vtkCellArray* cells ) const
00037 {
00038 grid->SetCells( types, locations, cells, NULL, NULL );
00039 }
00040 };
00041
00042 template <>
00043 struct setCells< vtkPolyData >
00044 {
00045 typedef vtkPolyData VTKGridType;
00046 void operator()( VTKGridType* grid,
00047 int dim,
00048 vtkUnsignedCharArray*,
00049 vtkIdTypeArray*,
00050 vtkCellArray* cells ) const
00051 {
00052 if( dim == 0 )
00053 {
00054 grid->SetVerts( cells );
00055 }
00056 else if( dim == 1 )
00057 {
00058 grid->SetLines( cells );
00059 }
00060 else if( dim == 2 )
00061 {
00062 grid->SetPolys( cells );
00063 }
00064 }
00065 };
00066
00067 } // namespace
00068 //basic class that given a range of moab cells will convert them to am unstructured grid.
00069 //holds only references to input cells, so they can't go out of scope
00070
00071 //The Topology tag is used to describe the dimensoniality of the cells we are reading
00072 // 0 == verts, 1 == lines, 2 == tri/quads, 3 = volume elements
00073 class LoadGeometry
00074 {
00075 moab::Interface* Interface;
00076 int TopologyDim;
00077 smoab::detail::MixedCellConnectivity MixConn;
00078 smoab::Range Points;
00079
00080 public:
00081 //----------------------------------------------------------------------------
00082 //warning cells input to constructor is held by reference
00083 LoadGeometry( const smoab::Range& cells, int topologyDim, const smoab::Interface& interface )
00084 : Interface( interface.Moab ), TopologyDim( topologyDim ), MixConn( cells, interface.Moab ), Points()
00085 {
00086 }
00087
00088 const smoab::Range& moabPoints() const
00089 {
00090 return this->Points;
00091 }
00092
00093 //----------------------------------------------------------------------------
00094 //todo: have support for using only a subsection of the input cells
00095 template < typename vtkDataSetType >
00096 void fill( vtkDataSetType* dataSet )
00097 {
00098 //now that mixConn has all the cells properly stored, lets fixup
00099 //the ids so that they start at zero and keep the same logical ordering
00100 //as before.
00101 vtkIdType numCells, connLen;
00102 this->MixConn.compactIds( numCells, connLen );
00103 this->addGridsTopology( dataSet, numCells, connLen );
00104 this->addCoordinates( dataSet );
00105 }
00106
00107 private:
00108 //----------------------------------------------------------------------------
00109 void addCoordinates( vtkPointSet* grid )
00110 {
00111 //this is sorta of hackish as moabPoints is only valid
00112 //after compactIds has been called
00113 this->MixConn.moabPoints( this->Points );
00114
00115 //since the smoab::range are always unique and sorted
00116 //we can use the more efficient coords_iterate
00117 //call in moab, which returns moab internal allocated memory
00118 vtkNew< vtkPoints > newPoints;
00119 newPoints->SetDataTypeToDouble();
00120 newPoints->SetNumberOfPoints( this->Points.size() );
00121
00122 //need a pointer to the allocated vtkPoints memory so that we
00123 //don't need to use an extra copy and we can bypass all vtk's check
00124 //on out of bounds
00125 double* rawPoints = static_cast< double* >( newPoints->GetVoidPointer( 0 ) );
00126 this->Interface->get_coords( this->Points, rawPoints );
00127
00128 grid->SetPoints( newPoints.GetPointer() );
00129 }
00130
00131 //----------------------------------------------------------------------------
00132 template < typename vtkDataSetType >
00133 void addGridsTopology( vtkDataSetType* grid, vtkIdType numCells, vtkIdType numConnectivity ) const
00134 {
00135 //correct the connectivity size to account for the vtk padding
00136 const vtkIdType vtkConnectivity = numCells + numConnectivity;
00137
00138 vtkNew< vtkIdTypeArray > cellArray;
00139 vtkNew< vtkIdTypeArray > cellLocations;
00140 vtkNew< vtkUnsignedCharArray > cellTypes;
00141
00142 cellArray->SetNumberOfValues( vtkConnectivity );
00143 cellLocations->SetNumberOfValues( numCells );
00144 cellTypes->SetNumberOfValues( numCells );
00145
00146 vtkIdType* rawArray = static_cast< vtkIdType* >( cellArray->GetVoidPointer( 0 ) );
00147 vtkIdType* rawLocations = static_cast< vtkIdType* >( cellLocations->GetVoidPointer( 0 ) );
00148 unsigned char* rawTypes = static_cast< unsigned char* >( cellTypes->GetVoidPointer( 0 ) );
00149
00150 this->MixConn.copyToVtkCellInfo( rawArray, rawLocations, rawTypes );
00151
00152 vtkNew< vtkCellArray > cells;
00153 cells->SetCells( numCells, cellArray.GetPointer() );
00154
00155 setCells< vtkDataSetType >()( grid, this->TopologyDim, cellTypes.GetPointer(), cellLocations.GetPointer(),
00156 cells.GetPointer() );
00157 }
00158 };
00159
00160 } // namespace detail
00161 } // namespace smoab
00162
00163 #endif // __smoab_detail_LoadGeometry_h