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 outputvtkInformation* 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 结果,绿色的是原始平面,红色是经过增加噪声后的平面。