You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
795 lines
24 KiB
795 lines
24 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkExecutive.cxx,v $
|
|
|
|
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 "vtkExecutive.h"
|
|
|
|
#include "vtkAlgorithm.h"
|
|
#include "vtkAlgorithmOutput.h"
|
|
#include "vtkCompositeDataPipeline.h"
|
|
#include "vtkDataObject.h"
|
|
#include "vtkGarbageCollector.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationExecutivePortKey.h"
|
|
#include "vtkInformationExecutivePortVectorKey.h"
|
|
#include "vtkInformationIntegerKey.h"
|
|
#include "vtkInformationKeyVectorKey.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkSmartPointer.h"
|
|
|
|
#include <vtkstd/vector>
|
|
#include <vtksys/ios/sstream>
|
|
|
|
vtkCxxRevisionMacro(vtkExecutive, "$Revision: 1.27.4.3 $");
|
|
vtkInformationKeyMacro(vtkExecutive, ALGORITHM_AFTER_FORWARD, Integer);
|
|
vtkInformationKeyMacro(vtkExecutive, ALGORITHM_BEFORE_FORWARD, Integer);
|
|
vtkInformationKeyMacro(vtkExecutive, ALGORITHM_DIRECTION, Integer);
|
|
vtkInformationKeyMacro(vtkExecutive, CONSUMERS, ExecutivePortVector);
|
|
vtkInformationKeyMacro(vtkExecutive, FORWARD_DIRECTION, Integer);
|
|
vtkInformationKeyMacro(vtkExecutive, FROM_OUTPUT_PORT, Integer);
|
|
vtkInformationKeyMacro(vtkExecutive, KEYS_TO_COPY, KeyVector);
|
|
vtkInformationKeyMacro(vtkExecutive, PRODUCER, ExecutivePort);
|
|
|
|
//----------------------------------------------------------------------------
|
|
class vtkExecutiveInternals
|
|
{
|
|
public:
|
|
vtkstd::vector<vtkInformationVector*> InputInformation;
|
|
vtkExecutiveInternals();
|
|
~vtkExecutiveInternals();
|
|
vtkInformationVector** GetInputInformation(int newNumberOfPorts);
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkExecutiveInternals::vtkExecutiveInternals()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkExecutiveInternals::~vtkExecutiveInternals()
|
|
{
|
|
// Delete all the input information vectors.
|
|
for(vtkstd::vector<vtkInformationVector*>::iterator
|
|
i = this->InputInformation.begin();
|
|
i != this->InputInformation.end(); ++i)
|
|
{
|
|
if(vtkInformationVector* v = *i)
|
|
{
|
|
v->Delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkInformationVector**
|
|
vtkExecutiveInternals::GetInputInformation(int newNumberOfPorts)
|
|
{
|
|
// Adjust the number of vectors.
|
|
int oldNumberOfPorts = static_cast<int>(this->InputInformation.size());
|
|
if(newNumberOfPorts > oldNumberOfPorts)
|
|
{
|
|
// Create new vectors.
|
|
this->InputInformation.resize(newNumberOfPorts, 0);
|
|
for(int i=oldNumberOfPorts; i < newNumberOfPorts; ++i)
|
|
{
|
|
this->InputInformation[i] = vtkInformationVector::New();
|
|
}
|
|
}
|
|
else if(newNumberOfPorts < oldNumberOfPorts)
|
|
{
|
|
// Delete old vectors.
|
|
for(int i=newNumberOfPorts; i < oldNumberOfPorts; ++i)
|
|
{
|
|
if(vtkInformationVector* v = this->InputInformation[i])
|
|
{
|
|
// Set the pointer to NULL first to avoid reporting of the
|
|
// entry if deleting the vector causes a garbage collection
|
|
// reference walk.
|
|
this->InputInformation[i] = 0;
|
|
v->Delete();
|
|
}
|
|
}
|
|
this->InputInformation.resize(newNumberOfPorts);
|
|
}
|
|
|
|
// Return the array of information vector pointers.
|
|
if(newNumberOfPorts > 0)
|
|
{
|
|
return &this->InputInformation[0];
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkExecutive::vtkExecutive()
|
|
{
|
|
this->ExecutiveInternal = new vtkExecutiveInternals;
|
|
this->OutputInformation = vtkInformationVector::New();
|
|
this->Algorithm = 0;
|
|
this->InAlgorithm = 0;
|
|
this->SharedInputInformation = 0;
|
|
this->SharedOutputInformation = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkExecutive::~vtkExecutive()
|
|
{
|
|
this->SetAlgorithm(0);
|
|
if(this->OutputInformation)
|
|
{
|
|
this->OutputInformation->Delete();
|
|
}
|
|
delete this->ExecutiveInternal;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkExecutive::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
if(this->Algorithm)
|
|
{
|
|
os << indent << "Algorithm: " << this->Algorithm << "\n";
|
|
}
|
|
else
|
|
{
|
|
os << indent << "Algorithm: (none)\n";
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkExecutive::Register(vtkObjectBase* o)
|
|
{
|
|
this->RegisterInternal(o, 1);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkExecutive::UnRegister(vtkObjectBase* o)
|
|
{
|
|
this->UnRegisterInternal(o, 1);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkExecutive::SetAlgorithm(vtkAlgorithm* newAlgorithm)
|
|
{
|
|
vtkDebugMacro(<< this->GetClassName() << " (" << this
|
|
<< "): setting Algorithm to " << newAlgorithm);
|
|
vtkAlgorithm* oldAlgorithm = this->Algorithm;
|
|
if(oldAlgorithm != newAlgorithm)
|
|
{
|
|
if(newAlgorithm)
|
|
{
|
|
newAlgorithm->Register(this);
|
|
}
|
|
this->Algorithm = newAlgorithm;
|
|
if(oldAlgorithm)
|
|
{
|
|
oldAlgorithm->UnRegister(this);
|
|
}
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkAlgorithm* vtkExecutive::GetAlgorithm()
|
|
{
|
|
return this->Algorithm;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkInformationVector** vtkExecutive::GetInputInformation()
|
|
{
|
|
// Use the shared input information vector if any is set.
|
|
if(this->SharedInputInformation)
|
|
{
|
|
return this->SharedInputInformation;
|
|
}
|
|
|
|
// Use this executive's input information vector.
|
|
if(this->Algorithm)
|
|
{
|
|
int numPorts = this->Algorithm->GetNumberOfInputPorts();
|
|
return this->ExecutiveInternal->GetInputInformation(numPorts);
|
|
}
|
|
else
|
|
{
|
|
return this->ExecutiveInternal->GetInputInformation(0);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkInformation* vtkExecutive::GetInputInformation(int port, int connection)
|
|
{
|
|
if(!this->InputPortIndexInRange(port, "get connected input information from"))
|
|
{
|
|
return 0;
|
|
}
|
|
vtkInformationVector* inVector = this->GetInputInformation()[port];
|
|
return inVector->GetInformationObject(connection);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkInformationVector* vtkExecutive::GetInputInformation(int port)
|
|
{
|
|
if(!this->InputPortIndexInRange(port, "get input information vector from"))
|
|
{
|
|
return 0;
|
|
}
|
|
return this->GetInputInformation()[port];
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkInformationVector* vtkExecutive::GetOutputInformation()
|
|
{
|
|
// Use the shared output information vector if any is set.
|
|
if(this->SharedOutputInformation)
|
|
{
|
|
return this->SharedOutputInformation;
|
|
}
|
|
|
|
// Use this executive's output information vector.
|
|
if (!this->Algorithm)
|
|
{
|
|
return 0;
|
|
}
|
|
// Set the length of the vector to match the number of ports.
|
|
int oldNumberOfPorts =
|
|
this->OutputInformation->GetNumberOfInformationObjects();
|
|
this->OutputInformation
|
|
->SetNumberOfInformationObjects(this->GetNumberOfOutputPorts());
|
|
|
|
// For any new information obects, set the executive pointer and
|
|
// port number on the information object to tell it what produces
|
|
// it.
|
|
int nop = this->Algorithm->GetNumberOfOutputPorts();
|
|
for(int i = oldNumberOfPorts; i < nop; ++i)
|
|
{
|
|
vtkInformation* info = this->OutputInformation->GetInformationObject(i);
|
|
info->Set(vtkExecutive::PRODUCER(), this, i);
|
|
}
|
|
|
|
return this->OutputInformation;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkInformation* vtkExecutive::GetOutputInformation(int port)
|
|
{
|
|
return this->GetOutputInformation()->GetInformationObject(port);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkExecutive* vtkExecutive::GetInputExecutive(int port, int index)
|
|
{
|
|
if(index < 0 || index >= this->GetNumberOfInputConnections(port))
|
|
{
|
|
vtkErrorMacro("Attempt to get executive for connection index " << index
|
|
<< " on input port " << port << " of algorithm "
|
|
<< this->Algorithm->GetClassName() << "(" << this->Algorithm
|
|
<< "), which has "
|
|
<< this->GetNumberOfInputConnections(port)
|
|
<< " connections.");
|
|
return 0;
|
|
}
|
|
if(vtkAlgorithmOutput* input = this->Algorithm->GetInputConnection(port, index))
|
|
{
|
|
return input->GetProducer()->GetExecutive();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkExecutive::ReportReferences(vtkGarbageCollector* collector)
|
|
{
|
|
// Report reference to our algorithm.
|
|
vtkGarbageCollectorReport(collector, this->Algorithm, "Algorithm");
|
|
for(int i=0; i < int(this->ExecutiveInternal->InputInformation.size()); ++i)
|
|
{
|
|
vtkGarbageCollectorReport(collector,
|
|
this->ExecutiveInternal->InputInformation[i],
|
|
"Input Information Vector");
|
|
}
|
|
vtkGarbageCollectorReport(collector, this->OutputInformation,
|
|
"Output Information Vector");
|
|
this->Superclass::ReportReferences(collector);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::Update()
|
|
{
|
|
if (this->Algorithm->GetNumberOfOutputPorts())
|
|
{
|
|
return this->Update(0);
|
|
}
|
|
return this->Update(-1);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::Update(int)
|
|
{
|
|
vtkErrorMacro("This class does not implement Update.");
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::GetNumberOfInputPorts()
|
|
{
|
|
if(this->Algorithm)
|
|
{
|
|
return this->Algorithm->GetNumberOfInputPorts();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::GetNumberOfOutputPorts()
|
|
{
|
|
if(this->Algorithm)
|
|
{
|
|
return this->Algorithm->GetNumberOfOutputPorts();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::GetNumberOfInputConnections(int port)
|
|
{
|
|
vtkInformationVector* inputs = this->GetInputInformation(port);
|
|
if (inputs)
|
|
{
|
|
return inputs->GetNumberOfInformationObjects();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::InputPortIndexInRange(int port, const char* action)
|
|
{
|
|
// Make sure the algorithm is set.
|
|
if(!this->Algorithm)
|
|
{
|
|
vtkErrorMacro("Attempt to " << (action?action:"access") <<
|
|
" input port index " << port << " with no algorithm set.");
|
|
return 0;
|
|
}
|
|
|
|
// Make sure the index of the input port is in range.
|
|
if(port < 0 || port >= this->Algorithm->GetNumberOfInputPorts())
|
|
{
|
|
vtkErrorMacro("Attempt to " << (action?action:"access")
|
|
<< " input port index " << port << " for algorithm "
|
|
<< this->Algorithm->GetClassName()
|
|
<< "(" << this->Algorithm << "), which has "
|
|
<< this->Algorithm->GetNumberOfInputPorts()
|
|
<< " input ports.");
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::OutputPortIndexInRange(int port, const char* action)
|
|
{
|
|
// Make sure the algorithm is set.
|
|
if(!this->Algorithm)
|
|
{
|
|
vtkErrorMacro("Attempt to " << (action?action:"access") <<
|
|
" output port index " << port << " with no algorithm set.");
|
|
return 0;
|
|
}
|
|
|
|
// Make sure the index of the output port is in range.
|
|
if(port < 0 || port >= this->Algorithm->GetNumberOfOutputPorts())
|
|
{
|
|
vtkErrorMacro("Attempt to " << (action?action:"access")
|
|
<< " output port index " << port << " for algorithm "
|
|
<< this->Algorithm->GetClassName()
|
|
<< "(" << this->Algorithm << "), which has "
|
|
<< this->Algorithm->GetNumberOfOutputPorts()
|
|
<< " output ports.");
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkAlgorithmOutput* vtkExecutive::GetProducerPort(vtkDataObject* d)
|
|
{
|
|
if(this->Algorithm && d)
|
|
{
|
|
vtkInformation* info = d->GetPipelineInformation();
|
|
vtkExecutive* dExecutive;
|
|
int port;
|
|
info->Get(vtkExecutive::PRODUCER(),dExecutive,port);
|
|
if(dExecutive == this)
|
|
{
|
|
return this->Algorithm->GetOutputPort(port);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkExecutive::SetSharedInputInformation(vtkInformationVector** inInfoVec)
|
|
{
|
|
this->SharedInputInformation = inInfoVec;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkExecutive::SetSharedOutputInformation(vtkInformationVector* outInfoVec)
|
|
{
|
|
this->SharedOutputInformation = outInfoVec;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkDataObject* vtkExecutive::GetOutputData(int port)
|
|
{
|
|
if(!this->OutputPortIndexInRange(port, "get data for"))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
vtkInformation* info = this->GetOutputInformation(port);
|
|
if (!info)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// for backward compatibility we bring Outputs up to date if they do not
|
|
// already exist
|
|
if (!this->InAlgorithm && !info->Has(vtkDataObject::DATA_OBJECT()))
|
|
{
|
|
// Bring the data object up to date only if it isn't already there
|
|
this->UpdateDataObject();
|
|
}
|
|
|
|
// Return the data object.
|
|
return info->Get(vtkDataObject::DATA_OBJECT());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkExecutive::SetOutputData(int newPort, vtkDataObject* newOutput)
|
|
{
|
|
vtkInformation *info = this->GetOutputInformation(newPort);
|
|
this->SetOutputData(newPort, newOutput, info);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkExecutive::SetOutputData(int newPort, vtkDataObject* newOutput,
|
|
vtkInformation* info)
|
|
{
|
|
if(info)
|
|
{
|
|
if(!newOutput || newOutput->GetPipelineInformation() != info)
|
|
{
|
|
if(newOutput)
|
|
{
|
|
newOutput->SetPipelineInformation(info);
|
|
}
|
|
else if(vtkDataObject* oldOutput = info->Get(vtkDataObject::DATA_OBJECT()))
|
|
{
|
|
oldOutput->Register(this);
|
|
oldOutput->SetPipelineInformation(0);
|
|
oldOutput->UnRegister(this);
|
|
}
|
|
|
|
// Output has changed. Reset the pipeline information.
|
|
this->ResetPipelineInformation(newPort, info);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vtkErrorMacro("Could not set output on port " << newPort << ".");
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkDataObject* vtkExecutive::GetInputData(int port, int index)
|
|
{
|
|
if(index < 0 || index >= this->GetNumberOfInputConnections(port))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
vtkInformationVector* inVector = this->GetInputInformation()[port];
|
|
vtkInformation* info = inVector->GetInformationObject(index);
|
|
vtkExecutive* e;
|
|
int producerPort;
|
|
info->Get(vtkExecutive::PRODUCER(),e,producerPort);
|
|
if(e)
|
|
{
|
|
return e->GetOutputData(producerPort);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkDataObject* vtkExecutive::GetInputData
|
|
(int port, int index, vtkInformationVector **inInfoVec)
|
|
{
|
|
if (!inInfoVec[port])
|
|
{
|
|
return 0;
|
|
}
|
|
vtkInformation *info = inInfoVec[port]->GetInformationObject(index);
|
|
if (!info)
|
|
{
|
|
return 0;
|
|
}
|
|
return info->Get(vtkDataObject::DATA_OBJECT());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::ProcessRequest(vtkInformation* request,
|
|
vtkInformationVector** inInfo,
|
|
vtkInformationVector* outInfo)
|
|
{
|
|
if(request->Has(FORWARD_DIRECTION()))
|
|
{
|
|
// Request will be forwarded.
|
|
if(request->Get(FORWARD_DIRECTION()) == vtkExecutive::RequestUpstream)
|
|
{
|
|
if(this->Algorithm && request->Get(ALGORITHM_BEFORE_FORWARD()))
|
|
{
|
|
if(!this->CallAlgorithm(request, vtkExecutive::RequestUpstream,
|
|
inInfo, outInfo))
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
if(!this->ForwardUpstream(request))
|
|
{
|
|
return 0;
|
|
}
|
|
if(this->Algorithm && request->Get(ALGORITHM_AFTER_FORWARD()))
|
|
{
|
|
if(!this->CallAlgorithm(request, vtkExecutive::RequestDownstream,
|
|
inInfo, outInfo))
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
if(request->Get(FORWARD_DIRECTION()) == vtkExecutive::RequestDownstream)
|
|
{
|
|
vtkErrorMacro("Downstream forwarding not yet implemented.");
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Request will not be forwarded.
|
|
vtkErrorMacro("Non-forwarded requests are not yet implemented.");
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::ComputePipelineMTime(vtkInformation*,
|
|
vtkInformationVector**,
|
|
vtkInformationVector*,
|
|
int, unsigned long*)
|
|
{
|
|
// Demand-driven executives that use this request should implement
|
|
// this method.
|
|
vtkErrorMacro("ComputePipelineMTime not implemented for this executive.");
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::ForwardDownstream(vtkInformation*)
|
|
{
|
|
// Do not forward downstream if the output is shared with another
|
|
// executive.
|
|
if(this->SharedOutputInformation)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
// Forwarding downstream is not yet implemented.
|
|
vtkErrorMacro("ForwardDownstream not yet implemented.");
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::ForwardUpstream(vtkInformation* request)
|
|
{
|
|
// Do not forward upstream if the input is shared with another
|
|
// executive.
|
|
if(this->SharedInputInformation)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (!this->Algorithm->ModifyRequest(request, BeforeForward))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Forward the request upstream through all input connections.
|
|
int result = 1;
|
|
for(int i=0; i < this->GetNumberOfInputPorts(); ++i)
|
|
{
|
|
int nic = this->Algorithm->GetNumberOfInputConnections(i);
|
|
vtkInformationVector* inVector = this->GetInputInformation()[i];
|
|
for(int j=0; j < nic; ++j)
|
|
{
|
|
vtkInformation* info = inVector->GetInformationObject(j);
|
|
// Get the executive producing this input. If there is none, then
|
|
// it is a NULL input.
|
|
vtkExecutive* e;
|
|
int producerPort;
|
|
info->Get(vtkExecutive::PRODUCER(),e,producerPort);
|
|
if(e)
|
|
{
|
|
int port = request->Get(FROM_OUTPUT_PORT());
|
|
request->Set(FROM_OUTPUT_PORT(), producerPort);
|
|
if(!e->ProcessRequest(request,
|
|
e->GetInputInformation(),
|
|
e->GetOutputInformation()))
|
|
{
|
|
result = 0;
|
|
}
|
|
request->Set(FROM_OUTPUT_PORT(), port);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!this->Algorithm->ModifyRequest(request, AfterForward))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkExecutive::CopyDefaultInformation(vtkInformation* request,
|
|
int direction,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec)
|
|
|
|
{
|
|
if(direction == vtkExecutive::RequestDownstream)
|
|
{
|
|
// Copy information from the first input to all outputs.
|
|
if(this->GetNumberOfInputPorts() > 0 &&
|
|
inInfoVec[0]->GetNumberOfInformationObjects() > 0)
|
|
{
|
|
vtkInformationKey** keys = request->Get(KEYS_TO_COPY());
|
|
int length = request->Length(KEYS_TO_COPY());
|
|
vtkInformation* inInfo = inInfoVec[0]->GetInformationObject(0);
|
|
int oiobj = outInfoVec->GetNumberOfInformationObjects();
|
|
for(int i=0; i < oiobj; ++i)
|
|
{
|
|
vtkInformation* outInfo = outInfoVec->GetInformationObject(i);
|
|
for(int j=0; j < length; ++j)
|
|
{
|
|
// Copy the entry.
|
|
outInfo->CopyEntry(inInfo, keys[j]);
|
|
|
|
// If the entry is a key vector, copy all the keys listed.
|
|
if(vtkInformationKeyVectorKey* vkey =
|
|
vtkInformationKeyVectorKey::SafeDownCast(keys[j]))
|
|
{
|
|
outInfo->CopyEntries(inInfo, vkey);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Get the output port from which the request was made. Use zero
|
|
// if output port was not specified.
|
|
int outputPort = 0;
|
|
if(request->Has(FROM_OUTPUT_PORT()))
|
|
{
|
|
outputPort = request->Get(FROM_OUTPUT_PORT());
|
|
}
|
|
|
|
// Copy information from the requesting output to all inputs.
|
|
if(outputPort >= 0 &&
|
|
outputPort < outInfoVec->GetNumberOfInformationObjects())
|
|
{
|
|
vtkInformationKey** keys = request->Get(KEYS_TO_COPY());
|
|
int length = request->Length(KEYS_TO_COPY());
|
|
vtkInformation* outInfo = outInfoVec->GetInformationObject(outputPort);
|
|
for(int i=0; i < this->GetNumberOfInputPorts(); ++i)
|
|
{
|
|
for(int j=0; j < inInfoVec[i]->GetNumberOfInformationObjects(); ++j)
|
|
{
|
|
vtkInformation* inInfo = inInfoVec[i]->GetInformationObject(j);
|
|
for(int k=0; k < length; ++k)
|
|
{
|
|
// Copy the entry.
|
|
inInfo->CopyEntry(outInfo, keys[k]);
|
|
|
|
// If the entry is a key vector, copy all the keys listed.
|
|
if(vtkInformationKeyVectorKey* vkey =
|
|
vtkInformationKeyVectorKey::SafeDownCast(keys[k]))
|
|
{
|
|
inInfo->CopyEntries(outInfo, vkey);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::CallAlgorithm(vtkInformation* request, int direction,
|
|
vtkInformationVector** inInfo,
|
|
vtkInformationVector* outInfo)
|
|
{
|
|
// Copy default information in the direction of information flow.
|
|
this->CopyDefaultInformation(request, direction, inInfo, outInfo);
|
|
|
|
// Invoke the request on the algorithm.
|
|
this->InAlgorithm = 1;
|
|
int result = this->Algorithm->ProcessRequest(request, inInfo, outInfo);
|
|
this->InAlgorithm = 0;
|
|
|
|
// If the algorithm failed report it now.
|
|
if(!result)
|
|
{
|
|
vtkErrorMacro("Algorithm " << this->Algorithm->GetClassName()
|
|
<< "(" << this->Algorithm
|
|
<< ") returned failure for request: "
|
|
<< *request);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkExecutive::CheckAlgorithm(const char* method,
|
|
vtkInformation* request)
|
|
{
|
|
if(this->InAlgorithm)
|
|
{
|
|
if(request)
|
|
{
|
|
vtksys_ios::ostringstream rqmsg;
|
|
request->Print(rqmsg);
|
|
vtkErrorMacro(<< method << " invoked during another request. "
|
|
"Returning failure to algorithm "
|
|
<< this->Algorithm->GetClassName() << "("
|
|
<< this->Algorithm << ") for the recursive request:\n"
|
|
<< rqmsg.str().c_str());
|
|
}
|
|
else
|
|
{
|
|
vtkErrorMacro(<< method << " invoked during another request. "
|
|
"Returning failure to algorithm "
|
|
<< this->Algorithm->GetClassName() << "("
|
|
<< this->Algorithm << ").");
|
|
}
|
|
|
|
// Tests should fail when this happens because there is a bug in
|
|
// the code.
|
|
if(getenv("DASHBOARD_TEST_FROM_CTEST") || getenv("DART_TEST_FROM_DART"))
|
|
{
|
|
abort();
|
|
}
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|