Does vtkNew is as same as vtkSmartPointer?

Hi, I’m a beginner of VTK. I faced an special issue about vtkNew and vtkSmartPointer
I have such code:

#include <vtkNIFTIImageReader.h>
#include <vtkNIFTIImageWriter.h>
#include <vtkCamera.h>
#include <vtkImageActor.h>
#include <vtkActor2D.h>
#include <vtkImageButterworthHighPass.h>
#include <vtkImageExtractComponents.h>
#include <vtkImageFFT.h>
#include <vtkImageIdealHighPass.h>
#include <vtkImageMapToWindowLevelColors.h>
#include <vtkImageMapper3D.h>
#include <vtkImageProperty.h>
#include <vtkImageRFFT.h>
#include <vtkImageReader2.h>
#include <vtkImageReader2Factory.h>
#include <vtkInteractorStyleImage.h>
#include <vtkNamedColors.h>
#include <vtkImageData.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkProp.h>
{
...
  vtkSmartPointer < vtkNIFTIImageReader > NiftReader = vtkSmartPointer < vtkNIFTIImageReader > ::New() ;
  NiftReader->SetFileName ( argv[1] ) ;
    
  vtkNew<vtkImageActor> butterworthActor;
  butterworthActor->GetMapper()->SetInputConnection(NiftReader->GetOutputPort());
  butterworthActor->GetProperty()->SetInterpolationTypeToNearest();

  vtkNew<vtkRenderer> butterworthRenderer;
  butterworthRenderer->AddActor(butterworthActor); // wrong here
...
}

I am using vtkNew now. But I got some error:

/home/zhaoz22/Desktop/FINAL/src/Butterworth.cxx: In function ‘int main(int, char**)’:
/home/zhaoz22/Desktop/FINAL/src/Butterworth.cxx:60:33: error: cannot convert ‘vtkNew<vtkImageActor>’ to ‘vtkProp*’
   60 |   butterworthRenderer->AddActor(butterworthActor);
      |                                 ^~~~~~~~~~~~~~~~
      |                                 |
      |                                 vtkNew<vtkImageActor>
In file included from /home/zhaoz22/Desktop/FINAL/src/Butterworth.cxx:22:
/usr/include/vtk-6.3/vtkRenderer.h:68:26: note:   initializing argument 1 of ‘void vtkRenderer::AddActor(vtkProp*)’
   68 |   void AddActor(vtkProp *p);
      |                 ~~~~~~~~~^
make[2]: *** [CMakeFiles/Butterworth.dir/build.make:63: CMakeFiles/Butterworth.dir/Butterworth.cxx.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/Butterworth.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

After I change those two vtkNew to vtkSmartPointer, it works fine like this:

vtkSmartPointer < vtkImageActor > butterworthActor = vtkSmartPointer < vtkImageActor > ::New() ;
vtkSmartPointer < vtkRenderer > butterworthRenderer = vtkSmartPointer < vtkRenderer > ::New() ;

Is there any reason for this?

Thanks!

Download VTKTextBook and go to page 59 VTK Pointer Classes. I hope this will explain what is happening. Also have a look at a few of the VTK Examples.

This might be a good place to start: WriteImage. renWin is passed as a pointer, also see how we handle writer. I hope this helps.

Really appriciate for your reply. I found this in vtkNew documentation:

Automatic casting is intentionally unavailable, calling GetPointer() will return a raw pointer

Is that the reason for this?

Thank you!

vtkNew owns the object for the lifetime of the object so “To pass the raw pointer to other classes it is necessary to use the GetPointer() method” see: A Tour of VTK Pointer Classes

1 Like

It depends on what version of VTK you are using. Automatic cast to raw pointer was added to vtkNew in VTK 8.1. This was done specifically to make its behavior similar to vtkSmartPointer.

1 Like

vtkNew is the new smart pointer preferred class to use instead of vtkSmartPointer.

Internally, the kitware team discussed not so long ago on discourse about cleaning up old vtk examples still written with old references to vtkSmartPointer and replace them with vtkNew.

Note that vtkNew is not always behaving the same as vtkSmartPointer though:

// As an example, this code:
  vtkSmartPointer<vtkRenderer> ren;
// is NOT equivalent to:
  vtkNew<vtkRenderer> ren;

The first construction is often unsafe, because user has potentially forgotten (except in rare intentional cases) to initialize the smart pointer. calling vtkRenderer::New() which is automatically done with vtkNew.

Conclusion: always try to use whenever possible vtkNew in latest versions of VTK, instead of vtkSmartPointer.

1 Like

@fab672000 I went through the VTK Examples a while back and converted most of the vtkSmartPointer usage to vtkNew.

1 Like