本程序为《VTK图形图像开发进阶》随书代码,本人结合教材和其他资源对其进行完整注释,方便初学者理解VTK体绘制用法。
95%代码包含注释,并涵盖所需知识讲解。
/**********************************************************************
文件名: 7.1_VolumeRenderingApp.cpp
Copyright (c) 张晓东, 罗火灵. All rights reserved.
更多信息请访问:
http://www.vtkchina.org (VTK中国)
http://blog.csdn.net/www_doling_net (东灵工作室)
**********************************************************************/
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkStructuredPoints.h>
#include <vtkStructuredPointsReader.h>
#include <vtkVolumeRayCastCompositeFunction.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkVolumeRayCastMapper.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkVolumeProperty.h>
#include <vtkAxesActor.h>
#include <vtkImageShiftScale.h>
#include <vtkImageCast.h>
#include <vtkFixedPointVolumeRayCastMapper.h>
//测试:../data/mummy.128.vtk
int main(int argc, char *argv[])
{
//Mapper输入1
vtkSmartPointer<vtkStructuredPointsReader> reader = vtkSmartPointer<vtkStructuredPointsReader>::New();
reader->SetFileName(argv[1]);//读取输入图像数据
reader->Update();
//Mapeer输入2
vtkSmartPointer<vtkVolumeRayCastCompositeFunction> rayCastFun = vtkSmartPointer<vtkVolumeRayCastCompositeFunction>::New();
//定义一个光线体绘制Mapper,主要接受如下两个输入
vtkSmartPointer<vtkVolumeRayCastMapper> volumeMapper = vtkSmartPointer<vtkVolumeRayCastMapper>::New();
volumeMapper->SetInputData(reader->GetOutput());//该函数设置输入图像数据
volumeMapper->SetVolumeRayCastFunction(rayCastFun);//该函数用于设置光线投射函数类型
//设置光线采样步长,默认采样步长为1
//volumeMapper->SetSampleDistance(volumeMapper->GetSampleDistance()*4);//步长越小,采样点越多,渲染效果越精细,
//设置图像采样距离,默认采样距离为1
//volumeMapper->SetAutoAdjustSampleDistances(0);//自动调节采样距离功能,设置0即关闭,默认情况下开启以保证交互时的实时性
//volumeMapper->SetImageSampleDistance(4);//设置图像采样距离函数(使用前,上行函数关闭),即投射光线的间距.图像采样距离为1/0.5/2,每个像素对应1/4条投射光线/每四个像素对应一条投射光线
//定义体绘制属性对象,并设置不透明度传输函数/梯度不透明度函数和颜色传输函数以及阴影
vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetInterpolationTypeToLinear();//设置线性插值方式
//volumeProperty->ShadeOn();//volumeProperty->ShadeOn();//vtkVolumeProperty默认关闭阴影效果,需要显示则调用ShadeOn()函数来打开阴影效果
volumeProperty->SetAmbient(0.4);//设置环境光系数
volumeProperty->SetDiffuse(0.6);//设置散射光系数
volumeProperty->SetSpecular(0.2);//设置反射光系数//一般情况下,三者和为一
vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity = vtkSmartPointer<vtkPiecewiseFunction>::New();
compositeOpacity->AddPoint(70, 0.00);//(灰度值1,不透明度1)
compositeOpacity->AddPoint(90, 0.40);//(灰度值2,不透明度2)
compositeOpacity->AddPoint(180, 0.60);//(灰度值3,不透明度3)
volumeProperty->SetScalarOpacity(compositeOpacity); //设置灰度不透明度传输函数
//测试隐藏部分数据,对比不同的设置
//compositeOpacity->AddPoint(120, 0.00);
//compositeOpacity->AddPoint(180, 0.60);
//volumeProperty->SetScalarOpacity(compositeOpacity);
vtkSmartPointer<vtkPiecewiseFunction> volumeGradientOpacity = vtkSmartPointer<vtkPiecewiseFunction>::New();
volumeGradientOpacity->AddPoint(10, 0.0);//(梯度值1,不透明度乘子1)
volumeGradientOpacity->AddPoint(90, 0.5);//(梯度值2,不透明度乘子2)
volumeGradientOpacity->AddPoint(100, 1.0);//(梯度值3,不透明度乘子3)
//volumeProperty->SetGradientOpacity(volumeGradientOpacity);//设置梯度不透明度效果对比
vtkSmartPointer<vtkColorTransferFunction> color = vtkSmartPointer<vtkColorTransferFunction>::New();
color->AddRGBPoint(0.000, 0.00, 0.00, 0.00);//(灰度值1,r1,g1,b1)
color->AddRGBPoint(64.00, 1.00, 0.52, 0.30);//(灰度值2,r2,g2,b2)
color->AddRGBPoint(190.0, 1.00, 1.00, 1.00);//(灰度值3,r3,g3,b3)
color->AddRGBPoint(220.0, 0.20, 0.20, 0.20);//(灰度值4,r4,g4,b4)
volumeProperty->SetColor(color);//颜色传输函数,与不透明度传输函数使用类似
//与vtkActor作用一致,需要设置如下两个输入
vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(volumeMapper);//该函数用于设置Mapper对象
volume->SetProperty(volumeProperty);//该函数用于设置属性对象
// 整个剧院就好比VTK程序的渲染窗口(vtkRenderWindow); 舞台就相当于渲染场景(vtkRenderer);
// 而那些演员就是程序中的Actor, 台上演员与台下观众的互动可以看作与应用程序的交互(vtkRenderWindowInteractor);
// 演员与观众的互动方式有很多种,现场的观众可以直接上台跟演员们握手拥抱,电视机前的可以发短信,计算机前的可以微博关注等,
// 这就好比程序中的交互器样式(vtkInteractorStyle); 对于舞台上的演员,观众都可以一一分辨出来,不会弄混,是因为他们穿着打扮、容貌都不一样,
// 这就相当于程序中vtkActor的不同性(vtkProperty); 台下观众的眼睛可以看作vtkCamera, 前排的观众因为离得近,在观看台上演员时会觉得他们比较高大,
// 而后排的观众因为离得远,所以那些演员看起来就会显得小些,每位观众看到的东西在他 / 她的世界里都是唯一的,
// 所以渲染场景Renderer 里的vtkCamera对象也是只有一一个; 舞台上的灯光可以有多个,所以渲染场景里的vtkLight也存在多个。
//定义vtkRenderer,vtkRenderWindow,vtkRenderWindowInteractor对象,建立可视化管线
vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();//负责管理场景的渲染过程.组成场景的对象包括Prop,照相机(vtkCamera)和光照(vtkLight)都被整合到一个vtkRenderer对象中.
ren->SetBackground(1.0, 1.0, 1.0);//用于设置渲染场景的背景颜色,用rgb的格式设置
ren->AddVolume( volume ); //AddActor(),该方法用于将vtkProp类型的对象添加到渲染场景
vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();//把操作系统与VTK渲染引擎连接到一起.
renWin->AddRenderer(ren);//加入vtkRenderer对象.一个vtkRenderWindow可以有多个vtkRenderWindow对象
renWin->SetSize(640, 480);//用于设置窗口的大小,以像素为单位
renWin->Render();//显示并渲染VTK窗口
renWin->SetWindowName("VolumeRenderingApp");
vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();//提供平台独立的响应鼠标/键盘和时钟事件的交互机制
iren->SetRenderWindow(renWin);//用于设置渲染窗口
ren->ResetCamera();//重置相机参数
renWin->Render();//渲染
iren->Start();//该方法表示开始进入事件响应循环
return EXIT_SUCCESS;
}
//在几何渲染中,通常使用vtkActor来渲染几何图形数据,使用vtkImageActor来渲染图像数据;
//在体绘制中,则使用vtkVolume渲染数据。
//在几何渲染中,通常采用vtkPolyDataMapper实现输入数据向图元数据的转换;
//在体绘制中,则采用的是vtkVolumeRayCastMapper, 这是与体绘制算法有关的,不同的体绘制算法会有不同的Mapper类,通常在上面代码中直接替换为相应的Mapper类即可。