Adding New Points in Programmable Filter

Hello, we (@lpalmstrom and I) have been trying to extend a vtkRectinear/Image Data/or vtkStructuredData with a python programmable filter. Our initial goal was to take the first column of a structured grid and add it as a new column to the end (right) of the dataset, lots of trials and errors, but in the end we were never able to grow the size of the dimensions from the initial dataset. We have simplified this down to something we think should work, which is:
load wavelet with extents 0,1024: 0,512:0,0 then run a programmable filter with the following code which explicitly makes a new set of points and sets them as the points for the output data set with new dimensions.

from paraview import vtk
import numpy as np # needed for interpolation and pi

newPoints = vtk.vtkPoints()
outputData = self.GetOutput()

lon = np.arange(0.0,360.0, 360/1026.0)
lat = np.arange(90.0,-90.0, -180.0/513.0)
print(len(lon), len(lat))

count = 0
for j in lat:
  for i in lon:
    newPoints.InsertPoint(count,i,j,0.0)
    count = count + 1

outputData.SetDimensions(len(lon),len(lat),1)
outputData.SetPoints(newPoints)

print(outputData.GetDimensions())

Note that the information tab for the output of the programmable filter shows the new dimensions, but the dataset itself does not have the new dimensions/points. We checked by selecting points in the upper right corner of the dataset and inspecting them with the spreadsheet view. Or saving the data as a vts and simply looking at the “WholeExtent” in the xml. The last column of data should be 1025 but it is still 1024.
In the end we want to extend the size of the dimensions/extents of the output dataset, but this doesn’t seem possible with our/my current knowledge. Should we be able to grow the dataset? We have code that does this by reading our data, creating a new data set and writing the new dataset, but it would be convenient to do this in the programmable filter.

If ever you’re changing the extents on an input structured dataset, you are required to provide two methods: RequestInformation to report to the down stream the new extent you’ll be producing and RequestUpdateExtent to map a down-stream extent request to an upstream extent request.

1 Like

Thank you for your response. I’m having trouble finding apropos examples of RequestInformation and RequestUpdateExtent so I’m trying to figure it out. I have two follow up questions.

  1. RequestUpdateExtent seems to exist to communicate up the pipeline, to the parent, that this filter needs a different extent provided or a different time step. I don’t want to get different extents from the parent and the filter will be incapable of dynamically changing subextents as output as well. Is RequestUpdateExtent still required?
  2. I started looking at RequestInformation and tried to explicitly set the whole_extent:
# Code for 'RequestInformation Script'.
executive = self.GetExecutive()
outInfo = executive.GetOutputInformation(0)
outInfo.Set(executive.WHOLE_EXTENT(), 0, 1025, 0, 512, 0, 0)

This actually produces the correct grid as viewed in the render window. but does throw an error:

ERROR: In /opt/glr/paraview/paraview-ci/build/superbuild/paraview/src/VTK/Common/ExecutionModel/vtkStreamingDemandDrivenPipeline.cxx, line 878

vtkPVPostFilterExecutive (0x6000018e3640): The update extent specified in the information for output port 0 on algorithm vtkPVPostFilter(0x6000012683f0) is 0 1025 0 512 0 0, which is outside the whole extent 0 1024 0 512 0 0.

Which references the whole extent from the upstream filter, which might be an issue with not having a RequestUpdateExtent? I tried setting UPDATE_EXTENT and WHOLE_EXTENT in the
RequestInformation and/or RequestUpdateExtent without success. In the meantime I found Berk’s VTK Pipeline Primer from 2014 which I’ll peruse to try and understand better…

Hi @patchett2002 and @lpalmstrom,

This missing ingredient here is setting the UPDATE_EXTENT in the input information that tells the upstream filter what extent is being requested. Try this for the RequestUpdateExtent script:

executive = self.GetExecutive() 
inInfo = executive.GetInputInformation(0, 0)
inInfo.Set(executive.UPDATE_EXTENT(), 0, 1024, 0, 512, 0, 0)
1 Like

Thanks Cory, that solved our problems.

1 Like