Temporal pipeline (updating TIME_RANGE and use of caches)

Hi Developers

I am making a client-server solution streaming vtkImageData and vtkPolyData using IGTLink. I would like to have a module, which exposes downstream TIME_STEPS = [currentTime] and TIME_RANGE = [currentTime, currentTime] and further downstream have a vtkTemporalDataSetCache, which has some depth and expose downstream the correct TIME_RANGE.

I have encountered some difficulties - any help is appreciated.

First question: I have made a simple python test program to figure out how to use the pipeline. It seems like the vtkTemporalDataSetCache is not working correctly. The first entry for UPDATE_TIME_STEP() = 0.0 is not read from the cache.

import numpy as np
import vtk
from vtk.numpy_interface import dataset_adapter as dsa
from vtk.util.vtkAlgorithm import VTKPythonAlgorithmBase

class TestSource(VTKPythonAlgorithmBase):
  def __init__(self):
    super(TestSource, self).__init__(
      nInputPorts=0,
      nOutputPorts=1, outputType='vtkImageData')
    self.timeStep = 0.0
    self.timeRange = [0.0, 0.0]

  def RequestInformation(self, request, inInfo, outInfo):
    info = outInfo.GetInformationObject(0)
    info.Set(vtk.vtkStreamingDemandDrivenPipeline.WHOLE_EXTENT(),
             (0, 60, 0, 60, 0, 0), 6)
  
    info.Set(vtk.vtkStreamingDemandDrivenPipeline.TIME_STEPS(),
             [self.timeStep], 1)
    info.Set(vtk.vtkStreamingDemandDrivenPipeline.TIME_RANGE(),
             [self.timeStep, self.timeStep], 2)
    info.Set(vtk.vtkAlgorithm.CAN_PRODUCE_SUB_EXTENT(), 1)
    info.Set(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_NUMBER_OF_PIECES(),
             1)
    info.Set(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_PIECE_NUMBER(),
             0)
    return 1
  
  def RequestUpdateExtent(self, request, inInfo, outInfo):
    info = outInfo.GetInformationObject(0)
    timeStep = info.Get(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP())
    print("The requested time-step: %f" % (timeStep))
    return 1

  def RequestData(self, request, inInfo, outInfo):
    print("RequestData")
    info = outInfo.GetInformationObject(0)
    # We produce only the extent that we are asked (UPDATE_EXTENT)
    ue = info.Get(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_EXTENT())
    ue = np.array(ue)

    output = vtk.vtkImageData.GetData(outInfo)

    # Parameters of the grid to produce
    dims = ue[1::2] - ue[0::2] + 1

    # The time step requested
    if info.Has(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP()):
      t = info.Get(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP())
    else:
      t = 0
    
    a = np.zeros((3, dims[0], dims[1]), order='F')
    a[0, :] = t
    
    output.SetExtent(*ue)
    output.SetSpacing(0.1, 0.1, 0.1)

    # Make a VTK array from the numpy array (using pointers)
    v = dsa.numpyTovtkDataArray(a.ravel(order='A').reshape(
                dims[0]*dims[1], 3))
    v.SetName("vectors")
    output.GetPointData().SetVectors(v)
    return 1

dummySource = TestSource()
dummySource.UpdateInformation()
dummySource.GetOutputInformation(0).Set(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP(), 0.0)
dummySource.Update()

staticCache = vtk.vtkTemporalDataSetCache()
staticCache.SetInputConnection(dummySource.GetOutputPort())
staticCache.SetCacheSize(10)

passThrough = vtk.vtkPassThrough()
passThrough.SetInputConnection(staticCache.GetOutputPort())

for i in range(10):
passThrough.GetOutputInformation(0).Set(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP(), float(i))
  passThrough.Update()
  print(passThrough.GetOutputDataObject(0).GetPointData().GetVectors().GetValue(0))

print("Reuse")
for i in range(3):
  passThrough.GetOutputInformation(0).Set(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP(), float(i))
  passThrough.Update()
  print(passThrough.GetOutputDataObject(0).GetPointData().GetVectors().GetValue(0))

The last part of the output reveals this:

Reuse
The requested time-step: 0.000000
RequestData [ first data not fetched from cache]
0.0
1.0

Second: How can I change the TIME_RANGE during pipeline execution and ensure that the TIME_RANGE propagated from a cache residing downstream corresponds to what is stored in the cache (preferably without implementing a new vtkTemporalDataSetCache.

Thanks in advance
Jens