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.
1251 lines
41 KiB
1251 lines
41 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkStreamingDemandDrivenPipeline.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 "vtkStreamingDemandDrivenPipeline.h"
|
|
|
|
#include "vtkAlgorithm.h"
|
|
#include "vtkAlgorithmOutput.h"
|
|
#include "vtkDataObject.h"
|
|
#include "vtkDataSet.h"
|
|
#include "vtkExtentTranslator.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationDoubleVectorKey.h"
|
|
#include "vtkInformationIntegerKey.h"
|
|
#include "vtkInformationIntegerVectorKey.h"
|
|
#include "vtkInformationObjectBaseKey.h"
|
|
#include "vtkInformationRequestKey.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkSmartPointer.h"
|
|
|
|
vtkCxxRevisionMacro(vtkStreamingDemandDrivenPipeline, "$Revision: 1.35.2.1 $");
|
|
vtkStandardNewMacro(vtkStreamingDemandDrivenPipeline);
|
|
|
|
vtkInformationKeyMacro(vtkStreamingDemandDrivenPipeline, CONTINUE_EXECUTING, Integer);
|
|
vtkInformationKeyMacro(vtkStreamingDemandDrivenPipeline, EXACT_EXTENT, Integer);
|
|
vtkInformationKeyMacro(vtkStreamingDemandDrivenPipeline, REQUEST_UPDATE_EXTENT, Request);
|
|
vtkInformationKeyMacro(vtkStreamingDemandDrivenPipeline, MAXIMUM_NUMBER_OF_PIECES, Integer);
|
|
vtkInformationKeyMacro(vtkStreamingDemandDrivenPipeline, UPDATE_EXTENT_INITIALIZED, Integer);
|
|
vtkInformationKeyMacro(vtkStreamingDemandDrivenPipeline, UPDATE_PIECE_NUMBER, Integer);
|
|
vtkInformationKeyMacro(vtkStreamingDemandDrivenPipeline, UPDATE_NUMBER_OF_PIECES, Integer);
|
|
vtkInformationKeyMacro(vtkStreamingDemandDrivenPipeline, UPDATE_NUMBER_OF_GHOST_LEVELS, Integer);
|
|
vtkInformationKeyRestrictedMacro(vtkStreamingDemandDrivenPipeline, WHOLE_EXTENT, IntegerVector, 6);
|
|
vtkInformationKeyRestrictedMacro(vtkStreamingDemandDrivenPipeline, UPDATE_EXTENT, IntegerVector, 6);
|
|
vtkInformationKeyRestrictedMacro(vtkStreamingDemandDrivenPipeline,
|
|
EXTENT_TRANSLATOR, ObjectBase,
|
|
"vtkExtentTranslator");
|
|
vtkInformationKeyRestrictedMacro(vtkStreamingDemandDrivenPipeline, WHOLE_BOUNDING_BOX, DoubleVector, 6);
|
|
vtkInformationKeyMacro(vtkStreamingDemandDrivenPipeline, TIME_STEPS, DoubleVector);
|
|
vtkInformationKeyMacro(vtkStreamingDemandDrivenPipeline, UPDATE_TIME_INDEX, Integer);
|
|
|
|
//----------------------------------------------------------------------------
|
|
class vtkStreamingDemandDrivenPipelineToDataObjectFriendship
|
|
{
|
|
public:
|
|
static void Crop(vtkDataObject* obj)
|
|
{
|
|
obj->Crop();
|
|
}
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkStreamingDemandDrivenPipeline::vtkStreamingDemandDrivenPipeline()
|
|
{
|
|
this->ContinueExecuting = 0;
|
|
this->UpdateExtentRequest = 0;
|
|
this->LastPropogateUpdateExtentShortCircuited = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkStreamingDemandDrivenPipeline::~vtkStreamingDemandDrivenPipeline()
|
|
{
|
|
if (this->UpdateExtentRequest)
|
|
{
|
|
this->UpdateExtentRequest->Delete();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkStreamingDemandDrivenPipeline::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::ProcessRequest(vtkInformation* request,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec)
|
|
{
|
|
// The algorithm should not invoke anything on the executive.
|
|
if(!this->CheckAlgorithm("ProcessRequest", request))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Look for specially supported requests.
|
|
if(request->Has(REQUEST_UPDATE_EXTENT()))
|
|
{
|
|
// Get the output port from which the request was made.
|
|
this->LastPropogateUpdateExtentShortCircuited = 1;
|
|
int outputPort = -1;
|
|
if(request->Has(FROM_OUTPUT_PORT()))
|
|
{
|
|
outputPort = request->Get(FROM_OUTPUT_PORT());
|
|
}
|
|
|
|
// Make sure the information on the output port is valid.
|
|
if(!this->VerifyOutputInformation(outputPort,inInfoVec,outInfoVec))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// If we need to execute, propagate the update extent.
|
|
int result = 1;
|
|
if(this->NeedToExecuteData(outputPort,inInfoVec,outInfoVec))
|
|
{
|
|
// Make sure input types are valid before algorithm does anything.
|
|
if(!this->InputCountIsValid(inInfoVec) ||
|
|
!this->InputTypeIsValid(inInfoVec))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Invoke the request on the algorithm.
|
|
this->LastPropogateUpdateExtentShortCircuited = 0;
|
|
result = this->CallAlgorithm(request, vtkExecutive::RequestUpstream,
|
|
inInfoVec, outInfoVec);
|
|
|
|
// Propagate the update extent to all inputs.
|
|
if(result)
|
|
{
|
|
result = this->ForwardUpstream(request);
|
|
}
|
|
result = 1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
if(request->Has(REQUEST_DATA()))
|
|
{
|
|
// Let the superclass handle the request first.
|
|
if(this->Superclass::ProcessRequest(request, inInfoVec, outInfoVec))
|
|
{
|
|
// Crop the output if the exact extent flag is set.
|
|
for(int i=0; i < outInfoVec->GetNumberOfInformationObjects(); ++i)
|
|
{
|
|
vtkInformation* info = outInfoVec->GetInformationObject(i);
|
|
if(info->Has(EXACT_EXTENT()) && info->Get(EXACT_EXTENT()))
|
|
{
|
|
vtkDataObject* data = info->Get(vtkDataObject::DATA_OBJECT());
|
|
vtkStreamingDemandDrivenPipelineToDataObjectFriendship::Crop(data);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Let the superclass handle other requests.
|
|
return this->Superclass::ProcessRequest(request, inInfoVec, outInfoVec);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline::Update()
|
|
{
|
|
return this->Superclass::Update();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline::Update(int port)
|
|
{
|
|
if(!this->UpdateInformation())
|
|
{
|
|
return 0;
|
|
}
|
|
if(port >= -1 && port < this->Algorithm->GetNumberOfOutputPorts())
|
|
{
|
|
int retval = 1;
|
|
// some streaming filters can request that the pipeline execute multiple
|
|
// times for a single update
|
|
do
|
|
{
|
|
retval = retval && this->PropagateUpdateExtent(port);
|
|
if (retval && !this->LastPropogateUpdateExtentShortCircuited)
|
|
{
|
|
retval = retval && this->UpdateData(port);
|
|
}
|
|
}
|
|
while (this->ContinueExecuting);
|
|
return retval;
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline::UpdateWholeExtent()
|
|
{
|
|
this->UpdateInformation();
|
|
// if we have an output then set the UE to WE for it
|
|
if (this->Algorithm->GetNumberOfOutputPorts())
|
|
{
|
|
this->SetUpdateExtentToWholeExtent
|
|
(this->GetOutputInformation()->GetInformationObject(0));
|
|
}
|
|
// otherwise do it for the inputs
|
|
else
|
|
{
|
|
// Loop over all input ports.
|
|
for(int i=0; i < this->Algorithm->GetNumberOfInputPorts(); ++i)
|
|
{
|
|
// Loop over all connections on this input port.
|
|
int numInConnections = this->Algorithm->GetNumberOfInputConnections(i);
|
|
for (int j=0; j<numInConnections; j++)
|
|
{
|
|
// Get the pipeline information for this input connection.
|
|
vtkInformation* inInfo = this->GetInputInformation(i, j);
|
|
this->SetUpdateExtentToWholeExtent(inInfo);
|
|
}
|
|
}
|
|
}
|
|
return this->Update();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
vtkStreamingDemandDrivenPipeline
|
|
::ExecuteInformation(vtkInformation* request,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec)
|
|
{
|
|
// Let the superclass make the request to the algorithm.
|
|
if(this->Superclass::ExecuteInformation(request,inInfoVec,outInfoVec))
|
|
{
|
|
for(int i=0; i < this->Algorithm->GetNumberOfOutputPorts(); ++i)
|
|
{
|
|
vtkInformation* info = outInfoVec->GetInformationObject(i);
|
|
vtkDataObject* data = info->Get(vtkDataObject::DATA_OBJECT());
|
|
|
|
if (!data)
|
|
{
|
|
return 0;
|
|
}
|
|
// Set default maximum request.
|
|
if(data->GetExtentType() == VTK_PIECES_EXTENT)
|
|
{
|
|
if(!info->Has(MAXIMUM_NUMBER_OF_PIECES()))
|
|
{
|
|
info->Set(MAXIMUM_NUMBER_OF_PIECES(), -1);
|
|
}
|
|
}
|
|
else if(data->GetExtentType() == VTK_3D_EXTENT)
|
|
{
|
|
if(!info->Has(WHOLE_EXTENT()))
|
|
{
|
|
int extent[6] = {0,-1,0,-1,0,-1};
|
|
info->Set(WHOLE_EXTENT(), extent, 6);
|
|
}
|
|
}
|
|
|
|
// Make sure an update request exists.
|
|
if(!info->Has(UPDATE_EXTENT_INITIALIZED()) ||
|
|
!info->Get(UPDATE_EXTENT_INITIALIZED()))
|
|
{
|
|
// Request all data by default.
|
|
this->SetUpdateExtentToWholeExtent
|
|
(outInfoVec->GetInformationObject(i));
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
vtkStreamingDemandDrivenPipeline
|
|
::CopyDefaultInformation(vtkInformation* request, int direction,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec)
|
|
{
|
|
// Let the superclass copy first.
|
|
this->Superclass::CopyDefaultInformation(request, direction,
|
|
inInfoVec, outInfoVec);
|
|
|
|
if(request->Has(REQUEST_INFORMATION()))
|
|
{
|
|
if(this->GetNumberOfInputPorts() > 0)
|
|
{
|
|
if(vtkInformation* inInfo = inInfoVec[0]->GetInformationObject(0))
|
|
{
|
|
// Copy information from the first input to all outputs.
|
|
for(int i=0; i < outInfoVec->GetNumberOfInformationObjects(); ++i)
|
|
{
|
|
vtkInformation* outInfo = outInfoVec->GetInformationObject(i);
|
|
outInfo->CopyEntry(inInfo, WHOLE_BOUNDING_BOX());
|
|
outInfo->CopyEntry(inInfo, WHOLE_EXTENT());
|
|
outInfo->CopyEntry(inInfo, MAXIMUM_NUMBER_OF_PIECES());
|
|
outInfo->CopyEntry(inInfo, EXTENT_TRANSLATOR());
|
|
outInfo->CopyEntry(inInfo, TIME_STEPS());
|
|
}
|
|
}
|
|
}
|
|
|
|
// Setup default information for the outputs.
|
|
for(int i=0; i < outInfoVec->GetNumberOfInformationObjects(); ++i)
|
|
{
|
|
vtkInformation* outInfo = outInfoVec->GetInformationObject(i);
|
|
|
|
// The data object will exist because UpdateDataObject has already
|
|
// succeeded. Except when this method is called by a subclass
|
|
// that does not provide this key in certain cases.
|
|
vtkDataObject* dataObject = outInfo->Get(vtkDataObject::DATA_OBJECT());
|
|
if (!dataObject)
|
|
{
|
|
continue;
|
|
}
|
|
vtkInformation* dataInfo = dataObject->GetInformation();
|
|
if(dataInfo->Get(vtkDataObject::DATA_EXTENT_TYPE()) == VTK_PIECES_EXTENT)
|
|
{
|
|
if (!outInfo->Has(MAXIMUM_NUMBER_OF_PIECES()))
|
|
{
|
|
if (this->GetNumberOfInputPorts() > 0)
|
|
{
|
|
// must have structured input; MAXIMUM_NUMBER_OF_PIECES will
|
|
// not be copied above (CopyEntry does nothing since key not set
|
|
// in inInfo); set to -1
|
|
outInfo->Set(MAXIMUM_NUMBER_OF_PIECES(), -1);
|
|
}
|
|
else
|
|
{
|
|
// Since most unstructured filters in VTK generate all their
|
|
// data once, set the default maximum number of pieces to 1.
|
|
outInfo->Set(MAXIMUM_NUMBER_OF_PIECES(), 1);
|
|
}
|
|
}
|
|
}
|
|
else if(dataInfo->Get(vtkDataObject::DATA_EXTENT_TYPE()) == VTK_3D_EXTENT)
|
|
{
|
|
if(!outInfo->Has(EXTENT_TRANSLATOR()) ||
|
|
!outInfo->Get(EXTENT_TRANSLATOR()))
|
|
{
|
|
// Create a default extent translator.
|
|
vtkExtentTranslator* translator = vtkExtentTranslator::New();
|
|
outInfo->Set(EXTENT_TRANSLATOR(), translator);
|
|
translator->Delete();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(request->Has(REQUEST_UPDATE_EXTENT()))
|
|
{
|
|
// Get the output port from which to copy the extent.
|
|
int outputPort = -1;
|
|
if(request->Has(FROM_OUTPUT_PORT()))
|
|
{
|
|
outputPort = request->Get(FROM_OUTPUT_PORT());
|
|
}
|
|
|
|
// Setup default information for the inputs.
|
|
if(outInfoVec->GetNumberOfInformationObjects() > 0)
|
|
{
|
|
// Copy information from the output port that made the request.
|
|
// Since VerifyOutputInformation has already been called we know
|
|
// there is output information with a data object.
|
|
vtkInformation* outInfo =
|
|
outInfoVec->GetInformationObject((outputPort >= 0)? outputPort : 0);
|
|
vtkDataObject* outData = outInfo->Get(vtkDataObject::DATA_OBJECT());
|
|
|
|
// Loop over all input ports.
|
|
for(int i=0; i < this->Algorithm->GetNumberOfInputPorts(); ++i)
|
|
{
|
|
// Loop over all connections on this input port.
|
|
int numInConnections = inInfoVec[i]->GetNumberOfInformationObjects();
|
|
for (int j=0; j<numInConnections; j++)
|
|
{
|
|
// Get the pipeline information for this input connection.
|
|
vtkInformation* inInfo = inInfoVec[i]->GetInformationObject(j);
|
|
|
|
// Copy the time request
|
|
if ( outInfo->Has(UPDATE_TIME_INDEX()) )
|
|
{
|
|
inInfo->CopyEntry(outInfo, UPDATE_TIME_INDEX());
|
|
}
|
|
|
|
// If an algorithm wants an exact extent it must explicitly
|
|
// add it to the request. We do not want to get the setting
|
|
// from another consumer of the same input.
|
|
inInfo->Remove(EXACT_EXTENT());
|
|
|
|
// Get the input data object for this connection. It should
|
|
// have already been created by the UpdateDataObject pass.
|
|
vtkDataObject* inData = inInfo->Get(vtkDataObject::DATA_OBJECT());
|
|
if(!inData)
|
|
{
|
|
vtkErrorMacro("Cannot copy default update request from output port "
|
|
<< outputPort << " on algorithm "
|
|
<< this->Algorithm->GetClassName()
|
|
<< "(" << this->Algorithm << ") to input connection "
|
|
<< j << " on input port " << i
|
|
<< " because there is no data object.");
|
|
continue;
|
|
}
|
|
|
|
// Consider all combinations of extent types.
|
|
if(inData->GetExtentType() == VTK_PIECES_EXTENT)
|
|
{
|
|
if(outData->GetExtentType() == VTK_PIECES_EXTENT)
|
|
{
|
|
if (outInfo->Get(UPDATE_PIECE_NUMBER()) < 0)
|
|
{
|
|
return;
|
|
}
|
|
inInfo->CopyEntry(outInfo, UPDATE_PIECE_NUMBER());
|
|
inInfo->CopyEntry(outInfo, UPDATE_NUMBER_OF_PIECES());
|
|
inInfo->CopyEntry(outInfo, UPDATE_NUMBER_OF_GHOST_LEVELS());
|
|
inInfo->CopyEntry(outInfo, UPDATE_EXTENT_INITIALIZED());
|
|
}
|
|
else if(outData->GetExtentType() == VTK_3D_EXTENT)
|
|
{
|
|
// The conversion from structrued requests to
|
|
// unstrcutured requests is always to request the whole
|
|
// extent.
|
|
this->SetUpdateExtentToWholeExtent(inInfo);
|
|
}
|
|
}
|
|
else if(inData->GetExtentType() == VTK_3D_EXTENT)
|
|
{
|
|
if(outData->GetExtentType() == VTK_PIECES_EXTENT)
|
|
{
|
|
int piece = outInfo->Get(UPDATE_PIECE_NUMBER());
|
|
int numPieces = outInfo->Get(UPDATE_NUMBER_OF_PIECES());
|
|
int ghostLevel = outInfo->Get(UPDATE_NUMBER_OF_GHOST_LEVELS());
|
|
if (piece >= 0)
|
|
{
|
|
this->SetUpdateExtent(inInfo, piece, numPieces, ghostLevel);
|
|
}
|
|
}
|
|
else if(outData->GetExtentType() == VTK_3D_EXTENT)
|
|
{
|
|
inInfo->CopyEntry(outInfo, UPDATE_EXTENT());
|
|
inInfo->CopyEntry(outInfo, UPDATE_EXTENT_INITIALIZED());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
vtkStreamingDemandDrivenPipeline
|
|
::ResetPipelineInformation(int port, vtkInformation* info)
|
|
{
|
|
this->Superclass::ResetPipelineInformation(port, info);
|
|
info->Remove(WHOLE_EXTENT());
|
|
info->Remove(MAXIMUM_NUMBER_OF_PIECES());
|
|
info->Remove(EXTENT_TRANSLATOR());
|
|
info->Remove(EXACT_EXTENT());
|
|
info->Remove(UPDATE_EXTENT_INITIALIZED());
|
|
info->Remove(UPDATE_EXTENT());
|
|
info->Remove(UPDATE_PIECE_NUMBER());
|
|
info->Remove(UPDATE_NUMBER_OF_PIECES());
|
|
info->Remove(UPDATE_NUMBER_OF_GHOST_LEVELS());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline::PropagateUpdateExtent(int outputPort)
|
|
{
|
|
// The algorithm should not invoke anything on the executive.
|
|
if(!this->CheckAlgorithm("PropagateUpdateExtent", 0))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Range check.
|
|
if(outputPort < -1 ||
|
|
outputPort >= this->Algorithm->GetNumberOfOutputPorts())
|
|
{
|
|
vtkErrorMacro("PropagateUpdateExtent given output port index "
|
|
<< outputPort << " on an algorithm with "
|
|
<< this->Algorithm->GetNumberOfOutputPorts()
|
|
<< " output ports.");
|
|
return 0;
|
|
}
|
|
|
|
// Setup the request for update extent propagation.
|
|
if (!this->UpdateExtentRequest)
|
|
{
|
|
this->UpdateExtentRequest = vtkInformation::New();
|
|
this->UpdateExtentRequest->Set(REQUEST_UPDATE_EXTENT());
|
|
// The request is forwarded upstream through the pipeline.
|
|
this->UpdateExtentRequest->Set(vtkExecutive::FORWARD_DIRECTION(), vtkExecutive::RequestUpstream);
|
|
// Algorithms process this request before it is forwarded.
|
|
this->UpdateExtentRequest->Set(vtkExecutive::ALGORITHM_BEFORE_FORWARD(), 1);
|
|
}
|
|
|
|
this->UpdateExtentRequest->Set(FROM_OUTPUT_PORT(), outputPort);
|
|
|
|
// Send the request.
|
|
return this->ProcessRequest(this->UpdateExtentRequest,
|
|
this->GetInputInformation(),
|
|
this->GetOutputInformation());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::VerifyOutputInformation(int outputPort,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec)
|
|
{
|
|
// If no port is specified, check all ports.
|
|
if(outputPort < 0)
|
|
{
|
|
for(int i=0; i < this->Algorithm->GetNumberOfOutputPorts(); ++i)
|
|
{
|
|
if(!this->VerifyOutputInformation(i,inInfoVec,outInfoVec))
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Get the information object to check.
|
|
vtkInformation* outInfo = outInfoVec->GetInformationObject(outputPort);
|
|
|
|
// Make sure there is a data object. It is supposed to be created
|
|
// by the UpdateDataObject step.
|
|
vtkDataObject* dataObject = outInfo->Get(vtkDataObject::DATA_OBJECT());
|
|
if(!dataObject)
|
|
{
|
|
vtkErrorMacro("No data object has been set in the information for "
|
|
"output port " << outputPort << ".");
|
|
return 0;
|
|
}
|
|
|
|
// Check extents.
|
|
vtkInformation* dataInfo = dataObject->GetInformation();
|
|
if(dataInfo->Get(vtkDataObject::DATA_EXTENT_TYPE()) == VTK_PIECES_EXTENT)
|
|
{
|
|
// For an unstructured extent, make sure the update request
|
|
// exists. We do not need to check if it is valid because
|
|
// out-of-range requests produce empty data.
|
|
if(!outInfo->Has(MAXIMUM_NUMBER_OF_PIECES()))
|
|
{
|
|
vtkErrorMacro("No maximum number of pieces has been set in the "
|
|
"information for output port " << outputPort
|
|
<< " on algorithm " << this->Algorithm->GetClassName()
|
|
<< "(" << this->Algorithm << ").");
|
|
return 0;
|
|
}
|
|
if(!outInfo->Has(UPDATE_PIECE_NUMBER()))
|
|
{
|
|
vtkErrorMacro("No update piece number has been set in the "
|
|
"information for output port " << outputPort
|
|
<< " on algorithm " << this->Algorithm->GetClassName()
|
|
<< "(" << this->Algorithm << ").");
|
|
return 0;
|
|
}
|
|
if(!outInfo->Has(UPDATE_NUMBER_OF_PIECES()))
|
|
{
|
|
vtkErrorMacro("No update number of pieces has been set in the "
|
|
"information for output port " << outputPort
|
|
<< " on algorithm " << this->Algorithm->GetClassName()
|
|
<< "(" << this->Algorithm << ").");
|
|
return 0;
|
|
}
|
|
if(!outInfo->Has(UPDATE_NUMBER_OF_GHOST_LEVELS()))
|
|
{
|
|
// Use zero ghost levels by default.
|
|
outInfo->Set(UPDATE_NUMBER_OF_GHOST_LEVELS(), 0);
|
|
}
|
|
}
|
|
else if(dataInfo->Get(vtkDataObject::DATA_EXTENT_TYPE()) == VTK_3D_EXTENT)
|
|
{
|
|
// For a structured extent, make sure the update request
|
|
// exists.
|
|
if(!outInfo->Has(WHOLE_EXTENT()))
|
|
{
|
|
vtkErrorMacro("No whole extent has been set in the "
|
|
"information for output port " << outputPort
|
|
<< " on algorithm " << this->Algorithm->GetClassName()
|
|
<< "(" << this->Algorithm << ").");
|
|
return 0;
|
|
}
|
|
if(!outInfo->Has(UPDATE_EXTENT()))
|
|
{
|
|
vtkErrorMacro("No update extent has been set in the "
|
|
"information for output port " << outputPort
|
|
<< " on algorithm " << this->Algorithm->GetClassName()
|
|
<< "(" << this->Algorithm << ").");
|
|
return 0;
|
|
}
|
|
// Make sure the update request is inside the whole extent.
|
|
int wholeExtent[6];
|
|
int updateExtent[6];
|
|
outInfo->Get(WHOLE_EXTENT(), wholeExtent);
|
|
outInfo->Get(UPDATE_EXTENT(), updateExtent);
|
|
if((updateExtent[0] < wholeExtent[0] ||
|
|
updateExtent[1] > wholeExtent[1] ||
|
|
updateExtent[2] < wholeExtent[2] ||
|
|
updateExtent[3] > wholeExtent[3] ||
|
|
updateExtent[4] < wholeExtent[4] ||
|
|
updateExtent[5] > wholeExtent[5]) &&
|
|
(updateExtent[0] <= updateExtent[1] &&
|
|
updateExtent[2] <= updateExtent[3] &&
|
|
updateExtent[4] <= updateExtent[5]))
|
|
{
|
|
// Update extent is outside the whole extent and is not empty.
|
|
vtkErrorMacro("The update extent specified in the "
|
|
"information for output port " << outputPort
|
|
<< " on algorithm " << this->Algorithm->GetClassName()
|
|
<< "(" << this->Algorithm << ") is "
|
|
<< updateExtent[0] << " " << updateExtent[1] << " "
|
|
<< updateExtent[2] << " " << updateExtent[3] << " "
|
|
<< updateExtent[4] << " " << updateExtent[5]
|
|
<< ", which is outside the whole extent "
|
|
<< wholeExtent[0] << " " << wholeExtent[1] << " "
|
|
<< wholeExtent[2] << " " << wholeExtent[3] << " "
|
|
<< wholeExtent[4] << " " << wholeExtent[5] << ".");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
vtkStreamingDemandDrivenPipeline
|
|
::ExecuteDataStart(vtkInformation* request,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec)
|
|
{
|
|
// Preserve the execution continuation flag in the request across
|
|
// iterations of the algorithm. Perform start operations only if
|
|
// not in an execute continuation.
|
|
if(this->ContinueExecuting)
|
|
{
|
|
request->Set(CONTINUE_EXECUTING(), 1);
|
|
}
|
|
else
|
|
{
|
|
request->Remove(CONTINUE_EXECUTING());
|
|
this->Superclass::ExecuteDataStart(request,inInfoVec,outInfoVec);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
vtkStreamingDemandDrivenPipeline
|
|
::ExecuteDataEnd(vtkInformation* request,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec)
|
|
{
|
|
// Preserve the execution continuation flag in the request across
|
|
// iterations of the algorithm. Perform start operations only if
|
|
// not in an execute continuation.
|
|
if(request->Get(CONTINUE_EXECUTING()))
|
|
{
|
|
this->ContinueExecuting = 1;
|
|
}
|
|
else
|
|
{
|
|
this->ContinueExecuting = 0;
|
|
this->Superclass::ExecuteDataEnd(request,inInfoVec,outInfoVec);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
vtkStreamingDemandDrivenPipeline
|
|
::MarkOutputsGenerated(vtkInformation* request,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec)
|
|
{
|
|
// Tell outputs they have been generated.
|
|
this->Superclass::MarkOutputsGenerated(request,inInfoVec,outInfoVec);
|
|
|
|
// Compute ghost level arrays for generated outputs.
|
|
for(int i=0; i < outInfoVec->GetNumberOfInformationObjects(); ++i)
|
|
{
|
|
vtkInformation* outInfo = outInfoVec->GetInformationObject(i);
|
|
vtkDataObject* data = outInfo->Get(vtkDataObject::DATA_OBJECT());
|
|
if(data && !outInfo->Get(DATA_NOT_GENERATED()))
|
|
{
|
|
if(vtkDataSet* ds = vtkDataSet::SafeDownCast(data))
|
|
{
|
|
ds->GenerateGhostLevelArray();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::NeedToExecuteData(int outputPort,
|
|
vtkInformationVector** inInfoVec,
|
|
vtkInformationVector* outInfoVec)
|
|
{
|
|
// Has the algorithm asked to be executed again?
|
|
if(this->ContinueExecuting)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
// If no port is specified, check all ports. This behavior is
|
|
// implemented by the superclass.
|
|
if(outputPort < 0)
|
|
{
|
|
return this->Superclass::NeedToExecuteData(outputPort,
|
|
inInfoVec,outInfoVec);
|
|
}
|
|
|
|
// Does the superclass want to execute?
|
|
if(this->Superclass::NeedToExecuteData(outputPort,inInfoVec,outInfoVec))
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
// We need to check the requested update extent. Get the output
|
|
// port information and data information. We do not need to check
|
|
// existence of values because it has already been verified by
|
|
// VerifyOutputInformation.
|
|
vtkInformation* outInfo = outInfoVec->GetInformationObject(outputPort);
|
|
vtkDataObject* dataObject = outInfo->Get(vtkDataObject::DATA_OBJECT());
|
|
vtkInformation* dataInfo = dataObject->GetInformation();
|
|
if(dataInfo->Get(vtkDataObject::DATA_EXTENT_TYPE()) == VTK_PIECES_EXTENT)
|
|
{
|
|
// Check the unstructured extent. If we do not have the requested
|
|
// piece, we need to execute.
|
|
int updateNumberOfPieces = outInfo->Get(UPDATE_NUMBER_OF_PIECES());
|
|
int dataNumberOfPieces = dataInfo->Get(vtkDataObject::DATA_NUMBER_OF_PIECES());
|
|
if(dataNumberOfPieces != updateNumberOfPieces)
|
|
{
|
|
return 1;
|
|
}
|
|
int dataGhostLevel = dataInfo->Get(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS());
|
|
int updateGhostLevel = outInfo->Get(UPDATE_NUMBER_OF_GHOST_LEVELS());
|
|
if(dataGhostLevel != updateGhostLevel)
|
|
{
|
|
return 1;
|
|
}
|
|
if (dataNumberOfPieces != 1)
|
|
{
|
|
int dataPiece = dataInfo->Get(vtkDataObject::DATA_PIECE_NUMBER());
|
|
int updatePiece = outInfo->Get(UPDATE_PIECE_NUMBER());
|
|
if (dataPiece != updatePiece)
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
else if(dataInfo->Get(vtkDataObject::DATA_EXTENT_TYPE()) == VTK_3D_EXTENT)
|
|
{
|
|
// Check the structured extent. If the update extent is outside
|
|
// of the extent and not empty, we need to execute.
|
|
int dataExtent[6];
|
|
int updateExtent[6];
|
|
outInfo->Get(UPDATE_EXTENT(), updateExtent);
|
|
dataInfo->Get(vtkDataObject::DATA_EXTENT(), dataExtent);
|
|
// if the ue is out side the de
|
|
if((updateExtent[0] < dataExtent[0] ||
|
|
updateExtent[1] > dataExtent[1] ||
|
|
updateExtent[2] < dataExtent[2] ||
|
|
updateExtent[3] > dataExtent[3] ||
|
|
updateExtent[4] < dataExtent[4] ||
|
|
updateExtent[5] > dataExtent[5]) &&
|
|
// and the ue is set
|
|
(updateExtent[0] <= updateExtent[1] &&
|
|
updateExtent[2] <= updateExtent[3] &&
|
|
updateExtent[4] <= updateExtent[5]))
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// if we are requesting a particular update time index, check
|
|
// if we have the desired time index
|
|
if ( outInfo->Has(UPDATE_TIME_INDEX()) )
|
|
{
|
|
if (!dataInfo->Has(vtkDataObject::DATA_TIME_INDEX()) ||
|
|
dataInfo->Get(vtkDataObject::DATA_TIME_INDEX()) !=
|
|
outInfo->Get(UPDATE_TIME_INDEX()))
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// We do not need to execute.
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::SetMaximumNumberOfPieces(vtkInformation *info, int n)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("SetMaximumNumberOfPieces on invalid output");
|
|
return 0;
|
|
}
|
|
if(this->GetMaximumNumberOfPieces(info) != n)
|
|
{
|
|
info->Set(MAXIMUM_NUMBER_OF_PIECES(), n);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::GetMaximumNumberOfPieces(vtkInformation *info)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("GetMaximumNumberOfPieces on invalid output");
|
|
return 0;
|
|
}
|
|
if(!info->Has(MAXIMUM_NUMBER_OF_PIECES()))
|
|
{
|
|
info->Set(MAXIMUM_NUMBER_OF_PIECES(), -1);
|
|
}
|
|
return info->Get(MAXIMUM_NUMBER_OF_PIECES());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::SetWholeExtent(vtkInformation *info, int extent[6])
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("SetWholeExtent on invalid output");
|
|
return 0;
|
|
}
|
|
int modified = 0;
|
|
int oldExtent[6];
|
|
this->GetWholeExtent(info, oldExtent);
|
|
if(oldExtent[0] != extent[0] || oldExtent[1] != extent[1] ||
|
|
oldExtent[2] != extent[2] || oldExtent[3] != extent[3] ||
|
|
oldExtent[4] != extent[4] || oldExtent[5] != extent[5])
|
|
{
|
|
modified = 1;
|
|
info->Set(WHOLE_EXTENT(), extent, 6);
|
|
}
|
|
return modified;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkStreamingDemandDrivenPipeline
|
|
::GetWholeExtent(vtkInformation *info, int extent[6])
|
|
{
|
|
static int emptyExtent[6] = {0,-1,0,-1,0,-1};
|
|
if(!info)
|
|
{
|
|
memcpy(extent, emptyExtent, sizeof(int)*6);
|
|
return;
|
|
}
|
|
if(!info->Has(WHOLE_EXTENT()))
|
|
{
|
|
info->Set(WHOLE_EXTENT(), emptyExtent, 6);
|
|
}
|
|
info->Get(WHOLE_EXTENT(), extent);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int* vtkStreamingDemandDrivenPipeline::GetWholeExtent(vtkInformation* info)
|
|
{
|
|
static int emptyExtent[6] = {0,-1,0,-1,0,-1};
|
|
if(!info)
|
|
{
|
|
return emptyExtent;
|
|
}
|
|
if(!info->Has(WHOLE_EXTENT()))
|
|
{
|
|
info->Set(WHOLE_EXTENT(), emptyExtent, 6);
|
|
}
|
|
return info->Get(WHOLE_EXTENT());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::SetUpdateExtentToWholeExtent(vtkInformation *info)
|
|
{
|
|
// Request all data.
|
|
int modified = 0;
|
|
if(vtkDataObject* data = info->Get(vtkDataObject::DATA_OBJECT()))
|
|
{
|
|
if(data->GetExtentType() == VTK_PIECES_EXTENT)
|
|
{
|
|
modified |= this->SetUpdatePiece(info, 0);
|
|
modified |= this->SetUpdateNumberOfPieces(info, 1);
|
|
modified |= this->SetUpdateGhostLevel(info, 0);
|
|
}
|
|
else if(data->GetExtentType() == VTK_3D_EXTENT)
|
|
{
|
|
int extent[6] = {0,-1,0,-1,0,-1};
|
|
info->Get(WHOLE_EXTENT(), extent);
|
|
modified |= this->SetUpdateExtent(info, extent);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vtkErrorMacro("SetUpdateExtentToWholeExtent called with no data object.");
|
|
}
|
|
|
|
// Make sure the update extent will remain the whole extent until
|
|
// the update extent is explicitly set by the caller.
|
|
info->Set(UPDATE_EXTENT_INITIALIZED(), 0);
|
|
|
|
return modified;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::SetUpdateExtent(vtkInformation *info, int extent[6])
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("SetUpdateExtent on invalid output");
|
|
return 0;
|
|
}
|
|
int modified = 0;
|
|
int oldExtent[6];
|
|
this->GetUpdateExtent(info, oldExtent);
|
|
if(oldExtent[0] != extent[0] || oldExtent[1] != extent[1] ||
|
|
oldExtent[2] != extent[2] || oldExtent[3] != extent[3] ||
|
|
oldExtent[4] != extent[4] || oldExtent[5] != extent[5])
|
|
{
|
|
modified = 1;
|
|
info->Set(UPDATE_EXTENT(), extent, 6);
|
|
}
|
|
info->Set(UPDATE_EXTENT_INITIALIZED(), 1);
|
|
return modified;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::SetUpdateExtent(vtkInformation *info, int piece,
|
|
int numPieces,
|
|
int ghostLevel)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("SetUpdateExtent on invalid output");
|
|
return 0;
|
|
}
|
|
int modified = 0;
|
|
modified |= this->SetUpdatePiece(info, piece);
|
|
modified |= this->SetUpdateNumberOfPieces(info, numPieces);
|
|
modified |= this->SetUpdateGhostLevel(info, ghostLevel);
|
|
if(vtkDataObject* data = info->Get(vtkDataObject::DATA_OBJECT()))
|
|
{
|
|
if(data->GetExtentType() == VTK_3D_EXTENT)
|
|
{
|
|
if(vtkExtentTranslator* translator = this->GetExtentTranslator(info))
|
|
{
|
|
int wholeExtent[6];
|
|
this->GetWholeExtent(info, wholeExtent);
|
|
translator->SetWholeExtent(wholeExtent);
|
|
translator->SetPiece(piece);
|
|
translator->SetNumberOfPieces(numPieces);
|
|
translator->SetGhostLevel(ghostLevel);
|
|
translator->PieceToExtent();
|
|
modified |= this->SetUpdateExtent(info, translator->GetExtent());
|
|
}
|
|
else
|
|
{
|
|
vtkErrorMacro("Cannot translate unstructured extent to structured "
|
|
"for algorithm "
|
|
<< this->Algorithm->GetClassName() << "("
|
|
<< this->Algorithm << ").");
|
|
}
|
|
}
|
|
}
|
|
return modified;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkStreamingDemandDrivenPipeline
|
|
::GetUpdateExtent(vtkInformation *info, int extent[6])
|
|
{
|
|
static int emptyExtent[6] = {0,-1,0,-1,0,-1};
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("GetUpdateExtent on invalid output");
|
|
memcpy(extent, emptyExtent, sizeof(int)*6);
|
|
return;
|
|
}
|
|
if(!info->Has(UPDATE_EXTENT()))
|
|
{
|
|
info->Set(UPDATE_EXTENT(), emptyExtent, 6);
|
|
info->Set(UPDATE_EXTENT_INITIALIZED(), 0);
|
|
}
|
|
info->Get(UPDATE_EXTENT(), extent);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int* vtkStreamingDemandDrivenPipeline
|
|
::GetUpdateExtent(vtkInformation *info)
|
|
{
|
|
static int emptyExtent[6] = {0,-1,0,-1,0,-1};
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("GetUpdateExtent on invalid output");
|
|
return emptyExtent;
|
|
}
|
|
if(!info->Has(UPDATE_EXTENT()))
|
|
{
|
|
info->Set(UPDATE_EXTENT(), emptyExtent, 6);
|
|
info->Set(UPDATE_EXTENT_INITIALIZED(), 0);
|
|
}
|
|
return info->Get(UPDATE_EXTENT());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::SetUpdatePiece(vtkInformation *info, int piece)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("SetUpdatePiece on invalid output");
|
|
return 0;
|
|
}
|
|
int modified = 0;
|
|
if(this->GetUpdatePiece(info) != piece)
|
|
{
|
|
info->Set(UPDATE_PIECE_NUMBER(), piece);
|
|
modified = 1;
|
|
}
|
|
info->Set(UPDATE_EXTENT_INITIALIZED(), 1);
|
|
return modified;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::GetUpdatePiece(vtkInformation *info)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("GetUpdatePiece on invalid output");
|
|
return 0;
|
|
}
|
|
if(!info->Has(UPDATE_PIECE_NUMBER()))
|
|
{
|
|
info->Set(UPDATE_PIECE_NUMBER(), 0);
|
|
}
|
|
return info->Get(UPDATE_PIECE_NUMBER());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::SetUpdateNumberOfPieces(vtkInformation *info, int n)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("SetUpdateNumberOfPieces on invalid output");
|
|
return 0;
|
|
}
|
|
int modified = 0;
|
|
if(this->GetUpdateNumberOfPieces(info) != n)
|
|
{
|
|
info->Set(UPDATE_NUMBER_OF_PIECES(), n);
|
|
modified = 1;
|
|
}
|
|
info->Set(UPDATE_EXTENT_INITIALIZED(), 1);
|
|
return modified;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::GetUpdateNumberOfPieces(vtkInformation *info)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("GetUpdateNumberOfPieces on invalid output");
|
|
return 1;
|
|
}
|
|
if(!info->Has(UPDATE_NUMBER_OF_PIECES()))
|
|
{
|
|
info->Set(UPDATE_NUMBER_OF_PIECES(), 1);
|
|
}
|
|
return info->Get(UPDATE_NUMBER_OF_PIECES());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::SetUpdateGhostLevel(vtkInformation *info, int n)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("SetUpdateGhostLevel on invalid output");
|
|
return 0;
|
|
}
|
|
if(this->GetUpdateGhostLevel(info) != n)
|
|
{
|
|
info->Set(UPDATE_NUMBER_OF_GHOST_LEVELS(), n);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline
|
|
::GetUpdateGhostLevel(vtkInformation *info)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("GetUpdateGhostLevel on invalid output");
|
|
return 0;
|
|
}
|
|
if(!info->Has(UPDATE_NUMBER_OF_GHOST_LEVELS()))
|
|
{
|
|
info->Set(UPDATE_NUMBER_OF_GHOST_LEVELS(), 0);
|
|
}
|
|
return info->Get(UPDATE_NUMBER_OF_GHOST_LEVELS());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline::SetRequestExactExtent(int port, int flag)
|
|
{
|
|
if(!this->OutputPortIndexInRange(port, "set request exact extent flag on"))
|
|
{
|
|
return 0;
|
|
}
|
|
vtkInformation* info = this->GetOutputInformation(port);
|
|
if(this->GetRequestExactExtent(port) != flag)
|
|
{
|
|
info->Set(EXACT_EXTENT(), flag);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline::GetRequestExactExtent(int port)
|
|
{
|
|
if(!this->OutputPortIndexInRange(port, "get request exact extent flag from"))
|
|
{
|
|
return 0;
|
|
}
|
|
vtkInformation* info = this->GetOutputInformation(port);
|
|
if(!info->Has(EXACT_EXTENT()))
|
|
{
|
|
info->Set(EXACT_EXTENT(), 0);
|
|
}
|
|
return info->Get(EXACT_EXTENT());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
vtkStreamingDemandDrivenPipeline
|
|
::SetExtentTranslator(vtkInformation *info, vtkExtentTranslator* translator)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("Attempt to set translator for invalid output");
|
|
return 0;
|
|
}
|
|
vtkExtentTranslator* oldTranslator =
|
|
vtkExtentTranslator::SafeDownCast(info->Get(EXTENT_TRANSLATOR()));
|
|
if(translator != oldTranslator)
|
|
{
|
|
info->Set(EXTENT_TRANSLATOR(), translator);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkExtentTranslator*
|
|
vtkStreamingDemandDrivenPipeline::GetExtentTranslator(vtkInformation *info)
|
|
{
|
|
if(!info)
|
|
{
|
|
vtkErrorMacro("Attempt to get translator for invalid output");
|
|
return 0;
|
|
}
|
|
vtkExtentTranslator* translator =
|
|
vtkExtentTranslator::SafeDownCast(info->Get(EXTENT_TRANSLATOR()));
|
|
if(!translator)
|
|
{
|
|
translator = vtkExtentTranslator::New();
|
|
info->Set(EXTENT_TRANSLATOR(), translator);
|
|
translator->Delete();
|
|
}
|
|
return translator;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkStreamingDemandDrivenPipeline::SetWholeBoundingBox(int port,
|
|
double extent[6])
|
|
{
|
|
if(!this->OutputPortIndexInRange(port, "set whole bounding box on"))
|
|
{
|
|
return 0;
|
|
}
|
|
vtkInformation* info = this->GetOutputInformation(port);
|
|
int modified = 0;
|
|
double oldBoundingBox[6];
|
|
this->GetWholeBoundingBox(port, oldBoundingBox);
|
|
if(oldBoundingBox[0] != extent[0] || oldBoundingBox[1] != extent[1] ||
|
|
oldBoundingBox[2] != extent[2] || oldBoundingBox[3] != extent[3] ||
|
|
oldBoundingBox[4] != extent[4] || oldBoundingBox[5] != extent[5])
|
|
{
|
|
modified = 1;
|
|
info->Set(WHOLE_BOUNDING_BOX(), extent, 6);
|
|
}
|
|
return modified;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkStreamingDemandDrivenPipeline::GetWholeBoundingBox(int port, double extent[6])
|
|
{
|
|
static double emptyBoundingBox[6] = {0,-1,0,-1,0,-1};
|
|
if(!this->OutputPortIndexInRange(port, "get whole bounding box from"))
|
|
{
|
|
memcpy(extent, emptyBoundingBox, sizeof(double)*6);
|
|
return;
|
|
}
|
|
vtkInformation* info = this->GetOutputInformation(port);
|
|
if(!info->Has(WHOLE_BOUNDING_BOX()))
|
|
{
|
|
info->Set(WHOLE_BOUNDING_BOX(), emptyBoundingBox, 6);
|
|
}
|
|
info->Get(WHOLE_BOUNDING_BOX(), extent);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double* vtkStreamingDemandDrivenPipeline::GetWholeBoundingBox(int port)
|
|
{
|
|
static double emptyBoundingBox[6] = {0,-1,0,-1,0,-1};
|
|
if(!this->OutputPortIndexInRange(port, "get whole bounding box from"))
|
|
{
|
|
return emptyBoundingBox;
|
|
}
|
|
vtkInformation* info = this->GetOutputInformation(port);
|
|
if(!info->Has(WHOLE_BOUNDING_BOX()))
|
|
{
|
|
info->Set(WHOLE_BOUNDING_BOX(), emptyBoundingBox, 6);
|
|
}
|
|
return info->Get(WHOLE_BOUNDING_BOX());
|
|
}
|
|
|