相信很多做研究的人都在使用VTK,其实VTK的学习分成两类。一类就是使用VTK中现有的算法来完成自己的工作,比如数据的显示和渲染。另外一类是需要继承里面的算法类,自己根据自己的需求来重新写一个算法。
对于第一种类型的应用,不要觉得使用C++来写代码会很复杂,其实不复杂。此种应用一般都是从数据源出发,然后顺着数据流管线一路往下走,最后显示。是面向过程的。
图1 简单的VTK管线流
下面的一个例子,就是这样的一个简单的应用,使用了AppendFilter算法。
#include <vtkActor.h>
#include <vtkAppendFilter.h>
#include <vtkDataSetMapper.h>
#include <vtkGlyph3DMapper.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPointSource.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkUnstructuredGrid.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <iostream>
vtkSmartPointer<vtkActor> Point2Glyph(vtkPoints* points,double const& scale);
int main(int,char**)
{
// Create 9 points
vtkNew<vtkPointSource> pointSource;
pointSource->SetNumberOfPoints(9);
pointSource->Update();
vtkSmartPointer<vtkPolyData> polydata=pointSource->GetOutput();
std::cout<<"There are "<<polydata->GetNumberOfPoints()
<<" points in the polydata set."<<std::endl;
// Create 2 points in a vtkUnstructuredGrid
vtkNew<vtkPoints> points;
points->InsertNextPoint(0,0,0);
points->InsertNextPoint(0,0,1);
vtkNew<vtkUnstructuredGrid> ug;
ug->SetPoints(points);
std::cout<<"There are "<<ug->GetNumberOfPoints()
<<" points in the unstructured grid."<<std::endl;
// Combine the two data sets
vtkNew<vtkAppendFilter> appendFilter;
appendFilter->AddInputData(polydata);
appendFilter->AddInputData(ug);
appendFilter->Update();
vtkSmartPointer<vtkUnstructuredGrid> combined=appendFilter->GetOutput();
std::cout<<"There are "<<combined->GetNumberOfPoints()
<<" points combined."<<std::endl;
// Create a mapper and actor
vtkNew<vtkNamedColors> colors;
vtkNew<vtkDataSetMapper> mapper;
mapper->SetInputConnection(appendFilter->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
vtkSmartPointer<vtkActor> sphereActor=Point2Glyph(appendFilter->GetOutput()->GetPoints(),0.25);
sphereActor->GetProperty()->SetColor(colors->GetColor3d("Gold").GetData());
// Create renderer window and interactor
vtkNew<vtkRenderer> ren;
vtkNew<vtkRenderWindow> renWin;
renWin->SetSize(1024,1024);
renWin->AddRenderer(ren);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
vtkNew<vtkInteractorStyleTrackballCamera> style;
iren->SetInteractorStyle(style);
ren->AddActor(actor);
ren->AddActor(sphereActor);
ren->SetBackground(colors->GetColor3d("RoyalBlue").GetData());
iren->Initialize();
iren->Start();
return 0;
}
vtkSmartPointer<vtkActor> Point2Glyph(vtkPoints* points,double const& scale){
double* bounds=points->GetBounds();
double maxLen=0;
for(int i=1;i<3;++i){
maxLen=std::max(bounds[i+1]-bounds[i],maxLen);
}
vtkNew<vtkSphereSource> sphereSource;
sphereSource->SetRadius(scale*maxLen);
sphereSource->SetThetaResolution(30);
sphereSource->SetPhiResolution(30);
vtkNew<vtkPolyData> pd;
pd->SetPoints(points);
vtkNew<vtkGlyph3DMapper> mapper;
mapper->SetInputData(pd);
mapper->SetSourceConnection(sphereSource->GetOutputPort());
mapper->ScalarVisibilityOff();
mapper->ScalingOff();
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
return actor;
}
输出的结果如下:
图2 输出结果