VTK/Streaming
Streaming time steps
This example demonstrates how a filter can stream multiple time steps. The example we will use to demonstrate this functionality is vtkTemporalStatistics.
Streaming happens over multiple executions of the filter. Therefore, we need a way of keeping track of which time step we are currently processing. For this purpose, vtkTemporalStatistics uses an data member called CurrentTimeIndex. CurrentTimeIndex is initialized to 0 in the constructor.
<source lang="cpp"> vtkTemporalStatistics::vtkTemporalStatistics() {
this->CurrentTimeIndex = 0;
} </source>
In RequestUpdateExtent(), we request the current time index. This is initially set to 0 but will be incremented after the streaming starts.
<source lang="cpp"> int vtkTemporalStatistics::RequestUpdateExtent(
vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *vtkNotUsed(outputVector))
{
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
double *inTimes = inInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS()); if (inTimes) { inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS(), &inTimes[this->CurrentTimeIndex], 1); }
return 1;
} </source>
In RequestData(), we first process the current time step. We then increment the current time index and set CONTINUE_EXECUTING if there are more time steps to process. This tells the executive to perform another pass of the REQUEST_UPDATE_EXTENT and REQUEST_DATA. This will lead to another call to RequestUpdateExtent() and RequestData() with the next time index. This will continue until the filter removes CONTINUE_EXECUTING from the request.
<source lang="cpp"> int vtkTemporalStatistics::RequestData(vtkInformation *request,
vtkInformationVector **inputVector, vtkInformationVector *outputVector)
{
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); vtkInformation *outInfo = outputVector->GetInformationObject(0);
vtkDataObject *input = vtkDataObject::GetData(inInfo); vtkDataObject *output = vtkDataObject::GetData(outInfo);
if (this->CurrentTimeIndex == 0) { // First execution, initialize arrays. this->InitializeStatistics(input, output); } else { // Subsequent execution, accumulate new data. this->AccumulateStatistics(input, output); }
this->CurrentTimeIndex++;
if ( this->CurrentTimeIndex < inInfo->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS())) { // There is still more to do. request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(), 1); } else { // We are done. Finish up. this->PostExecute(input, output); request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING()); this->CurrentTimeIndex = 0; }
return 1;
} </source>