VTK应用程序所需的数据可以通过两种途径获取:第一种是生成模型,然后处理这些模型数据(如由类 vtkCylinderSource 生成的多边形数据);第二种是从外部存储介质里导入相关的数据文件,然后在应用程序中处理这些读入的数据(如vkBMPReader 读取 BMP图像)。
另一方面,VTK也可以将程序中处理完成的数据写入单个文件中,或者将所渲染的场景导出,以备后续操作的使用。从可视化管线的角度来看,一般以数据的读取(或由模型创建数据)开始,而以数据的写盘操作(或Mapper)结束。
一、Reader 与 Writer 类
VTK的Reader类要将外部数据读入可视化管线,主要的步骤如下:
1)实例化 Reader 对象。
2)指定所要读取的文件名。
3)调用 Update()方法促使管线执行。当管线后续的Fiter有Update()请求时,如调用Render()方法管线就会读取相应的图像文件,所以这一步有时也可省略。
使用 Writer 类的主要步骤如下:
1)实例化 Writer 对象。
2)输入要写盘的数据以及指定待写盘的了件名。
3)调用 Write0)方法促使 Writer 类开始写盘操作。
1、vtkImageData类型
读取单个文件示例代码:
#include <vtkImageViewer2.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPNGReader.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkJPEGWriter.h>
int main()
{
//读取 PNG 图像
vtkSmartPointer<vtkPNGReader> reader = vtkSmartPointer<vtkPNGReader>::New();
reader->SetFileName("D:/VTK-logo.png");
//显示读取的单幅 PNG 图像
vtkSmartPointer<vtkImageViewer2> imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
imageViewer->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
imageViewer->SetupInteractor(renderWindowInteractor);
imageViewer->Render();
imageViewer->GetRenderer()->ResetCamera();
imageViewer->Render();
//保存成 JPG 图像
vtkSmartPointer<vtkJPEGWriter> writer = vtkSmartPointer<vtkJPEGWriter>::New();
writer->SetFileName("VTK-logo.jpg");
writer->SetInputConnection(reader->GetOutputPort());
writer->Write();
renderWindowInteractor->Start();
}
在读取图像文件时,如果无法确定所读取的图像是什么格式,可以使用vtkImageReader2Factory 来读取要导入的文件,该类会试着寻找一种最适合的类对图像做读取操作,这个类可以读取大部分标准格式的图像文件。
vtkSmartPointer<vtkImageReader2Factory> readerFactory = vtkSmartPointer<vtkImageReader2Factory>::New();
vtklmageReader2 * reader = readerFactory->CreateImageReader2("../VTK-logo");
reader->SetFileName("../VTK-logo");
reader->Update();
读取序列图像文件示例代码:
#include <vtkImageViewer2.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkJPEGReader.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
int main()
{
//生成图像序列的文件名数组
vtkSmartPointer< vtkStringArray > fileArray= vtkSmartPointer< vtkStringArray >::New();
char fileName[128];
for(int i= 1; i< 100; i++)
{
sprintf(fileName, "D:/Head/head%03d.jpg", i);
vtkStdString fileStr(fileName);
fileArray->InsertNextValue(fileStr);
}
//读取 JPG序列图像
vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileNames(fileArray);
//显示读取的 JPG 图像
vtkSmartPointer<vtkImageViewer2> imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
imageViewer->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New();
imageViewer->SetSlice(50); //默认显示第50个切片(即第50 层)
imageViewer->SetSliceOrientationToXY();
//imageViewer->SetSliceOrientationToYZ();
//imageViewer->SetSliceOrientationToXZ();
imageViewer->SetupInteractor(renderWindowInteractor);
imageViewer->Render();
renderWindowInteractor->Start();
return 0;
}
读取的文件及示例运行结果
2、vtkPolyData类型
3、vtkRectilinearGrid 类型
4、vtkStructuredGrid 类型
5、vtkUnstructuredGrid 类型
二、场景的导入和导出
场景的导入(Import)与导出(Export)是指将渲染场景中的对象,包括光照、相机、属性、变换矩阵等信息写入文件中,或者从外部文件中将这些对象导入渲染场景中,一般所导入的文件含有多个数据集。
VTK 中一般以关键字 Importer 和Exporter 命名的类是与场景的导入与导出相关的。Importer 类可以导入由其他 3D 模型软件(如 3DS MAX)所生成的模型文件;Exporter 则可以将 VTK里的场景生成可被其他 3D模型软件所处理的文件。
VTK 支持的 Import 类包括 vtk3DSImporter 和vtkVRMLImporter;而支持的 Exporter 类则相对要多一些,主要有 vkRIBExporter、vtkGL2PSExporter、vtkIVExporter、vtkOBJExporer、vtkOOGLExporter、vtkVRMLExporter、vtkPOVExporter、vtkX3DExporter 等。
示例代码:
// 3DS Import
vtkSmartPointer<vtk3DSImporter> importer = vtkSmartPointer<vtk3DSImporter>::New();
importer->SetFileName ( filename.c_str() );
importer->ComputeNormalsOn();
importer->Read();
vtkSmartPointer<vtkRenderer> renderer = importer->GetRenderer();
vtkSmartPointer<vtkRenderWindow> renderWindow = importer->GetRenderWindow();
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
三、总结
本文主要介绍了处于 VTK 可视化管线两端的类,即读操作和写操作相关的类。VTK 针对不同的数据类型,提供了不同的读写类,对于类的使用者而言,最重要的是根据不同的文件类型选择合适的 Reader/Writer 类进行读写操作。
另外,VTK 还可以导入由其他 3D 模型软件所生成的文件,也可将VTK 里生成的数据写成可被其他3D模型软件所处理的模型文件,这样有利于VTK与其他主流的模型软件的结合。