在vtk中颜色映射是可视化技术中最常用的,是根据属性值来对物体进行着色,将颜色查找表中的颜色映射到点或单元的属性值上,绘制时就可以用这些颜色值来绘制点和单元了。
接下来编写一个梯形实例来体现颜色映射算法,写代码前我们需要做如下准备:
- 属性数据
首先要介绍的是vtkDataSet这个类,vtkDataSet是所以数据集的父类,这里谈的可视化也都是对vtkDataSet数据对象进行的可视化,当然了,vtkPolyData、vtkImageData等子类也同样适用。
属性数据可以被表示为标量、张量、矢量、法向量等形式。vtk中包括点属性数据和单元属性数据,每个属性数据都分别和vtkDataSet数据相关联。可以用vtkDataArray 的子类来存储,vtkFloatArray等。
讲了这么多属性数据的概念就是为了创建属性数据为颜色映射做准备,通常可以按这个顺序进行创建:创建数组->分配大小->与数据集关联。 - 可视化多边形
多边形数据由点、线、三角形、三角带、多边形等基本单元构成(vtkPolyData),大部分过滤器都可以对这些数据进行处理。有些过滤器(比如vtkDecimatePro 和vtkTubeFilter)仅仅处理这种类型数据的一部分(三角网格和线)。
首先构造多边形数据,可以通过创建vtkPoints和vtkCellArrays的对象来存储点和单元,然后构造多边形数据,最后进行映射。 - 颜色查找表
我们可以手动创建一个颜色查找表,如果没有创造的话,贴心的vtk会自动为我们生成一个默认的颜色查找表,颜色查找表中允许我们自由设定颜色值。vtkLookupTable可以帮助我们来完成这个工作,同时,设定了颜色数量时,SetTabValue()方法可以将颜色值插入到指定的位置。另外,SetScalarRange()告诉我们采取什么方法映射,标量值大于最大值的将被归为最大值,标量值小于最小值的将被归为最小,因为颜色索引是根据属性的最值建立的。
准备工作做完了,下面直接贴代码,相应的注释跟在代码后面。
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkConeSource.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include <vtkLookupTable.h>
int main()
{
int i;
//梯形的顶点坐标
static float x[8][3]={{0,0,0}, {4,0,0}, {4,4,0}, {0,4,0},
{1,1,1}, {3,1,1}, {3,3,1}, {1,3,1}};
//4个顶点构成一个单元,一共6个单元
static vtkIdType y[6][4]={{0,1,2,3}, {4,5,6,7}, {0,1,5,4},
{1,2,6,5}, {2,3,7,6}, {3,0,4,7}};
vtkPoints *points = vtkPoints::New();
for(i=0;i<8;i++)
points->InsertPoint(i,x[i]);
vtkCellArray *polys = vtkCellArray::New();
for(i=0;i<6;i++)
polys->InsertNextCell(4,y[i]);
//存储标量值
vtkFloatArray *scalars = vtkFloatArray::New();
for(i=0;i<8;i++)
scalars->InsertTuple1(i,i);
//构建多边形数据
vtkPolyData *cube = vtkPolyData::New();
cube->SetPoints(points);
//设定单元的组成方式
cube->SetPolys(polys);
cube->GetPointData()->SetScalars(scalars);
//定义颜色映射表
vtkLookupTable *pColorTable=vtkLookupTable::New();
pColorTable->SetNumberOfColors(6);
pColorTable->SetTableValue(0,1.0,0.0,1.0,1.0);
pColorTable->SetTableValue(1,0.0,1.0,1.0,1.0);
pColorTable->SetTableValue(2,1.0,1.0,1.0,1.0);
pColorTable->SetTableValue(3,1.0,0.0,1.0,1.0);
pColorTable->SetTableValue(4,0.0,0.0,1.0,1.0);
pColorTable->SetTableValue(5,1.0,1.0,0.0,1.0);
pColorTable->Build();
//数据映射
vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New();
cubeMapper->SetInput(cube);
cubeMapper->SetScalarRange(0,7);
cubeMapper->SetLookupTable(pColorTable);
vtkActor *cubeActor = vtkActor::New();
cubeActor->SetMapper(cubeMapper);
vtkCamera *camera = vtkCamera::New();
camera->SetPosition(1,1,1);
camera->SetFocalPoint(0,0,0);
vtkRenderer *renderer = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(renderer);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
renderer->AddActor(cubeActor);
renderer->SetActiveCamera(camera);
renderer->ResetCamera();
renderer->SetBackground(1,1,1);
renWin->SetSize(400,400);
renWin->Render();
iren->Start();
//删除
points->Delete();
polys->Delete();
scalars->Delete();
cube->Delete();
cubeMapper->Delete();
cubeActor->Delete();
camera->Delete();
renderer->Delete();
renWin->Delete();
iren->Delete();
pColorTable->Delete();
return 0;
}