[vtkusers] Understanding vtkSmartPointers

Fcs ftpronk at engits.com
Mon May 28 07:43:02 EDT 2018


Using VTK for one of our projects, we are encountering some memory leaks
which, in time, cripple our system.  So I'm trying to have a better
understanding of the  VTK pointers
<https://blog.kitware.com/a-tour-of-vtk-pointer-classes/>  . 

It was my (erroneous..?) belief that the *vtkSmartPointer*s would destroy
the object they were holding when getting out of scope.  Carefully reading
the kitware blog post linked hereinabove, and playing around with a test
code (code sample below), I now understand that it is objects held by
*vtkNew* that will be destroyed when out-of-scope, and that
*vtkSmartPointer*s, on the contrary, will keep them alive as long as the
reference count is non-zero.  Is this correct? 

Now, from a practical point of view:  does this mean that I can, in a class,
create an entire VTK pipeline with *vtkSmartPointer*s, and only store the
latest object in a member variable to keep every object alive (So, in my
code below, only bookkeep the object returned by applyFilters())?  And that
when I'm finished, I can call ->Delete() on that object to clean-up the
entire pipeline?  Is this a good practice?  Until now, I was painstakingly
storing every object created for the lifetime of a pipeline, and I would
like to know if I can simplify my code..

Thank you! 

Francois. 



Toy code:
(returns vtkDebugLeaks has found no leaks) 


#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkStructuredGrid.h>
#include <vtkPoints.h>
#include <vtkCellCenters.h>
#include <vtkDoubleArray.h>
#include <vtkCellDataToPointData.h>
#include <vtkCellData.h>
#include <vtkClipDataSet.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkPolyDataAlgorithm.h>


vtkSmartPointer<vtkPolyDataAlgorithm>
applyFilters(vtkSmartPointer<vtkStructuredGrid> grid) 
{ 
  // Convert cell data to point data 
  vtkSmartPointer<vtkCellDataToPointData> c2p = 
      vtkSmartPointer<vtkCellDataToPointData>::New(); 
  c2p->PassCellDataOn(); 
  c2p->SetInputData(grid); 

  // Clip at value r = 4.5 
  vtkSmartPointer<vtkClipDataSet> clip = 
      vtkSmartPointer<vtkClipDataSet>::New(); 
  clip->SetInputConnection(c2p->GetOutputPort()); 
  clip->SetInputArrayToProcess(0, 0, 0, 0, "R"); 
  clip->SetValue(4.5); 
  clip->InsideOutOn(); 

  // Make plane 
  vtkSmartPointer<vtkPlane> plane = 
      vtkSmartPointer<vtkPlane>::New(); 
  plane->SetOrigin(0.,0.,0.); 
  plane->SetNormal(0, 0, 1); 

  // Cut 
  vtkSmartPointer<vtkCutter> cutter = 
      vtkSmartPointer<vtkCutter>::New(); 
  cutter->SetCutFunction(plane); 
  cutter->SetInputConnection(clip->GetOutputPort()); 

  return cutter; 
} 


int main() 
{ 
  // Create structured grid 
  int nx = 101, ny = 101, nz = 101; 
  double dx, dy, dz; 
  dx = dy = dz = 10./(nx-1); 
  vtkSmartPointer<vtkStructuredGrid> grid = 
      vtkSmartPointer<vtkStructuredGrid>::New(); 
  grid->SetDimensions(nx, ny, nz); 
  vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New(); 
  for (int i = 0; i < nx; ++i) { 
    for (int j = 0; j < ny; ++j) { 
      for (int k = 0; k < nz; ++k) { 
        pts->InsertNextPoint(-5+dx*i, -5+dy*j, -5+dz*k); 
      } 
    } 
  } 
  grid->SetPoints(pts); 

  // Create cell scalar field 
  vtkSmartPointer<vtkDoubleArray> arr = 
      vtkSmartPointer<vtkDoubleArray>::New(); 
  arr->SetNumberOfComponents(1); 
  arr->SetName("R"); 
  vtkSmartPointer<vtkCellCenters> cell_centres = 
      vtkSmartPointer<vtkCellCenters>::New(); 
  cell_centres->SetInputData(grid); 
  cell_centres->Update(); 
  for (int i = 0; i < grid->GetNumberOfCells(); ++i) { 
    double pt[3]; 
    cell_centres->GetOutput()->GetPoint(i, pt); 
    double r = pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]; 
    arr->InsertNextValue(r); 
  } 
  grid->GetCellData()->AddArray(arr); 

  // Call clipping functions 
  vtkSmartPointer<vtkPolyDataAlgorithm> poly_algo = applyFilters(grid); 

  // Create a mapper and actor 
  vtkSmartPointer<vtkPolyDataMapper> mapper = 
      vtkSmartPointer<vtkPolyDataMapper>::New(); 
  mapper->SetInputConnection(poly_algo->GetOutputPort()); 
  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); 
  actor->SetMapper(mapper); 

  // Create a renderer, render window and interactor 
  vtkSmartPointer<vtkRenderer> renderer = 
      vtkSmartPointer<vtkRenderer>::New(); 
  vtkSmartPointer<vtkRenderWindow> render_window = 
      vtkSmartPointer<vtkRenderWindow>::New(); 
  render_window->SetWindowName("Plane"); 
  render_window->AddRenderer(renderer); 
  vtkSmartPointer<vtkRenderWindowInteractor> window_interactor = 
      vtkSmartPointer<vtkRenderWindowInteractor>::New(); 
  window_interactor->SetRenderWindow(render_window); 

  // Add the actors to the scene 
  renderer->AddActor(actor); 

  // Render and interact 
  render_window->Render(); 
  window_interactor->Start(); 

  return EXIT_SUCCESS; 
} 




--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html


More information about the vtkusers mailing list