QT&VTK(二) VTK读取所有.vtk文件的属性等相应操作

VTK可以处理的文件类型很多,这里介绍的是.vtk文件的读取,

1. 其中.vtk类型的文件有自己的定义格式,主要分为:几何结构和属性两部分,其中几何结构包括:坐标,拓扑形状的表述。拓扑即组成模型的单元形状,如一维的线,二维的三角形、平行四边形、多边形;三维的四面体、多边形等,根据不同的组成单元,VTK读入时才能知道将单元画成什么样的形状,因此.vtk文件中需说明,如三角形的代号是5,如何在vtk文件中表达,可以参考vtk格式的文档,Bing就有。单元的类型参考介绍VTK基本数据结构

2. 对于不同类型的数据,vtk读入时有不同的函数,如对于规则的四边形,vtk可用vtkstructuredGrid读入,这里参考不同类型的数据集为了通用,我再本项目中选择的vtkPolyData来存储数据。

3. 属性数据由vtkDataArray来表示。属性即单元或点上带有的参数性质,如电势,场强等。从第一类分有:POINT_DATA, CELL_DATA, FIELD_DATA,顾名思义,POINT_DATA就是表明该属性数据定义在点上,如电势,而像单元质量等可能就会被定义在单元上,FIELD_DATA表示既不是在点,又不是在单元上的属性,不常用,这里不再介绍。下图为以上知识点的总结 。

QT&VTK(二) VTK读取所有.vtk文件的属性等相应操作_第1张图片

2.1 属性数据的第二类分级就是:Scalars, Vecotrs, Tensors等 同样是根据名称可以得出,数据分为1维的张量,如电势;3维的矢量,如场强;9维的张量,如张力,注:VTK目前支持对称矩阵的张量。

4. 简单了解.vtk文件的定义后,我们就可以上代码了。有些变量我已经提前声明过了。

string vtkPath='test'
yReader=vtkSmartPointer<vtkDataSetReader>::New();
vtkPath=path.toStdString();
vtkPath.append(".vtk");
Reader->SetFileName(vtkPath.c_str());

Reader->ReadAllScalarsOn();
Reader->ReadAllVectorsOn();
Reader->ReadAllNormalsOn();
Reader->ReadAllTensorsOn();
Reader->ReadAllColorScalarsOn();
Reader->ReadAllTCoordsOn();
Reader->ReadAllFieldsOn();
Reader->GetOutput()->Register(Reader);

//首先读出所有Point和Cell 点属性
DatasetAttributesPoint= vtkSmartPointer <vtkDataSetAttributes> ::New();
DatasetAttributesCell= vtkSmartPointer <vtkDataSetAttributes> ::New();
vtkSmartPointer<vtkDataSet> DataSet=vtkSmartPointer<vtkDataSet> ::New()
DataSet=Reader->GetOutput();
DatasetAttributesPoint=DataSet->GetAttributes(0);// 读取所有POINT点
DatasetAttributesCell=DataSet->GetAttributes(1);// CELL enum编号为1,

// 获取文件中各种类型属性的数量
int numScalars=Reader->GetNumberOfScalarsInFile();
int numVectors=Reader->GetNumberOfVectorsInFile();
int numTensors=Reader->GetNumberOfTensorsInFile();

//读取所有类型属性的名称,并进行存储操作
 for(int i=0;i<numScalars;i++){
        const char* name=Reader->GetScalarsNameInFile(i);
        /*
        ...
        */
 }
 for(int i=0;i<numVectors;i++){
        const char* name=Reader->GetVectorsNameInFile(i);
                /*
        ...
        */
 }
 for(int i=0;i<numTensors;i++){
        const char* name=Reader->GetTensorsNameInFile(i);//
                /*
        ...
        */
 }

//按照名称获取属性
vtkSmartPointer<vtkDataArray> dataSet;
dataSet =DatasetAttributesCell->GetScalars(name.c_str());
dataSet =DatasetAttributesPoint->GetVectors(name.c_str());
dataSet=DatasetAttributesPoint->GetTensors(name.c_str());

vtkSmartPointer<vtkUnstructuredGridReader> MeshReader=vtkSmartPointer<vtkUnstructuredGridReader>::New();
MeshReader->SetFileName(vtkPath.c_str());
MeshReader->Update();
MeshPoints=MeshReader->GetOutput()->GetPoints();
MeshCells=MeshReader->GetOutput()->GetCells();
polyData=vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(MeshPoints);
polyData->SetPolys(MeshCells);

// 以下属性,按照实际情况选择代码
polyData->GetPointData()->SetScalars(dataSet);
polyData->GetPointData()->SetVectors(dataSet);
polyData->GetPointData()->SetTensors(dataSet);

polyData->GetCellData()->SetScalars(dataSet);
polyData->GetCellData()->SetVectors(dataSet);
polyData->GetCellData()->SetTensors(dataSet);

// 以下代码是在Qt中显示vk Widget的代码,所以没有单独的renderwindow.
vMapper->SetInputData(polyData);
vActor->SetMapper(vMapper);
surfaceWidget->GetRenderWindow()->AddRenderer(vRenderer);
vRenderer->AddActor(vActor);
surfaceWidget->update();
surfaceWidget->GetRenderWindow()->AddRenderer(yRenderer);
surfaceWidget->GetRenderWindow()->Render();

你可能感兴趣的:(VTK,qt)