1. 程式人生 > >VTK學習(一)SetInputData()和SetInputConnection()替換SetInput()

VTK學習(一)SetInputData()和SetInputConnection()替換SetInput()

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. }
現在可以用以下代替
  1. void MyFilter::RequestData(…)
  2. {
  3. vtkDataObject* input = inInfo->Get(vtkDataObject::DATA_OBJECT());
  4. this->InternalFilter->SetInputData(input);
  5. this->InternalFilter->Update();
  6. }

另一個優點是,此更改會從管道中刪除一些迴圈引用,從而無需使用垃圾回收器。這對使用大型管道時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. 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.

https://www.vtk.org/Wiki/VTK/VTK_6_Migration/Replacement_of_SetInput

例子

  1. #include "vtkAutoInit.h"
  2. VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
  3. VTK_MODULE_INIT(vtkInteractionStyle);
  4. /**********************************************************************
  5. 檔名: 2.3_Viewport.cpp
  6. Copyright (c) 張曉東, 羅火靈. All rights reserved.
  7. 更多資訊請訪問:
  8. http://www.vtkchina.org (VTK中國)
  9. http://blog.csdn.net/www_doling_net (東靈工作室)
  10. **********************************************************************/
  11. /**********************************************************************
  12. 檔名: 2.3_Viewport.cpp
  13. Copyright (c) 張曉東, 羅火靈. All rights reserved.
  14. 更多資訊請訪問:
  15. http://www.vtkchina.org (VTK中國)
  16. http://blog.csdn.net/www_doling_net (東靈工作室)
  17. **********************************************************************/
  18. #include <vtkConeSource.h>
  19. #include <vtkCubeSource.h>
  20. #include <vtkCylinderSource.h>
  21. #include <vtkSphereSource.h>
  22. #include <vtkPolyDataMapper.h>
  23. #include <vtkRenderer.h>
  24. #include <vtkRenderWindow.h>
  25. #include <vtkActor.h>
  26. #include <vtkRenderWindowInteractor.h>
  27. #include <vtkSmartPointer.h>
  28. int main()
  29. {
  30. vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();
  31. vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
  32. vtkSmartPointer<vtkCylinderSource> cylinder = vtkSmartPointer<vtkCylinderSource>::New();
  33. vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
  34. vtkSmartPointer<vtkPolyDataMapper> coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  35. coneMapper->SetInputData(cone->GetOutput());//SetInput改為SetInputData
  36. vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  37. cubeMapper->SetInputData(cube->GetOutput());
  38. vtkSmartPointer<vtkPolyDataMapper> cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  39. cylinderMapper->SetInputData(cylinder->GetOutput());
  40. vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  41. sphereMapper->SetInputData(sphere->GetOutput());
  42. vtkSmartPointer<vtkActor> coneActor = vtkSmartPointer<vtkActor>::New();
  43. coneActor->SetMapper(coneMapper);
  44. vtkSmartPointer<vtkActor> cubeActor = vtkSmartPointer<vtkActor>::New();
  45. cubeActor->SetMapper(cubeMapper);
  46. vtkSmartPointer<vtkActor> cylinderActor = vtkSmartPointer<vtkActor>::New();
  47. cylinderActor->SetMapper(cylinderMapper);
  48. vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
  49. sphereActor->SetMapper(sphereMapper);
  50. vtkSmartPointer<vtkRenderer> renderer1 = vtkSmartPointer<vtkRenderer>::New();
  51. renderer1->AddActor(coneActor);
  52. renderer1->SetBackground(1.0, 0.0, 0.0);
  53. renderer1->SetViewport(0.0, 0.0, 0.5, 0.5);
  54. vtkSmartPointer<vtkRenderer> renderer2 = vtkSmartPointer<vtkRenderer>::New();
  55. renderer2->AddActor(cubeActor);
  56. renderer2->SetBackground(0, 0, 0);
  57. renderer2->SetViewport(0.5, 0.0, 1.0, 0.5);
  58. vtkSmartPointer<vtkRenderer> renderer3 = vtkSmartPointer<vtkRenderer>::New();
  59. renderer3->AddActor(cylinderActor);
  60. renderer3->SetBackground(0.0, 0.0, 1.0);
  61. renderer3->SetViewport(0.0, 0.5, 0.5, 1.0);
  62. vtkSmartPointer<vtkRenderer> renderer4 = vtkSmartPointer<vtkRenderer>::New();
  63. renderer4->AddActor(sphereActor);
  64. renderer4->SetBackground(1.0, 1.0, 0.0);
  65. renderer4->SetViewport(0.5, 0.5, 1.0, 1.0);
  66. vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
  67. renWin->AddRenderer(renderer1);
  68. renWin->AddRenderer(renderer2);
  69. renWin->AddRenderer(renderer3);
  70. renWin->AddRenderer(renderer4);
  71. renWin->SetSize(640, 480);
  72. renWin->Render();
  73. renWin->SetWindowName("Viewport");
  74. vtkSmartPointer<vtkRenderWindowInteractor> interactor =
  75. vtkSmartPointer<vtkRenderWindowInteractor>::New();
  76. interactor->SetRenderWindow(renWin);
  77. renWin->Render();
  78. interactor->Initialize();
  79. interactor->Start();
  80. return EXIT_SUCCESS;
  81. }

執行在執行《VTK圖形影象進階》第五章5.3_ImageResliceExample.cpp時,會提示MetaImage cannot read data from file或者顯示視窗是空白,後來搜尋了VTKExample中的例子,發現可以這樣解決:

imgActor->SetInput(colorMap->GetOutput());
改為
imgActor->GetMapper()->SetInputConnection(colorMap->GetOutputPort());
同時新增標頭檔案
#include <vtkImageMapper3D.h>
參考連結https://heliublog.com/2017/05/10/VTK%E6%8F%90%E7%A4%BAMetaImage%20cannot%20read%20data%20from%20file/