VTK6引入了一些向后不兼容的更改。这里更详细地描述了这些变化背后的原因。其中一个更改是使用SetInputData()和SetInputConnection()替换SetInput()。
VTK4中管道对象连接连接
someFilter - > SetInput ( someReader - > GetOutput ());
VTK5中更改为
someFilter - > SetInputConnection ( someReader - > GetOutputPort ());
SetInput()和相关方法被保留为向后兼容性。
VTK6中 此方法和所有相关功能(如SetSource)在VTK 6中已被删除。这背后的主要原因是在将数据对象与管道对象分离(参见此处有详细信息)时,不可能保留此方法。在VTK 5中,SetInput()是使用SetInputConnection()实现的,但这需要访问该算法及其输出端口给定一个数据对象。在VTK 6中,由于数据对象不再引用生成它的算法,所以不可能建立仅给出数据对象的流水线连接。
为了便于将独立数据对象分配给算法的输入,我们在VTK 6中引入了一组方便的功能。下面是一个例子:
someFilter - > SetInputData ( aDataObject );
请注意,即使下面的代码将被编译,它不会创建一个管道连接,也不应该用于代替SetInputConnection()。
someFilter - > SetInputData ( someReader - > GetOutput ());
将数据对象与管道对象分离的另一个优点是开发人员不再需要创建输入副本,以便使用内部过滤器。 以前,这是算法正常运行所必需的:
1 void MyFilter::RequestData(…)
2 {
3 vtkDataObject* input = inInfo->Get(vtkDataObject::DATA_OBJECT());
4 vtkDataObject* copy = input->NewInstance();
5 copy->ShallowCopy(input);
6 this->InternalFilter->SetInput(copy);
7 this->InternalFilter->Update();
8 …
9 }
现在可以用以下代替
1 void MyFilter::RequestData(…)
2 {
3 vtkDataObject* input = inInfo->Get(vtkDataObject::DATA_OBJECT());
4 this->InternalFilter->SetInputData(input);
5 this->InternalFilter->Update();
6 …
7 }
另一个优点是,此更改会从管道中删除一些循环引用,从而无需使用垃圾回收器。这对使用大型管道时VTK的性能有明显的影响。
这种变化可能对VTK社区产生最大的影响。同时,这是最简单的解决方案。这是一个经验法则:
- 如果要建立管道连接,请使用SetInputConnection
- 如果要处理独立数据集,请使用SetInputData
以下是一些具体的例子。注意,即使我们在所有这些示例中使用SetInput(),类似的方法,如SetSource()也应该遵循相同的模式。查找SetSourceConnection()或SetSourceData()为例。此外,我们忽略这些示例中的端口号,但大多数应该使用端口号。
例子1
anotherFilter->SetInput(aFilter->GetOutput());
anotherFilter->SetInputConnection(aFilter->GetOutputPort());
例子2
1 vtkDataObject* output = aFilter->GetOutput();
2 anotherFilter->SetInput(output);
anotherFilter->SetInputConnection(aFilter->GetOutputPort());
例子3
1 vtkPolyData *pd = vtkPolyData::New();
2 aFilter->SetInput(pd);
1 vtkPolyData *pd = vtkPolyData::New();
2 aFilter->SetInputData(pd);
例子4
1 vtkDataObject* output = aFilter->GetOutput();
2 aFilter->Update();
3 anotherFilter->SetInput(output);
1 vtkDataObject* output = aFilter->GetOutput();
2 aFilter->Update();
3 anotherFilter->SetInputData(output);
例子5
1 void myfunction(vtkDataObject* dobj)
2 {
3 vtkAFilter* aFilter = vtkAFilter::New();
4 aFilter->SetInput(dobj);
5 aFilter->Update();
6 // …
7 }
This example is also ambiguous. You need to trace it up to find the origin of dobj. If this is the common use:
myfunction(aFilter->GetOutput());
you will have to refactor myfunction to take an algorithm and an output port. For example:
1 void myfunction(vtkAlgorithm* alg, int port)
2 {
3 vtkAFilter* aFilter = vtkAFilter::New();
4 aFilter->SetInputConnection(alg->GetOutputPort(port));
5 aFilter->Update();
6 // …
7 }
8
9 myfunction(aFilter, 0);
If this is the common use:
1 vtkPolyData* pd = vtkPolyData::New();
2 // fill pd
3 myfunction(pd);
then replacing SetInput() with SetInputData() would work.
例子
1 #include "vtkAutoInit.h"
2 VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
3 VTK_MODULE_INIT(vtkInteractionStyle);
4
5 #include <vtkConeSource.h>
6 #include <vtkCubeSource.h>
7 #include <vtkCylinderSource.h>
8 #include <vtkSphereSource.h>
9 #include <vtkPolyDataMapper.h>
10 #include <vtkRenderer.h>
11 #include <vtkRenderWindow.h>
12 #include <vtkActor.h>
13 #include <vtkRenderWindowInteractor.h>
14 #include <vtkSmartPointer.h>
15
16 int main()
17 {
18 vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();
19 vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
20 vtkSmartPointer<vtkCylinderSource> cylinder = vtkSmartPointer<vtkCylinderSource>::New();
21 vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
22
23 vtkSmartPointer<vtkPolyDataMapper> coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
24 coneMapper->SetInputData(cone->GetOutput());//SetInput改为SetInputData
25 vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
26 cubeMapper->SetInputData(cube->GetOutput());
27 vtkSmartPointer<vtkPolyDataMapper> cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
28 cylinderMapper->SetInputData(cylinder->GetOutput());
29 vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
30 sphereMapper->SetInputData(sphere->GetOutput());
31
32 vtkSmartPointer<vtkActor> coneActor = vtkSmartPointer<vtkActor>::New();
33 coneActor->SetMapper(coneMapper);
34 vtkSmartPointer<vtkActor> cubeActor = vtkSmartPointer<vtkActor>::New();
35 cubeActor->SetMapper(cubeMapper);
36 vtkSmartPointer<vtkActor> cylinderActor = vtkSmartPointer<vtkActor>::New();
37 cylinderActor->SetMapper(cylinderMapper);
38 vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
39 sphereActor->SetMapper(sphereMapper);
40
41
42 vtkSmartPointer<vtkRenderer> renderer1 = vtkSmartPointer<vtkRenderer>::New();
43 renderer1->AddActor(coneActor);
44 renderer1->SetBackground(1.0, 0.0, 0.0);
45 renderer1->SetViewport(0.0, 0.0, 0.5, 0.5);
46 vtkSmartPointer<vtkRenderer> renderer2 = vtkSmartPointer<vtkRenderer>::New();
47 renderer2->AddActor(cubeActor);
48 renderer2->SetBackground(0, 0, 0);
49 renderer2->SetViewport(0.5, 0.0, 1.0, 0.5);
50 vtkSmartPointer<vtkRenderer> renderer3 = vtkSmartPointer<vtkRenderer>::New();
51 renderer3->AddActor(cylinderActor);
52 renderer3->SetBackground(0.0, 0.0, 1.0);
53 renderer3->SetViewport(0.0, 0.5, 0.5, 1.0);
54 vtkSmartPointer<vtkRenderer> renderer4 = vtkSmartPointer<vtkRenderer>::New();
55 renderer4->AddActor(sphereActor);
56 renderer4->SetBackground(1.0, 1.0, 0.0);
57 renderer4->SetViewport(0.5, 0.5, 1.0, 1.0);
58
59 vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
60 renWin->AddRenderer(renderer1);
61 renWin->AddRenderer(renderer2);
62 renWin->AddRenderer(renderer3);
63 renWin->AddRenderer(renderer4);
64 renWin->SetSize(640, 480);
65 renWin->Render();
66 renWin->SetWindowName("Viewport");
67
68 vtkSmartPointer<vtkRenderWindowInteractor> interactor =
69 vtkSmartPointer<vtkRenderWindowInteractor>::New();
70 interactor->SetRenderWindow(renWin);
71
72 renWin->Render();
73 interactor->Initialize();
74 interactor->Start();
75
76 return EXIT_SUCCESS;
77 }
会提示MetaImage cannot read data from file或者显示窗口是空白,后来搜索了VTKExample中的例子,发现可以这样解决:
imgActor->SetInput(colorMap->GetOutput());
改为
imgActor->GetMapper()->SetInputConnection(colorMap->GetOutputPort());
同时添加头文件
#include <vtkImageMapper3D.h>