How to get vtkDataSet (cells, points, ...) information from a source in VTK-9?

I’m writing C++ for VTK-9.3.1. How can an application discover what vtkDataSets are produced by a source, e.g. a third-party subclass of vtkAbstractPolyDataReader?

In VTK-8 I could get vtkDataSet information from a source by calling its GetOutput() method which returned a vtkPolyData object, e.g.:

vtkDataSet* dataset = source_->GetOutput();
vtkCellData* cellData = dataset->GetCellData();
// How many cells in dataset?
std::cout  << "cells: " << cellData->GetNumberOfArrays() << "\n";

As of VTK-9, GetOutput() is deprecated in favor of GetOutputPort(), which returns a vtkAlgorithmOutput object. How do I get the same vtkDataSet information from vtkAlgorithmOutput and/or vtkAbstractPolyDataReader?
Thanks!

GetOutput() is still the best way to get the vtkDataSet, keep using it like you did before. Definitely not deprecated. It’s necessary to call source->Update() before GetOutput(), but that was also true previously.

1 Like

Thanks!
I’m misunderstanding something though.
I’ve subclassed vtkAbstractPolyDataReader to TopoGridReader, which includes these members:

    /// Grid points
    vtkSmartPointer<vtkPoints> gridPoints_;

    /// Delaunay triangle vertices
    vtkSmartPointer<vtkCellArray> gridPolygons_;

My TopoGridReader::RequestData() looks like:

int TopoGridReader::RequestData(vtkInformation* request,
			       vtkInformationVector** inputVector,
			       vtkInformationVector* outputVector) {
  
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkDataSet* output = vtkDataSet::GetData(outInfo);
 
  vtkPolyData* polyOutput = vtkPolyData::SafeDownCast(output);
  [... populate gridPoints_ and gridPolygons_ …]

  // Save to output points and polygons
  polyOutput->SetPoints(gridPoints_);
  polyOutput->SetPolys(gridPolygons_);

Then when building the pipeline, data from TopoGridReader is rendered as I expect it, but TopoGridReader::GetOutput() seems to indicate 0 points and 0 cells:

gridReader->SetFileName(filename);
gridReader->Update();  // Invokes gridReader->RequestData()

/// DEBUG ////
vtkDataSet* dataset = gridReader_->GetOutput();

vtkCellData* cellData = dataset->GetCellData();
// How many cells in dataset?
qDebug() << "#cells: " << cellData->GetNumberOfArrays();
    
vtkPointData *pointData = dataset->GetPointData();
// How many points in dataset?
qDebug() << "#points: " << pointData->GetNumberOfArrays();

The debug output shows 0 cells and 0 points. What am I doing wrong here?

#cells:  0
#points:  0

Thanks!

The CellData and PointData aren’t the cells and points, they’re collections of named arrays that hold data values (e.g. colors, temperatures, directions, normals) that are associated with the points. As far as I understand, these arrays are irrelevant to what you are trying to achieve.

If you want to get the points and polys from the output, why not just cast the output to vtkPolyData and call GetPoints() and GetPolys()?

1 Like

That works - thanks @dgobbi ! Do you know why VTK provides both vtkPoints and vtkPointData? I don’t understand the relation between these classes. Likewise for vtkCellArray and vtkCellData. Moreover my TopoGridReader class doesn’t explicitly deal with vtkPointData or vtkCellData - Will this cause problems? What other pieces of VTK need these?

Let’s say you had a data file where each point in the file had a color associated with it. In VTK, the points would go into vtkPoints, the colors would go in vtkPointData. Hopefully that clears up the relationship between vtkPoints and vtkPointData. Of course, VTK can associate a lot more than just colors with the points and cells.

If the authors had called the class vtkPointAttributes or vtkPointProperties, it would be less confusing. But vtkPointData is the name they chose, and we just have to live with that.

If you’re only inserested in geometry and topology, then you don’t need use vtkPointData or vtkCellData.

1 Like

Ah, I see the distinction - thanks @dgobbi .
My goal is to understand how data flows between VTK pipeline elements. Now thanks to you I see how I can inspect my TopoGridReader::GetOutput() for vtkPolyData.

A vtkElevationFilter object is next in the pipeline:

elevFilter->SetInputConnection(gridReader_->GetOutputPort());
elevFilter_->SetScalarRange(low, high); 
// Feed elevFilter output to surfaceMapper   
surfaceMapper->SetInputConnection(elevFilter->GetOutputPort());

How can I inspect the output of the vtkElevationFilter? I tried:

polyData = pipeline->elevFilter_->GetPolyDataOutput();
polys = polyData->GetPolys();
if (polys) {
  qDebug() << "#cells in elevFilter: " << polys->GetNumberOfCells();
}
else {
  qDebug() << "no polys in elevFilter output";
}
    
points = polyData->GetPoints();
if (points) {
  qDebug() << "#points in elevFilter: " << points->GetNumberOfPoints();
}
else {
  qDebug() << "no points in elevFilter output";      
}

But the debug output is:

#cells in elevFilter output:  0
no points in elevFilter output

But my VTK app displays the elevation data as I expect, so obviously data is flowing through the pipeline. What am I missing?

Call pipeline->elevFilter_->Update() before inspecting the output. When you render the data, it’s the renderer that calls Update().

1 Like

Thanks, that does it!
Can you recommend a good up-to-date document describing the VTK pipeline at this level?
E.g. this Kitware New Pipeline document doesn’t mention the need to call Update() that I can see

That PDF doesn’t say anything about how to use the pipeline, it only describes how to write filters for the pipeline and assumes familiarity with vtkDataSet.

I don’t know of any really good documentation, so I’ll just point you here: Learning - VTK documentation (though you’ve probably already been there).

1 Like