VTK的学习方法-第二类型应用
VTK的高级使用方法是自己写一个算法(Filter),本文使用的数据类型位polydata,这个数据类型应用比较广泛。
我们的算法一般是继承VTK里面的vtkpolydataalgorithm,然后自己添加一些变量,重写(override)里面的requestdata方法。
我们写一个增加噪声的方法吧。首先定义头文件如下
#ifndef MYNOISEFILTER
#define MYNOISEFILTER
#include <vtkPolyDataAlgorithm.h>
class myNoiseFilter:public vtkPolyDataAlgorithm{
public:
vtkTypeMacro(myNoiseFilter,vtkPolyDataAlgorithm);
static myNoiseFilter *New();
vtkSetMacro(NoiseVariance,double);
private:
myNoiseFilter(const myNoiseFilter&);
void operator=(const myNoiseFilter&);
double NoiseVariance;
protected:
myNoiseFilter(){}
~myNoiseFilter(){}
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override;
};
#endif // MYNOISEFILTER
然后是这个类的requestdata部分
#include "myNoiseFilter.h"
#include <vtkObjectFactory.h>
#include <vtkStreamingDemandDrivenPipeline.h>
#include <vtkInformationVector.h>
#include <vtkInformation.h>
#include <vtkMath.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
vtkStandardNewMacro(myNoiseFilter);
int myNoiseFilter::RequestData(vtkInformation *request,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector){
// Get the input and output
vtkInformation* inInfo=inputVector[0]->GetInformationObject(0);
vtkPolyData* input=vtkPolyData::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkInformation* outInfo=outputVector->GetInformationObject(0);
vtkPolyData* output=vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkMath::RandomSeed(time(NULL));
output->ShallowCopy(input);
vtkSmartPointer<vtkPoints> newPoints=vtkSmartPointer<vtkPoints>::New();
for(vtkIdType i=0;i<output->GetNumberOfPoints();++i){
double p[3];
output->GetPoint(i,p);
for(int j=0;j<3;++j){
double value=vtkMath::Random(-this->NoiseVariance,this->NoiseVariance);
p[j]+=value;
}
newPoints->InsertNextPoint(p);
}
output->SetPoints(newPoints);
return 1;
}
然后我们应用一下这个算法,看看结果如何?
#include <iostream>
#include "myNoiseFilter.h"
#include <vtkSphereSource.h>
#include <vtkPlaneSource.h>
#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkNew.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkProperty.h>
using namespace std;
int main(int,char**)
{
vtkSmartPointer<vtkPlaneSource> plane=vtkSmartPointer<vtkPlaneSource>::New();
plane->SetXResolution(10);
plane->SetYResolution(10);
plane->Update();
vtkSmartPointer<vtkPlaneSource> plane2=vtkSmartPointer<vtkPlaneSource>::New();
plane2->SetXResolution(10);
plane2->SetYResolution(10);
plane2->SetCenter(0,0,2);
plane2->Update();
vtkNew<vtkPolyDataMapper> planeMapper;
planeMapper->SetInputConnection(plane->GetOutputPort());
vtkNew<vtkActor> planeActor;
planeActor->SetMapper(planeMapper);
planeActor->GetProperty()->SetColor(0,1,0);
vtkSmartPointer<myNoiseFilter> noiseFilter=vtkSmartPointer<myNoiseFilter>::New();
noiseFilter->SetInputConnection(plane2->GetOutputPort());
noiseFilter->SetNoiseVariance(0.05);
noiseFilter->Update();
vtkNew<vtkPolyDataMapper> noiseMapper;
noiseMapper->SetInputConnection(noiseFilter->GetOutputPort());
vtkNew<vtkActor> noiseActor;
noiseActor->SetMapper(noiseMapper);
noiseActor->GetProperty()->SetColor(1,0,0);
vtkNew<vtkRenderer> ren;
ren->SetBackground(0.2,0.3,0.5);
ren->AddActor(planeActor);
ren->AddActor(noiseActor);
vtkNew<vtkRenderWindow> renWin;
renWin->SetSize(1024,1024);
renWin->AddRenderer(ren);
vtkNew<vtkRenderWindowInteractor> iren;
vtkNew<vtkInteractorStyleTrackballCamera> style;
iren->SetInteractorStyle(style);
iren->SetRenderWindow(renWin);
iren->Initialize();
iren->Start();
return 0;
}
运行结果如下图所示
图1 结果,绿色的是原始平面,红色是经过增加噪声后的平面。