// vtk headers #include #include #include #include #include #include #include #include #include #include // LBPM headers #include "IO/Mesh.h" #include "IO/MeshDatabase.h" extern std::ostream DebugStream1; extern std::ostream DebugStream2; // Convert a point array to vtkFloatArray inline vtkFloatArray* pointToVTK( const std::vector& points ) { vtkFloatArray *coords = vtkFloatArray::New(); coords->SetNumberOfComponents(3); coords->SetNumberOfTuples(points.size()); for (size_t i=0; iSetTuple3(i,points[i].x,points[i].y,points[i].z); return coords; } // Return the mesh type inline avtMeshType vtkMeshType( IO::MeshType meshType ) { avtMeshType vtkType = AVT_UNKNOWN_MESH; if ( meshType==IO::PointMesh ) vtkType = AVT_POINT_MESH; else if ( meshType==IO::SurfaceMesh ) vtkType = AVT_SURFACE_MESH; else if ( meshType==IO::VolumeMesh ) vtkType = AVT_RECTILINEAR_MESH; return vtkType; } // Return the topological dimension inline int vtkTopDim( IO::MeshType meshType ) { int dim = -1; if ( meshType==IO::PointMesh ) dim = 1; else if ( meshType==IO::SurfaceMesh ) dim = 2; else if ( meshType==IO::VolumeMesh ) dim = 3; return dim; } // Convert a PointList to vtkDataSet inline vtkDataSet* PointListToVTK( std::shared_ptr mesh ) { vtkFloatArray *coords = pointToVTK(mesh->points); vtkPoints *points = vtkPoints::New(VTK_FLOAT); points->SetData(coords); points->ComputeBounds(); size_t N = mesh->points.size(); vtkPolyData *vtkMesh = vtkPolyData::New(); vtkMesh->SetPoints(points); vtkMesh->Allocate(N); for (int i=0; i<(int)N; i++) { vtkIdType ids[1] = {i}; vtkMesh->InsertNextCell(VTK_VERTEX,1,ids); } // vtkMesh->BuildCells(); vtkMesh->ComputeBounds(); points->Delete(); coords->Delete(); return vtkMesh; } // Convert a TriMesh to vtkDataSet inline vtkDataSet* TriMeshToVTK( std::shared_ptr mesh ) { vtkFloatArray *coords = pointToVTK(mesh->vertices->points); ASSERT(coords!=NULL); vtkPoints *points = vtkPoints::New(VTK_FLOAT); points->SetData(coords); points->ComputeBounds(); const std::vector& A = mesh->A; const std::vector& B = mesh->B; const std::vector& C = mesh->C; size_t N_tri = A.size(); vtkPolyData *vtkMesh = vtkPolyData::New(); vtkMesh->SetPoints(points); vtkMesh->Allocate(N_tri); for (size_t i=0; iInsertNextCell(VTK_TRIANGLE,3,ids); } vtkMesh->BuildCells(); vtkMesh->ComputeBounds(); points->Delete(); coords->Delete(); return vtkMesh; } // Convert a TriList to vtkDataSet inline vtkDataSet* TriListToVTK( std::shared_ptr mesh ) { std::vector point_set(3*mesh->A.size()); for (size_t i=0; iA.size(); i++) { point_set[3*i+0] = mesh->A[i]; point_set[3*i+1] = mesh->B[i]; point_set[3*i+2] = mesh->C[i]; } vtkFloatArray *coords = pointToVTK(point_set); ASSERT(coords!=NULL); vtkPoints *points = vtkPoints::New(VTK_FLOAT); points->SetData(coords); points->ComputeBounds(); size_t N_tri = mesh->A.size(); vtkPolyData *vtkMesh = vtkPolyData::New(); vtkMesh->SetPoints(points); vtkMesh->Allocate(N_tri); for (int i=0; i<(int)N_tri; i++) { vtkIdType ids[3] = {3*i+0,3*i+1,3*i+2}; vtkMesh->InsertNextCell(VTK_TRIANGLE,3,ids); } vtkMesh->BuildCells(); vtkMesh->ComputeBounds(); points->Delete(); coords->Delete(); return vtkMesh; } // Convert a DomainMesh to vtkDataSet inline vtkDataSet* DomainToVTK( std::shared_ptr mesh ) { int nx = mesh->nx; int ny = mesh->ny; int nz = mesh->nz; if ( nx==0 || ny==0 || nz==0 ) { DebugStream::Stream1() << " Domain mesh is empty" << std::endl; return NULL; } RankInfoStruct rank_data(mesh->rank,mesh->nprocx,mesh->nprocy,mesh->nprocz); vtkFloatArray *x = vtkFloatArray::New(); vtkFloatArray *y = vtkFloatArray::New(); vtkFloatArray *z = vtkFloatArray::New(); for(int i=0; i<=nx; i++) x->InsertNextValue(static_cast(nx*rank_data.ix+i)/static_cast(nx*mesh->nprocx)); for(int j=0; j<=ny; j++) y->InsertNextValue(static_cast(ny*rank_data.jy+j)/static_cast(ny*mesh->nprocy)); for(int k=0; k<=nz; k++) z->InsertNextValue(static_cast(nz*rank_data.kz+k)/static_cast(nz*mesh->nprocz)); vtkRectilinearGrid *vtkMesh = vtkRectilinearGrid::New(); vtkMesh->SetDimensions(nx+1,ny+1,nz+1); vtkMesh->SetXCoordinates(x); vtkMesh->SetYCoordinates(y); vtkMesh->SetZCoordinates(z); vtkMesh->ComputeBounds(); x->Delete(); y->Delete(); z->Delete(); return vtkMesh; } // Convert a mesh to vtkDataSet inline vtkDataSet* meshToVTK( std::shared_ptr mesh ) { if ( mesh.get() == NULL ){ DebugStream::Stream1() << " Mesh is NULL" << std::endl; return NULL; } vtkDataSet* mesh2 = NULL; const std::string className = mesh->className(); if ( className == "PointList" ) { // We are dealing with a point mesh mesh2 = PointListToVTK( std::dynamic_pointer_cast(mesh) ); DebugStream1 << " Point mesh created" << std::endl; } else if ( className == "TriMesh" ) { mesh2 = TriMeshToVTK( std::dynamic_pointer_cast(mesh) ); DebugStream1 << " Surface mesh created" << std::endl; } else if ( className == "TriList" ) { mesh2 = TriListToVTK( std::dynamic_pointer_cast(mesh) ); DebugStream1 << " Surface mesh created" << std::endl; } else if ( className == "DomainMesh" ) { mesh2 = DomainToVTK( std::dynamic_pointer_cast(mesh) ); DebugStream1 << " Volume mesh created" << std::endl; } else { //DebugStream1 << " Error, unknown mesh type" << std::endl; return NULL; } return mesh2; } // Convert a variable to vtkDataSet inline vtkDataArray* varToVTK( std::shared_ptr var ) { vtkFloatArray* var2 = NULL; if ( var->dim==1 ) { // Scalar variable var2 = vtkFloatArray::New(); var2->SetNumberOfTuples(var->data.length()); for (size_t i=0; idata.length(); i++) var2->SetTuple1(i,var->data(i)); } else { DebugStream::Stream1() << " Error, variable not yet supported" << std::endl; return NULL; } return var2; }