Commit f020ebb6 authored by Berk Geveci's avatar Berk Geveci

Refactored and update the way algorithms are updated.

The way algorithms were updated (made to execute) with
request meta-data (such as update extent) was very error
prone and counter-intuitive. Added new methods to make
updating with meta-data easier. I also deprecated a number
of methods to set request meta-data. This will encourage
developers to migrate to the new API which is less error-
prone.
parent 4aeff3b8
......@@ -73,12 +73,14 @@ void SetIsoValueRMI(void *localArg, void *vtkNotUsed(remoteArg),
float val;
vtkMultiProcessController *contrl = args->Controller;
vtkPistonContour *iso = args->ContourFilter;
val = iso->GetIsoValue();
iso->SetIsoValue(val + ISO_STEP);
args->elev->Update();
args->elev->Update(contrl->GetLocalProcessId(),
contrl->GetNumberOfProcesses(), 0);
vtkMultiProcessController *contrl = args->Controller;
contrl->Send(args->elev->GetOutput(), 0, ISO_OUTPUT_TAG);
}
......@@ -113,14 +115,8 @@ void MyMain(vtkMultiProcessController *controller, void *arg)
val = (myid+1) / static_cast<float>(numProcs);
elev->SetScalarRange(val, val+0.001);
// Tell the pipeline which piece we want to update.
vtkStreamingDemandDrivenPipeline *exec =
vtkStreamingDemandDrivenPipeline::SafeDownCast(elev->GetExecutive());
exec->SetUpdateNumberOfPieces(exec->GetOutputInformation(0), numProcs);
exec->SetUpdatePiece(exec->GetOutputInformation(0), myid);
// Make sure all processes update at the same time.
elev->Update();
elev->Update(myid, numProcs, 0);
if (myid != 0)
{
......@@ -168,7 +164,7 @@ void MyMain(vtkMultiProcessController *controller, void *arg)
{
// Set the local value
contour->SetIsoValue(contour->GetIsoValue() + ISO_STEP);
elev->Update();
elev->Update(myid, numProcs, 0);
for (int i = 1; i < numProcs; ++i)
{
......
......@@ -588,18 +588,18 @@ void vtkPistonMapper::Update()
{
this->UpdateInformation();
vtkInformation* inInfo = this->GetInputInformation();
// vtkInformation* inInfo = this->GetInputInformation();
// If the estimated pipeline memory usage is larger than
// the memory limit, break the current piece into sub-pieces.
if (inInfo)
{
vtkStreamingDemandDrivenPipeline::SetUpdateExtent(
inInfo,
this->Piece,
this->NumberOfPieces,
this->GhostLevel);
}
// if (inInfo)
// {
// vtkStreamingDemandDrivenPipeline::SetUpdateExtent(
// inInfo,
// this->Piece,
// this->NumberOfPieces,
// this->GhostLevel);
// }
this->vtkMapper::Update();
}
......@@ -214,6 +214,20 @@ void vtkInformation::Copy(vtkInformation* from, int deep)
delete oldInternal;
}
//----------------------------------------------------------------------------
void vtkInformation::Append(vtkInformation* from, int deep)
{
if(from)
{
typedef vtkInformationInternals::MapType MapType;
for(MapType::const_iterator i = from->Internal->Map.begin();
i != from->Internal->Map.end(); ++i)
{
this->CopyEntry(from, i->first, deep);
}
}
}
//----------------------------------------------------------------------------
void vtkInformation::CopyEntry(vtkInformation* from,
vtkInformationKey* key, int deep)
......
......@@ -107,6 +107,13 @@ public:
// objects are created).
VTKCOMMONCORE_EXPORT void Copy(vtkInformation* from, int deep=0);
// Description:
// Append all information entries from the given vtkInformation
// instance. If deep==1, a deep copy of the information structure is performed
// (new instances of any contained vtkInformation and vtkInformationVector
// objects are created).
VTKCOMMONCORE_EXPORT void Append(vtkInformation* from, int deep=0);
// Description:
// Copy the key/value pair associated with the given key in the
// given information object. If deep=1, a deep copy of the information
......
......@@ -138,9 +138,7 @@ int TestCopyAttributeData(int,char *[])
for (int r = 0; r < 2; r++)
{
filter->UpdateInformation();
filter->SetUpdateExtent(outExt);
filter->Update();
filter->UpdateExtent(outExt);
vtkImageData *output = filter->GetOutput();
......
......@@ -41,6 +41,7 @@
#include "vtkCompositeDataPipeline.h"
#include "vtkTable.h"
#include "vtkTrivialProducer.h"
#include "vtkNew.h"
#include <set>
#include <vector>
......@@ -1455,6 +1456,77 @@ void vtkAlgorithm::Update(int port)
this->GetExecutive()->Update(port);
}
//----------------------------------------------------------------------------
int vtkAlgorithm::Update(int port, vtkInformationVector* requests)
{
vtkStreamingDemandDrivenPipeline* sddp =
vtkStreamingDemandDrivenPipeline::SafeDownCast(this->GetExecutive());
if (sddp)
{
return sddp->Update(port, requests);
}
else
{
return this->GetExecutive()->Update(port);
}
}
//----------------------------------------------------------------------------
int vtkAlgorithm::Update(vtkInformation* requests)
{
vtkNew<vtkInformationVector> reqs;
reqs->SetInformationObject(0, requests);
return this->Update(0, reqs.GetPointer());
}
//----------------------------------------------------------------------------
int vtkAlgorithm::UpdatePiece(
int piece, int numPieces, int ghostLevels, int* extents)
{
typedef vtkStreamingDemandDrivenPipeline vtkSDDP;
vtkNew<vtkInformation> reqs;
reqs->Set(vtkSDDP::UPDATE_PIECE_NUMBER(), piece);
reqs->Set(vtkSDDP::UPDATE_NUMBER_OF_PIECES(), numPieces);
reqs->Set(vtkSDDP::UPDATE_NUMBER_OF_GHOST_LEVELS(), ghostLevels);
if (extents)
{
reqs->Set(vtkSDDP::UPDATE_EXTENT(), extents, 6);
}
return this->Update(reqs.GetPointer());
}
//----------------------------------------------------------------------------
int vtkAlgorithm::UpdateExtent(int* extents)
{
typedef vtkStreamingDemandDrivenPipeline vtkSDDP;
vtkNew<vtkInformation> reqs;
reqs->Set(vtkSDDP::UPDATE_EXTENT(), extents, 6);
return this->Update(reqs.GetPointer());
}
//----------------------------------------------------------------------------
int vtkAlgorithm::UpdateTimeStep(
double time, int piece, int numPieces, int ghostLevels, int* extents)
{
typedef vtkStreamingDemandDrivenPipeline vtkSDDP;
vtkNew<vtkInformation> reqs;
reqs->Set(vtkSDDP::UPDATE_TIME_STEP(), time);
if (piece >= 0)
{
reqs->Set(vtkSDDP::UPDATE_PIECE_NUMBER(), piece);
reqs->Set(vtkSDDP::UPDATE_NUMBER_OF_PIECES(), numPieces);
reqs->Set(vtkSDDP::UPDATE_NUMBER_OF_GHOST_LEVELS(), ghostLevels);
}
if (extents)
{
reqs->Set(vtkSDDP::UPDATE_EXTENT(), extents, 6);
}
return this->Update(reqs.GetPointer());
}
//----------------------------------------------------------------------------
void vtkAlgorithm::PropagateUpdateExtent()
{
......@@ -1490,7 +1562,6 @@ void vtkAlgorithm::UpdateDataObject()
}
}
//----------------------------------------------------------------------------
void vtkAlgorithm::UpdateWholeExtent()
{
......@@ -1658,9 +1729,17 @@ void vtkAlgorithm::SetProgressText(const char* ptext)
}
}
// This is here to shut off warnings about deprecated functions
// calling deprecated functions.
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifndef VTK_LEGACY_REMOVE
//-------------------------------------------------------------
int vtkAlgorithm::SetUpdateExtentToWholeExtent(int port)
{
VTK_LEGACY_BODY(vtkAlgorithm::SetUpdateExtentToWholeExtent, "VTK 7.1");
if (this->GetOutputInformation(port))
{
return
......@@ -1676,6 +1755,7 @@ int vtkAlgorithm::SetUpdateExtentToWholeExtent(int port)
//-------------------------------------------------------------
int vtkAlgorithm::SetUpdateExtentToWholeExtent()
{
VTK_LEGACY_BODY(vtkAlgorithm::SetUpdateExtentToWholeExtent, "VTK 7.1");
return this->SetUpdateExtentToWholeExtent(0);
}
......@@ -1685,6 +1765,7 @@ void vtkAlgorithm::SetUpdateExtent(int port,
int numPieces,
int ghostLevel)
{
VTK_LEGACY_BODY(vtkAlgorithm::SetUpdateExtent, "VTK 7.1");
if (this->GetOutputInformation(port))
{
vtkStreamingDemandDrivenPipeline::SetUpdateExtent(
......@@ -1695,10 +1776,20 @@ void vtkAlgorithm::SetUpdateExtent(int port,
}
}
//-------------------------------------------------------------
void vtkAlgorithm::SetUpdateExtent(int piece,
int numPieces,
int ghostLevel)
{
VTK_LEGACY_BODY(vtkAlgorithm::SetUpdateExtent, "VTK 7.1");
this->SetUpdateExtent(0, piece, numPieces, ghostLevel);
}
//-------------------------------------------------------------
void vtkAlgorithm::SetUpdateExtent(int port,
int extent[6])
{
VTK_LEGACY_BODY(vtkAlgorithm::SetUpdateExtent, "VTK 7.1");
if (this->GetOutputInformation(port))
{
vtkStreamingDemandDrivenPipeline::SetUpdateExtent(
......@@ -1707,6 +1798,15 @@ void vtkAlgorithm::SetUpdateExtent(int port,
}
}
//-------------------------------------------------------------
void vtkAlgorithm::SetUpdateExtent(int extent[6])
{
VTK_LEGACY_BODY(vtkAlgorithm::SetUpdateExtent, "VTK 7.1");
this->SetUpdateExtent(0, extent);
}
#endif // VTK_LEGACY_REMOVE
//----------------------------------------------------------------------------
int* vtkAlgorithm::GetUpdateExtent(int port)
{
......
......@@ -459,6 +459,56 @@ public:
virtual void Update(int port);
virtual void Update();
// Description:
// This method enables the passing of data requests to the algorithm
// to be used during execution (in addition to bringing a particular
// port up-to-date). The requests argument should contain an information
// object for each port that requests need to be passed. For each
// of those, the pipeline will copy all keys to the output information
// before execution. This is equivalent to:
// \verbatim
// algorithm->UpdateInformation();
// for (int i=0; i<algorithm->GetNumberOfOutputPorts(); i++)
// {
// vtkInformation* portRequests = requests->GetInformationObject(i);
// if (portRequests)
// {
// algorithm->GetOutputInformation(i)->Append(portRequests);
// }
// }
// algorithm->Update();
// \endverbatim
// Available requests include UPDATE_PIECE_NUMBER(), UPDATE_NUMBER_OF_PIECES()
// UPDATE_EXTENT() etc etc.
virtual int Update(int port, vtkInformationVector* requests);
// Description:
// Convenience method to update an algorithm after passing requests
// to its first output port. See documentation for
// Update(int port, vtkInformationVector* requests) for details.
virtual int Update(vtkInformation* requests);
// Description:
// Convenience method to update an algorithm after passing requests
// to its first output port. See documentation for
// Update(int port, vtkInformationVector* requests) for details.
// Supports piece and extent (optional) requests.
virtual int UpdatePiece(
int piece, int numPieces, int ghostLevels, int* extents=0);
// Description:
// Convenience method to update an algorithm after passing requests
// to its first output port.
// Supports extent request.
virtual int UpdateExtent(int* extents);
// Description:
// Convenience method to update an algorithm after passing requests
// to its first output port. See documentation for
// Update(int port, vtkInformationVector* requests) for details.
// Supports time, piece (optional) and extent (optional) requests.
virtual int UpdateTimeStep(double time,
int piece=-1, int numPieces=1, int ghostLevels=0, int* extents=0);
// Description:
// Bring the algorithm's information up-to-date.
......@@ -513,37 +563,32 @@ public:
// If the whole output extent is required, this method can be called to set
// the output update extent to the whole extent. This method assumes that
// the whole extent is known (that UpdateInformation has been called).
int SetUpdateExtentToWholeExtent(int port);
VTK_LEGACY(int SetUpdateExtentToWholeExtent(int port));
// Description:
// Convenience function equivalent to SetUpdateExtentToWholeExtent(0)
// This method assumes that the whole extent is known (that UpdateInformation
// has been called).
int SetUpdateExtentToWholeExtent();
VTK_LEGACY(int SetUpdateExtentToWholeExtent());
// Description:
// Set the output update extent in terms of piece and ghost levels.
void SetUpdateExtent(int port,
int piece,int numPieces, int ghostLevel);
VTK_LEGACY(void SetUpdateExtent(int port,
int piece,int numPieces, int ghostLevel));
// Description:
// Convenience function equivalent to SetUpdateExtent(0, piece,
// numPieces, ghostLevel)
void SetUpdateExtent(int piece,int numPieces, int ghostLevel)
{
this->SetUpdateExtent(0, piece, numPieces, ghostLevel);
}
VTK_LEGACY(void SetUpdateExtent(
int piece,int numPieces, int ghostLevel));
// Description:
// Set the output update extent for data objects that use 3D extents
void SetUpdateExtent(int port, int extent[6]);
VTK_LEGACY(void SetUpdateExtent(int port, int extent[6]));
// Description:
// Convenience function equivalent to SetUpdateExtent(0, extent)
void SetUpdateExtent(int extent[6])
{
this->SetUpdateExtent(0, extent);
}
VTK_LEGACY(void SetUpdateExtent(int extent[6]));
// Description:
// These functions return the update extent for output ports that
......
......@@ -96,38 +96,6 @@ void vtkCachedStreamingDemandDrivenPipeline
os << indent << "CacheSize: " << this->CacheSize << "\n";
}
//----------------------------------------------------------------------------
int vtkCachedStreamingDemandDrivenPipeline::Update()
{
return this->Superclass::Update();
}
//----------------------------------------------------------------------------
int vtkCachedStreamingDemandDrivenPipeline::Update(int port)
{
if(!this->UpdateInformation())
{
return 0;
}
if(port >= 0 && port < this->Algorithm->GetNumberOfOutputPorts())
{
int retval = 1;
// some streaming filters can request that the pipeline execute multiple
// times for a single update
do
{
retval =
this->PropagateUpdateExtent(port) && this->UpdateData(port) && retval;
}
while (this->ContinueExecuting);
return retval;
}
else
{
return 1;
}
}
//----------------------------------------------------------------------------
int vtkCachedStreamingDemandDrivenPipeline
::NeedToExecuteData(int outputPort,
......
......@@ -35,11 +35,6 @@ public:
vtkStreamingDemandDrivenPipeline);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Bring the algorithm's outputs up-to-date.
virtual int Update();
virtual int Update(int port);
// Description:
// This is the maximum number of images that can be retained in memory.
// it defaults to 10.
......
......@@ -480,9 +480,6 @@ vtkDataObject* vtkCompositeDataPipeline::ExecuteSimpleAlgorithmForBlock(
vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
extent,
6);
info->Set(
vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT_INITIALIZED(),
1);
storedPiece =
info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
storedNumPieces=
......
......@@ -59,13 +59,35 @@ public:
virtual int Update(int port);
virtual int UpdateWholeExtent();
// Description:
// This method enables the passing of data requests to the algorithm
// to be used during execution (in addition to bringing a particular
// port up-to-date). The requests argument should contain an information
// object for each port that requests need to be passed. For each
// of those, the pipeline will copy all keys to the output information
// before execution. This is equivalent to:
// \verbatim
// executive->UpdateInformation();
// for (int i=0; i<executive->GetNumberOfOutputPorts(); i++)
// {
// vtkInformation* portRequests = requests->GetInformationObject(i);
// if (portRequests)
// {
// executive->GetOutputInformation(i)->Append(portRequests);
// }
// }
// executive->Update();
// \endverbatim
// Available requests include UPDATE_PIECE_NUMBER(), UPDATE_NUMBER_OF_PIECES()
// UPDATE_EXTENT() etc etc.
virtual int Update(int port, vtkInformationVector* requests);
// Description:
// Propagate the update request from the given output port back
// through the pipeline. Should be called only when information is
// up to date.
int PropagateUpdateExtent(int outputPort);
// Description:
// Propagate time through the pipeline. this is a special pass
// only necessary if there is temporal meta data that must be updated
......@@ -80,42 +102,6 @@ public:
static void GetWholeExtent(vtkInformation *, int extent[6]);
static int* GetWholeExtent(vtkInformation *);
// Description:
// If the whole input extent is required to generate the requested output
// extent, this method can be called to set the input update extent to the
// whole input extent. This method assumes that the whole extent is known
// (that UpdateInformation has been called)
int SetUpdateExtentToWholeExtent(int port);
static int SetUpdateExtentToWholeExtent(vtkInformation *);
// Description:
// Get/Set the update extent for output ports that use 3D extents.
int SetUpdateExtent(int port, int extent[6]);
int SetUpdateExtent(int port, int x0, int x1, int y0, int y1, int z0, int z1);
static int SetUpdateExtent(vtkInformation *, int extent[6]);
static void GetUpdateExtent(vtkInformation *, int extent[6]);
static int* GetUpdateExtent(vtkInformation *);
// Description:
// Set/Get the update piece, update number of pieces, and update
// number of ghost levels for an output port. Similar to update
// extent in 3D.
int SetUpdateExtent(int port,
int piece, int numPieces, int ghostLevel);
static int SetUpdateExtent(vtkInformation *,
int piece, int numPieces, int ghostLevel);
static int SetUpdatePiece(vtkInformation *, int piece);
static int GetUpdatePiece(vtkInformation *);
static int SetUpdateNumberOfPieces(vtkInformation *, int n);
static int GetUpdateNumberOfPieces(vtkInformation *);
static int SetUpdateGhostLevel(vtkInformation *, int n);
static int GetUpdateGhostLevel(vtkInformation *);
// Description:
// Get/Set the update extent for output ports that use Temporal Extents
int SetUpdateTimeStep(int port, double time);
static int SetUpdateTimeStep(vtkInformation *, double time);
// Description:
// This request flag indicates whether the requester can handle more
// data than requested for the given port. Right now it is used in
......@@ -213,6 +199,41 @@ public:
// \ingroup InformationKeys
static vtkInformationDoubleVectorKey *BOUNDS();
// Description:
// If the whole input extent is required to generate the requested output
// extent, this method can be called to set the input update extent to the
// whole input extent. This method assumes that the whole extent is known
// (that UpdateInformation has been called)
VTK_LEGACY(int SetUpdateExtentToWholeExtent(int port));
VTK_LEGACY(static int SetUpdateExtentToWholeExtent(vtkInformation *));
// Description:
// Get/Set the update extent for output ports that use 3D extents.
VTK_LEGACY(int SetUpdateExtent(int port, int extent[6]));
VTK_LEGACY(int SetUpdateExtent(int port, int x0, int x1, int y0, int y1, int z0, int z1));
VTK_LEGACY(static int SetUpdateExtent(vtkInformation *, int extent[6]));
static void GetUpdateExtent(vtkInformation *, int extent[6]);
static int* GetUpdateExtent(vtkInformation *);
// Description:
// Set/Get the update piece, update number of pieces, and update
// number of ghost levels for an output port. Similar to update
// extent in 3D.
VTK_LEGACY(int SetUpdateExtent(int port,
int piece, int numPieces, int ghostLevel));
VTK_LEGACY(static int SetUpdateExtent(vtkInformation *,
int piece, int numPieces, int ghostLevel));
VTK_LEGACY(static int SetUpdatePiece(vtkInformation *, int piece));
static int GetUpdatePiece(vtkInformation *);
VTK_LEGACY(static int SetUpdateNumberOfPieces(vtkInformation *, int n));
static int GetUpdateNumberOfPieces(vtkInformation *);
VTK_LEGACY(static int SetUpdateGhostLevel(vtkInformation *, int n));
static int GetUpdateGhostLevel(vtkInformation *);
// Description:
// Get/Set the update extent for output ports that use Temporal Extents
VTK_LEGACY(int SetUpdateTimeStep(int port, double time));
VTK_LEGACY(static int SetUpdateTimeStep(vtkInformation *, double time));
protected:
vtkStreamingDemandDrivenPipeline();
~vtkStreamingDemandDrivenPipeline();
......
Changes in VTK 7.1 {#VTK-7-1-Changes}
==================
This pages documents API and behavior changes between VTK 7.0 and
VTK 7.1
Pipeline Update Methods
-----------------------
The following methods were deprecated in VTK 7.1:
### vtkAlgorithm:
int SetUpdateExtentToWholeExtent(int port);
int SetUpdateExtentToWholeExtent();
void SetUpdateExtent(int port,
int piece,int numPieces, int ghostLevel);
void SetUpdateExtent(
int piece,int numPieces, int ghostLevel);
void SetUpdateExtent(int port, int extent[6]);
void SetUpdateExtent(int extent[6]);
### vtkStreamingDemandDrivenPipeline:
int SetUpdateExtentToWholeExtent(int port);
static int SetUpdateExtentToWholeExtent(vtkInformation *);
int SetUpdateExtent(int port, int extent[6]);
int SetUpdateExtent(int port, int x0, int x1, int y0, int y1, int z0, int z1);
static int SetUpdateExtent(vtkInformation *, int extent[6]);
int SetUpdateExtent(int port,
int piece, int numPieces, int ghostLevel);
static int SetUpdateExtent(vtkInformation *,
int piece, int numPieces, int ghostLevel);
static int SetUpdatePiece(vtkInformation *, int piece);
static int SetUpdateNumberOfPieces(vtkInformation *, int n);
static int SetUpdateGhostLevel(vtkInformation *, int n);
int SetUpdateTimeStep(int port, double time);
static int SetUpdateTimeStep(vtkInformation *, double time);
The following new methods were added:
### vtkAlgorithm:
int Update(int port, vtkInformationVector* requests);
int Update(vtkInformation* requests);
int UpdatePiece(int piece, int numPieces, int ghostLevels, int* extents=0);
int UpdateExtent(int piece, int numPieces, int ghostLevels, int* extents=0);
int UpdateTimeStep(double time,
int piece=-1, int numPieces=1, int ghostLevels=0, int* extents=0);
### vtkStreamingDemandDrivenPipeline:
int Update(int port, vtkInformationVector* requests);
The main reason behind these changes is to make requesting a particular time step or a particular spatial subset (extent or pieces) during an update easier and more predictable. Prior to these changes, the following is the best way to request a subset during update:
vtkNew<vtkRTAnalyticSource> source;
// Set some properties of source here
source->UpdateInformation();
source->SetUpdateExtent(0, 5, 0, 5, 2, 2);
source->Update();
Note that the following will not work:
vtkNew<vtkRTAnalyticSource> source;
// Set some properties of source here
// source->UpdateInformation(); <-- this was commented out
source->SetUpdateExtent(0, 5, 0, 5, 2, 2);
source->Update();
This is because when the output of an algorithm is initialized, all request meta-data stored in its OutputInformation is removed. The initialization of the output happens during the first *RequestInformation*, which is why `UpdateInformation()` needs to be called before setting any request values. To make things more complicated, the following will also not work:
vtkNew<vtkRTAnalyticSource> source;
// Set some properties of source here
source->UpdateInformation();
source->SetUpdateExtent(0, 5, 0, 5, 2, 2);
source->Modified();
source->Update();
This is because during *RequestInformation*, the extent and piece requests are initialized to default values (which is the whole dataset) and *RequestInformation* is called during update if the algorithm has been modified since the last information update.
This necessary sequence of calls has been mostly tribal knowledge and is very error prone. To simplify pipeline updates with requests, we introduced a new set of methods. With the new API, our example would be:
vtkNew<vtkRTAnalyticSource> source;
int updateExtent[6] = {0, 5, 0, 5, 2, 2};
// Set some properties of source here
source->UpdateExtent(updateExtent);
To ask for a particular time step from a time source, we would do something like this:
vtkNew<vtkExodusIIReader> reader;
// Set properties here
reader->UpdateTimeStep(0.5);
// or
reader->UpdateTimeStep(0.5, 1, 2, 1);
The last call asks for time value 0.5 and the first of two pieces with one ghost level.
The new algorithm also supports directly passing a number of keys to make requests:
typedef vtkStreamingDemandDrivenPipeline vtkSDDP;
vtkNew<vtkRTAnalyticSource> source;