1.裁剪
对于一些体积比较大,结构比较复杂的体数据进行体绘制的渲染效果难以展示其内部细节,需要用到裁剪技术来渲染部分数据。vtkVolumeMapper类中提供了两种裁剪技术,分别为Cropping和Clipping。
Cropping技术只支持VTKImageData数据的裁剪。该方法在每个坐标轴上定义两个裁剪面,共有6个裁剪面(xmin,xmax,ymin,ymax,zmin,zmax)。将三维空间分为27个可视区域。这些裁剪面仅与数据的原点和像素尺寸有关,而不依赖于数据的任何坐标运算,因此可以使用27位数字来定义这些区域,每一位表示一个区域。当某位上数字为1时,说明显示其对应的区域。在这些区域中,小于(xmin,ymin)的区域为第一位,然后根据先X方向,再Y轴方向,最后Z轴方向的顺序来定义每个区域的位号。例如,当只显示中间区域时,其对应的27位数字为0x0002000.
2.基于Cropping的裁剪技术
vtkVolumeMapper中定义了Cropping接口函数,使用Cropping进行裁剪的代码如下:
volumeMapper->SetCropping(1);//开启Cropping功能 volumeMapper->SetCroppingRegionPlanes(50, 150, 50, 200, 50, 150); volumeMapper->SetCroppingRegionFlags(0x0002000);
其中:
- vtkVolumeMapper::SetCropping(1),设置裁剪功能;
- vtkVolumeMapper::SetCroppingRegionPlanes(),设置三个坐标轴上六个裁剪面位置。
- vtkVolumeMapper::SetCroppingRegionFlag(),设置显示区域标记。
- 此外,该类也提供了其他成员函数设置显示区域,避免自行计算显示区域标记:
- SetCroppingRegionFlagsToSubVolume();
- SetCroppingRegionFlagsToFence();
- SetCroppingRegionFlagsToInvertedFence();
- SetCroppingRegionFlagsToCross();
- SetCroppingRegionFlagsToInvertedCross();
示例代码如下:
#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); VTK_MODULE_INIT(vtkRenderingVolumeOpenGL); VTK_MODULE_INIT(vtkRenderingFreeType); VTK_MODULE_INIT(vtkInteractionStyle); #include <vtkSmartPointer.h> #include <vtkStructuredPoints.h>//vtkStructuredPointsReader* -> vtkGPUVolumeRayCastMapper* #include <vtkStructuredPointsReader.h> #include <vtkGPUVolumeRayCastMapper.h> #include <vtkVolumeProperty.h> #include <vtkPiecewiseFunction.h> #include <vtkColorTransferFunction.h> #include <vtkVolume.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkCamera.h> int main() { vtkSmartPointer<vtkStructuredPointsReader> reader = vtkSmartPointer<vtkStructuredPointsReader>::New(); reader->SetFileName("mummy.128.vtk"); reader->Update(); vtkSmartPointer<vtkGPUVolumeRayCastMapper> origMapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New(); origMapper->SetInputData(reader->GetOutput()); vtkSmartPointer<vtkGPUVolumeRayCastMapper> volumeMapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New(); volumeMapper->SetInputData(reader->GetOutput()); volumeMapper->SetCropping(1);//开启Cropping功能 volumeMapper->SetCroppingRegionPlanes(50, 150, 50, 200, 50, 150); volumeMapper->SetCroppingRegionFlags(0x0002000); /*****************************************************************/ //设置体绘制相关属性 vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New(); volumeProperty->SetInterpolationTypeToLinear(); //设置线性插值方式 volumeProperty->ShadeOn();//开启阴影属性 volumeProperty->SetAmbient(0.4);//设置环境温度 volumeProperty->SetDiffuse(0.6);//设置漫反射系数 volumeProperty->SetSpecular(0.2);//设置镜面反射系数 //添加灰度不透明度属性 vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity = vtkSmartPointer<vtkPiecewiseFunction>::New(); compositeOpacity->AddPoint(70, 0.0); compositeOpacity->AddPoint(90, 0.4); compositeOpacity->AddPoint(180, 0.6); volumeProperty->SetScalarOpacity(compositeOpacity); //添加梯度不同明度属性 vtkSmartPointer<vtkPiecewiseFunction> gradientOpacity = vtkSmartPointer<vtkPiecewiseFunction>::New(); gradientOpacity->AddPoint(10, 0.0); gradientOpacity->AddPoint(90, 0.5); gradientOpacity->AddPoint(100, 1.0); volumeProperty->SetGradientOpacity(gradientOpacity); //添加颜色传输 vtkSmartPointer<vtkColorTransferFunction> color = vtkSmartPointer<vtkColorTransferFunction>::New(); color->AddRGBPoint(0, 0, 0, 0); color->AddRGBPoint(64, 1.0, 0.52, 0.3); color->AddRGBPoint(190.0, 1.00, 1.00, 1.00); color->AddRGBPoint(220.0, 0.20, 0.20, 0.20); volumeProperty->SetColor(color); /***********************************************************/ //渲染管道 vtkSmartPointer<vtkVolume> origVolume = vtkSmartPointer<vtkVolume>::New(); origVolume->SetMapper(origMapper); origVolume->SetProperty(volumeProperty); vtkSmartPointer<vtkVolume> croppingVolume = vtkSmartPointer<vtkVolume>::New(); croppingVolume->SetMapper(volumeMapper); croppingVolume->SetProperty(volumeProperty); / double origView[4] = { 0, 0, 0.5, 1 }; double croppingView[4] = { 0.5, 0, 1, 1 }; vtkSmartPointer<vtkRenderer> origRender = vtkSmartPointer<vtkRenderer>::New(); origRender->AddVolume(origVolume); origRender->SetBackground(1, 1, 0); origRender->SetViewport(origView); vtkSmartPointer<vtkRenderer> croppingRender = vtkSmartPointer<vtkRenderer>::New(); croppingRender->AddVolume(croppingVolume); croppingRender->SetBackground(0, 1, 0); croppingRender->SetViewport(croppingView); /// vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New(); rw->AddRenderer(origRender); rw->AddRenderer(croppingRender); rw->SetWindowName("Cropping Volume"); rw->SetSize(640, 320); vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New(); rwi->SetRenderWindow(rw); origRender->GetActiveCamera()->SetPosition(0, -1, 0); origRender->GetActiveCamera()->SetFocalPoint(0, 0, 0); origRender->GetActiveCamera()->SetViewUp(0,0,1); origRender->GetActiveCamera()->Azimuth(30); origRender->GetActiveCamera()->Elevation(30); origRender->ResetCamera(); croppingRender->SetActiveCamera(origRender->GetActiveCamera()); rw->Render(); rwi->Start(); return 0; }
输出结果如下: