Updates will be applied - 3:30pm EDT (UTC -400). No downtime expected.

Commit be279517 authored by Berk Geveci's avatar Berk Geveci

Added new meta-data and request capability to the pipeline.

Added the ability for keys to copy themselves during pipeline passes.
This allows arbitrary meta-data to flow back and forth in the pipeline
with changing the executives. Although this is similar to KEYS_TO_COPY,
it works significantly better. KEYS_TO_COPY has one major flow: it
does not work if the algorithm that is supposed to add the key to
KEYS_TO_COPY already executed and a filter downstream is causing re-
execution.

Also added the ability for keys to store meta-data in a data object's
information. Allowing them to check it later in NeedToExecuteData.
This allows filters to send a request upstream to potentially cause
a new execution of the pipeline with changing the executives. This was
not possible before.

This was done by adding 3 new virtual methods to vtkInformationKey:
NeedToExecute(), StoreMetaData() and CopyDefaultInformation(). Normally
these do nothing. Subclasses can overwrite them to implement new
behavior. These methods are called by the pipeline at certain times.
CopyDefaultInformation() is called during CopyDefaultInformation(),
StoreMetaData() after execution (REQUEST_DATA), NeedToExecute during
NeedToExecuteData.

Change-Id: Ice192eb0be9f0a47b512c1b0fa3cfbede74d81e1
parent 2b7b2fb3
......@@ -96,6 +96,45 @@ public:
void Print(vtkInformation* info);
virtual void Print(ostream& os, vtkInformation* info);
// Description:
// This function is only relevant when the pertaining key
// is used in a VTK pipeline. Specific keys that handle
// pipeline data requests (for example, UPDATE_PIECE_NUMBER)
// can overwrite this method to notify the pipeline that a
// a filter should be (re-)executed because what is in
// the current output is different that what is being requested
// by the key. For example, DATA_PIECE_NUMBER != UPDATE_PIECE_NUMBER.
virtual bool NeedToExecute(vtkInformation* pipelineInfo,
vtkInformation* dobjInfo) {return false;}
// Description:
// This function is only relevant when the pertaining key
// is used in a VTK pipeline. Specific keys that handle
// pipeline data requests (for example, UPDATE_PIECE_NUMBER)
// can overwrite this method to store in the data information
// meta-data about the request that led to the current filter
// execution. This meta-data can later be used to compare what
// is being requested to decide whether the filter needs to
// re-execute. For example, a filter may store the current
// UPDATE_PIECE_NUMBER in the data object's information as
// the DATA_PIECE_NUMBER. DATA_PIECE_NUMBER can later be compared
// to a new UPDATA_PIECE_NUMBER to decide whether a filter should
// re-execute.
virtual void StoreMetaData(vtkInformation* request,
vtkInformation* pipelineInfo,
vtkInformation* dobjInfo) {}
// Description:
// This function is only relevant when the pertaining key
// is used in a VTK pipeline. By overwriting this method, a
// key can decide if/how to copy itself downstream or upstream
// during a particular pipeline pass. For example, meta-data keys
// can copy themselves during REQUEST_INFORMATION whereas request
// keys can copy themselves during REQUEST_UPDATE_EXTENT.
virtual void CopyDefaultInformation(vtkInformation* request,
vtkInformation* fromInfo,
vtkInformation* toInfo) {}
protected:
const char* Name;
const char* Location;
......@@ -129,6 +168,13 @@ private:
{ \
return CLASS##_##NAME; \
}
#define vtkInformationKeySubclassMacro(CLASS, NAME, type, super) \
static vtkInformation##type##Key* CLASS##_##NAME = \
new vtkInformation##type##Key(#NAME, #CLASS); \
vtkInformation##super##Key* CLASS::NAME() \
{ \
return CLASS##_##NAME; \
}
#define vtkInformationKeyRestrictedMacro(CLASS, NAME, type, required) \
static vtkInformation##type##Key* CLASS##_##NAME = \
new vtkInformation##type##Key(#NAME, #CLASS, required); \
......@@ -137,4 +183,5 @@ private:
return CLASS##_##NAME; \
}
#endif
......@@ -24,8 +24,10 @@ SET(Module_SRCS
vtkImageProgressIterator.cxx
vtkImageToStructuredGrid.cxx
vtkImageToStructuredPoints.cxx
vtkInformationDataObjectMetaDataKey.cxx
vtkInformationExecutivePortKey.cxx
vtkInformationExecutivePortVectorKey.cxx
vtkInformationIntegerRequestKey.cxx
vtkMultiBlockDataSetAlgorithm.cxx
vtkMultiTimeStepAlgorithm.cxx
vtkPassInputTypeAlgorithm.cxx
......
......@@ -2,6 +2,7 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
NO_DATA NO_VALID
TestCopyAttributeData.cxx
TestImageDataToStructuredGrid.cxx
TestMetaData.cxx
TestSetInputDataObject.cxx
TestTemporalSupport.cxx
)
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestTemporalSupport.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// This test verifies that information keys are copied up & down the
// pipeline properly and NeedToExecute/StoreMetaData functions as expected.
#include "vtkInformation.h"
#include "vtkInformationDataObjectMetaDataKey.h"
#include "vtkInformationIntegerRequestKey.h"
#include "vtkInformationIntegerKey.h"
#include "vtkInformationVector.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkPolyData.h"
#include "vtkPolyDataAlgorithm.h"
#include "vtkPolyDataNormals.h"
#define TEST_SUCCESS 0
#define TEST_FAILURE 1
class MySource : public vtkPolyDataAlgorithm
{
public:
static MySource *New();
vtkTypeMacro(vtkPolyDataAlgorithm,vtkAlgorithm);
static vtkInformationDataObjectMetaDataKey* META_DATA();
static vtkInformationIntegerRequestKey* REQUEST();
static vtkInformationIntegerKey* DATA();
bool Failed;
unsigned int NumberOfExecutions;
int Result;
protected:
MySource()
{
this->SetNumberOfInputPorts(0);
this->SetNumberOfOutputPorts(1);
this->Failed = false;
this->NumberOfExecutions = 0;
this->Result = -1;
}
virtual int RequestInformation(vtkInformation*,
vtkInformationVector**,
vtkInformationVector* outputVector)
{
vtkInformation* outInfo = outputVector->GetInformationObject(0);
vtkPolyData* pd = vtkPolyData::New();
outInfo->Set(META_DATA(), pd);
pd->Delete();
return 1;
}
virtual int RequestData(vtkInformation*,
vtkInformationVector**,
vtkInformationVector* outputVector)
{
// Here we verify that a request set at the end of the pipeline
// made it to here properly.
vtkInformation* outInfo = outputVector->GetInformationObject(0);
if (!outInfo->Has(REQUEST()) ||
outInfo->Get(REQUEST()) != this->Result)
{
this->Failed = true;
}
this->NumberOfExecutions++;
return 1;
}
};
vtkStandardNewMacro(MySource);
vtkInformationKeyMacro(MySource, META_DATA, DataObjectMetaData);
vtkInformationKeyMacro(MySource, DATA, Integer);
class vtkInformationMyRequestKey : public vtkInformationIntegerRequestKey
{
public:
vtkInformationMyRequestKey(const char* name, const char* location) :
vtkInformationIntegerRequestKey(name, location)
{
this->DataKey = MySource::DATA();
}
};
vtkInformationKeySubclassMacro(MySource, REQUEST, MyRequest, IntegerRequest);
int TestMetaData(int, char*[])
{
vtkNew<MySource> mySource;
vtkNew<vtkPolyDataNormals> filter;
filter->SetInputConnection(mySource->GetOutputPort());
filter->UpdateInformation();
// Do we have the meta-data created by the reader at the end
// of the pipeline?
if (!filter->GetOutputInformation(0)->Has(MySource::META_DATA()))
{
return TEST_FAILURE;
}
filter->GetOutputInformation(0)->Set(MySource::REQUEST(), 2);
mySource->Result = 2;
filter->Update();
// Nothing changed. This should not cause re-execution
filter->Update();
filter->GetOutputInformation(0)->Set(MySource::REQUEST(), 3);
mySource->Result = 3;
// Request changed. This should cause re-execution
filter->Update();
if (mySource->NumberOfExecutions != 2)
{
return TEST_FAILURE;
}
if (mySource->Failed)
{
return TEST_FAILURE;
}
return TEST_SUCCESS;
}
......@@ -22,6 +22,7 @@
#include "vtkInformationExecutivePortKey.h"
#include "vtkInformationExecutivePortVectorKey.h"
#include "vtkInformationIntegerKey.h"
#include "vtkInformationIterator.h"
#include "vtkInformationKeyVectorKey.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
......@@ -673,6 +674,11 @@ void vtkExecutive::CopyDefaultInformation(vtkInformation* request,
vtkInformationKey** keys = request->Get(KEYS_TO_COPY());
int length = request->Length(KEYS_TO_COPY());
vtkInformation* inInfo = inInfoVec[0]->GetInformationObject(0);
vtkSmartPointer<vtkInformationIterator> infoIter =
vtkSmartPointer<vtkInformationIterator>::New();
infoIter->SetInformation(inInfo);
int oiobj = outInfoVec->GetNumberOfInformationObjects();
for(int i=0; i < oiobj; ++i)
{
......@@ -689,6 +695,15 @@ void vtkExecutive::CopyDefaultInformation(vtkInformation* request,
outInfo->CopyEntries(inInfo, vkey);
}
}
// Give the keys an opportunity to copy themselves.
infoIter->InitTraversal();
while(!infoIter->IsDoneWithTraversal())
{
vtkInformationKey* key = infoIter->GetCurrentKey();
key->CopyDefaultInformation(request, inInfo, outInfo);
infoIter->GoToNextItem();
}
}
}
}
......@@ -709,6 +724,11 @@ void vtkExecutive::CopyDefaultInformation(vtkInformation* request,
vtkInformationKey** keys = request->Get(KEYS_TO_COPY());
int length = request->Length(KEYS_TO_COPY());
vtkInformation* outInfo = outInfoVec->GetInformationObject(outputPort);
vtkSmartPointer<vtkInformationIterator> infoIter =
vtkSmartPointer<vtkInformationIterator>::New();
infoIter->SetInformation(outInfo);
for(int i=0; i < this->GetNumberOfInputPorts(); ++i)
{
for(int j=0; j < inInfoVec[i]->GetNumberOfInformationObjects(); ++j)
......@@ -726,6 +746,15 @@ void vtkExecutive::CopyDefaultInformation(vtkInformation* request,
inInfo->CopyEntries(outInfo, vkey);
}
}
// Give the keys an opportunity to copy themselves.
infoIter->InitTraversal();
while(!infoIter->IsDoneWithTraversal())
{
vtkInformationKey* key = infoIter->GetCurrentKey();
key->CopyDefaultInformation(request, outInfo, inInfo);
infoIter->GoToNextItem();
}
}
}
}
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkInformationDataObjectMetaDataKey.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkInformationDataObjectMetaDataKey.h"
#include "vtkInformation.h"
#include "vtkStreamingDemandDrivenPipeline.h"
//----------------------------------------------------------------------------
vtkInformationDataObjectMetaDataKey::vtkInformationDataObjectMetaDataKey(const char* name, const char* location) :
vtkInformationDataObjectKey(name, location)
{
}
//----------------------------------------------------------------------------
vtkInformationDataObjectMetaDataKey::~vtkInformationDataObjectMetaDataKey()
{
}
//----------------------------------------------------------------------------
void vtkInformationDataObjectMetaDataKey::CopyDefaultInformation(
vtkInformation* request,
vtkInformation* fromInfo,
vtkInformation* toInfo)
{
if (request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_INFORMATION()))
{
this->ShallowCopy(fromInfo, toInfo);
}
}
//----------------------------------------------------------------------------
void vtkInformationDataObjectMetaDataKey::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
\ No newline at end of file
/*=========================================================================
Program: Visualization Toolkit
Module: vtkInformationDataObjectMetaDataKey.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkInformationDataObjectMetaDataKey - key used to define meta-data of type vtkDataObject
// vtkInformationDataObjectMetaDataKey is a vtkInformationDataObjectKey
// that (shallow) copies itself downstream during the REQUEST_INFORMATION pass. Hence
// it can be used to provide meta-data of type vtkDataObject or any subclass.
#ifndef __vtkInformationDataObjectMetaDataKey_h
#define __vtkInformationDataObjectMetaDataKey_h
#include "vtkCommonExecutionModelModule.h" // For export macro
#include "vtkInformationDataObjectKey.h"
#include "vtkCommonInformationKeyManager.h" // Manage instances of this type.
class VTKCOMMONEXECUTIONMODEL_EXPORT vtkInformationDataObjectMetaDataKey : public vtkInformationDataObjectKey
{
public:
vtkTypeMacro(vtkInformationDataObjectMetaDataKey,vtkInformationDataObjectKey);
void PrintSelf(ostream& os, vtkIndent indent);
vtkInformationDataObjectMetaDataKey(const char* name, const char* location);
~vtkInformationDataObjectMetaDataKey();
// Description:
// Simply shallow copies the key from fromInfo to toInfo if request
// has the REQUEST_INFORMATION() key.
// This is used by the pipeline to propagate this key downstream.
virtual void CopyDefaultInformation(vtkInformation* request,
vtkInformation* fromInfo,
vtkInformation* toInfo);
private:
vtkInformationDataObjectMetaDataKey(const vtkInformationDataObjectMetaDataKey&); // Not implemented.
void operator=(const vtkInformationDataObjectMetaDataKey&); // Not implemented.
};
#endif
/*=========================================================================
Program: Visualization Toolkit
Module: vtkInformationIntegerRequestKey.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkInformationIntegerRequestKey.h"
#include "vtkInformation.h"
#include "vtkStreamingDemandDrivenPipeline.h"
//----------------------------------------------------------------------------
vtkInformationIntegerRequestKey::vtkInformationIntegerRequestKey(const char* name, const char* location) :
vtkInformationIntegerKey(name, location)
{
this->DataKey = 0;
}
//----------------------------------------------------------------------------
vtkInformationIntegerRequestKey::~vtkInformationIntegerRequestKey()
{
}
//----------------------------------------------------------------------------
void vtkInformationIntegerRequestKey::CopyDefaultInformation(
vtkInformation* request,
vtkInformation* fromInfo,
vtkInformation* toInfo)
{
if (request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
{
this->ShallowCopy(fromInfo, toInfo);
}
}
//----------------------------------------------------------------------------
bool vtkInformationIntegerRequestKey::NeedToExecute(vtkInformation* pipelineInfo,
vtkInformation* dobjInfo)
{
if (!dobjInfo->Has(this->DataKey) ||
dobjInfo->Get(this->DataKey) != pipelineInfo->Get(this))
{
return true;
}
return false;
}
//----------------------------------------------------------------------------
void vtkInformationIntegerRequestKey::StoreMetaData(vtkInformation*,
vtkInformation* pipelineInfo,
vtkInformation* dobjInfo)
{
dobjInfo->Set(this->DataKey, pipelineInfo->Get(this));
}
//----------------------------------------------------------------------------
void vtkInformationIntegerRequestKey::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
\ No newline at end of file
/*=========================================================================
Program: Visualization Toolkit
Module: vtkInformationIntegerRequestKey.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkInformationIntegerRequestKey - key that can used to request integer values from the pipeline
// vtkInformationIntegerRequestKey is a vtkInformationIntegerKey that can
// used to request integer values from upstream. A good example of this is
// UPDATE_NUMBER_OF_PIECES where downstream can request that upstream provides
// data partitioned into a certain number of pieces. There are several components
// that make this work. First, the key will copy itself upstream during
// REQUEST_UPDATE_EXTENT. Second, after a successfull execution, it will stor
// its value into a data object's information using a specific key defined by
// its data member DataKey. Third, before execution, it will check if the requested
// value matched the value in the data object's information. If not, it will ask
// the pipeline to execute.
//
// The best way to use this class is to subclass it to set the DataKey data member.
// This is usually done in the subclass' constructor.
#ifndef __vtkInformationIntegerRequestKey_h
#define __vtkInformationIntegerRequestKey_h
#include "vtkCommonExecutionModelModule.h" // For export macro
#include "vtkInformationIntegerKey.h"
#include "vtkCommonInformationKeyManager.h" // Manage instances of this type.
class VTKCOMMONEXECUTIONMODEL_EXPORT vtkInformationIntegerRequestKey : public vtkInformationIntegerKey
{
public:
vtkTypeMacro(vtkInformationIntegerRequestKey,vtkInformationIntegerKey);
void PrintSelf(ostream& os, vtkIndent indent);
vtkInformationIntegerRequestKey(const char* name, const char* location);
~vtkInformationIntegerRequestKey();
// Description:
// Returns true if a value of type DataKey does not exist in dobjInfo
// or if it is different that the value stored in pipelineInfo using
// this key.
virtual bool NeedToExecute(vtkInformation* pipelineInfo,
vtkInformation* dobjInfo);
// Description:
// Copies the value stored in pipelineInfo using this key into
// dobjInfo.
virtual void StoreMetaData(vtkInformation* request,
vtkInformation* pipelineInfo,
vtkInformation* dobjInfo);
// Description:
// Copies the value stored in fromInfo using this key into toInfo
// if request has the REQUEST_UPDATE_EXTENT key.
virtual void CopyDefaultInformation(vtkInformation* request,
vtkInformation* fromInfo,
vtkInformation* toInfo);
protected:
vtkInformationIntegerKey* DataKey;
private:
vtkInformationIntegerRequestKey(const vtkInformationIntegerRequestKey&); // Not implemented.
void operator=(const vtkInformationIntegerRequestKey&); // Not implemented.
};
#endif
......@@ -27,6 +27,7 @@
#include "vtkInformationInformationVectorKey.h"
#include "vtkInformationIntegerKey.h"
#include "vtkInformationIntegerVectorKey.h"
#include "vtkInformationIterator.h"
#include "vtkInformationObjectBaseKey.h"
#include "vtkInformationRequestKey.h"
#include "vtkInformationStringKey.h"
......@@ -1109,6 +1110,22 @@ vtkStreamingDemandDrivenPipeline
{
outInfo->Remove(PREVIOUS_UPDATE_TIME_STEP());
}
// Give the keys an opportunity to store meta-data in
// the data object about what update request lead to
// the last execution. This information can later be
// used to decide whether an execution is necessary.
vtkSmartPointer<vtkInformationIterator> infoIter =
vtkSmartPointer<vtkInformationIterator>::New();
infoIter->SetInformation(outInfo);
infoIter->InitTraversal();
while(!infoIter->IsDoneWithTraversal())
{
vtkInformationKey* key = infoIter->GetCurrentKey();
key->StoreMetaData(request, outInfo, dataInfo);
infoIter->GoToNextItem();
}
}
}
}
......@@ -1236,6 +1253,25 @@ int vtkStreamingDemandDrivenPipeline
return 1;
}
// Ask the keys if we need to execute. Keys can overwrite
// NeedToExecute() to make their own decision about whether
// what they are asking for is different than what is in the
// data and whether the filter should execute.
vtkSmartPointer<vtkInformationIterator> infoIter =
vtkSmartPointer<vtkInformationIterator>::New();
infoIter->SetInformation(outInfo);
infoIter->InitTraversal();
while(!infoIter->IsDoneWithTraversal())
{
vtkInformationKey* key = infoIter->GetCurrentKey();
if (key->NeedToExecute(outInfo, dataInfo))
{
return 1;
}
infoIter->GoToNextItem();
}
// We do not need to execute.
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment