笔者搜索发现大部分都讲vtk格式文件(.vtk),但都比较少讲怎么读取文件,其实vtk提供了许多方便的接口,相较于ugrid文件可能需要自己解析,标准vtk文件直接使用官方的接口读取即可。
一、读取非结构化网格文件
这里以非结构化网格为例。。。
#include <QCoreApplication>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkInteractionStyle)
#include <vtkUnstructuredGrid.h>
#include <vtkUnstructuredGridReader.h>
#include <vtkSmartPointer.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkProperty.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
vtkSmartPointer<vtkUnstructuredGridReader> unReader = vtkSmartPointer<vtkUnstructuredGridReader>::New();
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
unReader->SetFileName("C:\\Users\\Administrator\\Desktop\\VTK\\abc.vtk");
unReader->ReadAllVectorsOn();
unReader->ReadAllScalarsOn();
unReader->ReadAllFieldsOn();
unReader->Update();
mapper->SetInputData(unReader->GetOutput());
actor->SetMapper(mapper);
//actor->GetProperty()->SetRepresentationToWireframe();//渲染为线框图
actor->GetProperty()->SetRepresentationToSurface();//渲染为面
renderer->AddActor(actor);
renderWindow->AddRenderer(renderer);
renderWindow->Render();
auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
interactor->Start();
return a.exec();
}
二、读取标量矢量
先通过reader读到标量、矢量的数量,然后获取到标矢量的名字,并存起来,再设置reader单个的标量,使用vtkdoublearray拷贝reader中几何数据的标量数据,再得到array中的标量范围,并设置到mapper中,最后渲染即可。
#include <QCoreApplication>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkInteractionStyle)
#include <string>
#include <vector>
#include <vtkSmartPointer.h>
#include <vtkDataArray.h>
#include <vtkUnstructuredGrid.h>
#include <vtkUnstructuredGridReader.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <iostream>
#include <vtkDoubleArray.h>
#include <vtkPointData.h>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
vtkSmartPointer<vtkUnstructuredGridReader> unReader = vtkSmartPointer<vtkUnstructuredGridReader>::New();
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
unReader->SetFileName("C:\\Users\\Administrator\\Desktop\\VTK\\abc.vtk");
unReader->ReadAllVectorsOn();
unReader->ReadAllScalarsOn();
unReader->ReadAllFieldsOn();
unReader->Update();
int num1 = unReader->GetNumberOfScalarsInFile();//读取标量数量
int num2 = unReader->GetNumberOfVectorsInFile();//读取矢量数量
vector<string> scalarname_;
for(int i =0 ;i< num1;i++){
string scalarname = unReader->GetScalarsNameInFile(i);//取到每个标量名
scalarname_.push_back(scalarname);//存储每个标量名
}
vector<string> vectorname_;
for(int i =0;i<num2;i++){
string vectorname = unReader->GetVectorsNameInFile(i);//取到每个矢量
vectorname_.push_back(vectorname);//存储每个矢量
}
cout<<"------------scalarname---------"<<endl;
for(auto a: scalarname_){
cout<<"name: "<<a<<endl;//打印每个标量名
}
cout<<"------------vectorname----------"<<endl;
for(auto b:vectorname_){
cout<<"name: "<<b<<endl;//打印每个矢量名
}
mapper->SetInputData(unReader->GetOutput());
actor->SetMapper(mapper);
actor->GetProperty()->SetRepresentationToWireframe();//渲染为线框图
actor->GetProperty()->SetRepresentationToSurface();//渲染为面
renderer->AddActor(actor);
renderWindow->AddRenderer(renderer);
unReader->SetScalarsName(scalarname_[2].c_str());//设置单个的标量,vector存储了标量名,想显示哪个就传入哪个
unReader->Update();//刷新
vtkDoubleArray* array = vtkDoubleArray::New();
array->DeepCopy(((unReader->GetOutput())->GetPointData())->GetScalars());//使用doublearray拷贝除reader中非结构化网格的几何数据中的标量数据
array->Modified();
double range[2];
array->GetRange(range);//传入double型数组得到标量的范围,0--最小 1--最大
mapper->SetScalarRange(range[0],range[1]);//设置到mapper中
renderWindow->Render();//渲染
auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
interactor->Start();
return a.exec();
}
注释已经足够详尽,对照代码可以多琢磨,需要深入了解vtk的几何数据和拓扑数据。
最后赠言:智者不入爱河,牛马点缀生活!