Commit 1a0b4e9d authored by Berk Geveci's avatar Berk Geveci Committed by George Zagaris
Browse files

Refactored how pieces and extents are handled.

Refactoring the way VTK goes between piece and structured
extents. Before, extent translators were used when the pipeline
moved from structured to unstructured data converting piece
request to extent request. This caused many problems with filters
that altered extents, mainly a lot of redundant IO due to
repartitioning of different extents. This became extremely
cumbersome to manage when running distributed. The new behavior
pushes the extent translation all to way to the readers and
only when readers are able to read a subset. This works much
better. The only downside is that filters need to be able to
handle data extents different than update extents. Most filters
can do this but many imaging filters cannot. Those that are
needed in parallel will have to be updated.

As part of this work, I also removed MAXIMUM_NUMBER_OF_PIECES
and added CAN_HANDLE_PIECE_REQUEST. MAXIMUM_NUMBER_OF_PIECES had
reduced to being a boolean. 1 for serial sources, -1 for parallel
...
parent 0b20e771
......@@ -56,6 +56,7 @@ vtkInformationKeyMacro(vtkDataObject, FIELD_NUMBER_OF_TUPLES, Integer);
vtkInformationKeyRestrictedMacro(vtkDataObject, FIELD_RANGE, DoubleVector, 2);
vtkInformationKeyRestrictedMacro(vtkDataObject, PIECE_EXTENT, IntegerVector, 6);
vtkInformationKeyMacro(vtkDataObject, FIELD_OPERATION, Integer);
vtkInformationKeyRestrictedMacro(vtkDataObject, ALL_PIECES_EXTENT, IntegerVector, 6);
vtkInformationKeyRestrictedMacro(vtkDataObject, DATA_EXTENT, IntegerPointer, 6);
vtkInformationKeyRestrictedMacro(vtkDataObject, ORIGIN, DoubleVector, 3);
vtkInformationKeyRestrictedMacro(vtkDataObject, SPACING, DoubleVector, 3);
......@@ -162,6 +163,7 @@ void vtkDataObject::Initialize()
if (this->Information)
{
// Make sure the information is cleared.
this->Information->Remove(ALL_PIECES_EXTENT());
this->Information->Remove(DATA_PIECE_NUMBER());
this->Information->Remove(DATA_NUMBER_OF_PIECES());
this->Information->Remove(DATA_NUMBER_OF_GHOST_LEVELS());
......
......@@ -298,6 +298,7 @@ public:
static vtkInformationDataObjectKey* DATA_OBJECT();
static vtkInformationIntegerKey* DATA_EXTENT_TYPE();
static vtkInformationIntegerPointerKey* DATA_EXTENT();
static vtkInformationIntegerVectorKey* ALL_PIECES_EXTENT();
static vtkInformationIntegerKey* DATA_PIECE_NUMBER();
static vtkInformationIntegerKey* DATA_NUMBER_OF_PIECES();
static vtkInformationIntegerKey* DATA_NUMBER_OF_GHOST_LEVELS();
......
......@@ -461,11 +461,7 @@ int vtkDataSet::CheckAttributes()
}
//----------------------------------------------------------------------------
void vtkDataSet::GenerateGhostLevelArray(int update_piece,
int update_num_pieces,
int vtkNotUsed(update_ghost_level),
int* whole_extent,
vtkExtentTranslator* translator)
void vtkDataSet::GenerateGhostLevelArray(int zeroExt[6])
{
// Make sure this is a structured data set.
if(this->GetExtentType() != VTK_3D_EXTENT)
......@@ -477,10 +473,12 @@ void vtkDataSet::GenerateGhostLevelArray(int update_piece,
if(!this->PointData->GetArray("vtkGhostLevels"))
{ // Create ghost levels for cells and points.
vtkUnsignedCharArray *levels;
int zeroExt[6], extent[6];
int extent[6];
int i, j, k, di, dj, dk, dist;
this->Information->Get(vtkDataObject::DATA_EXTENT(), extent);
/*
// Get the extent with ghost level 0.
translator->SetWholeExtent(whole_extent);
translator->SetPiece(update_piece);
......@@ -488,6 +486,7 @@ void vtkDataSet::GenerateGhostLevelArray(int update_piece,
translator->SetGhostLevel(0);
translator->PieceToExtent();
translator->GetExtent(zeroExt);
*/
// ---- POINTS ----
// Allocate the appropriate number levels (number of points).
......@@ -504,7 +503,7 @@ void vtkDataSet::GenerateGhostLevelArray(int update_piece,
{
dk = zeroExt[4] - k;
}
if (k >= zeroExt[5] && k < whole_extent[5])
if (k >= zeroExt[5])
{ // Special case for last tile.
dk = k - zeroExt[5] + 1;
}
......@@ -515,7 +514,7 @@ void vtkDataSet::GenerateGhostLevelArray(int update_piece,
{
dj = zeroExt[2] - j;
}
if (j >= zeroExt[3] && j < whole_extent[3])
if (j >= zeroExt[3])
{ // Special case for last tile.
dj = j - zeroExt[3] + 1;
}
......@@ -526,7 +525,7 @@ void vtkDataSet::GenerateGhostLevelArray(int update_piece,
{
di = zeroExt[0] - i;
}
if (i >= zeroExt[1] && i < whole_extent[1])
if (i >= zeroExt[1])
{ // Special case for last tile.
di = i - zeroExt[1] + 1;
}
......
......@@ -332,12 +332,9 @@ public:
// Description:
// Normally called by pipeline executives or algoritgms only. This method
// computes the ghost arrays for a given dataset.
virtual void GenerateGhostLevelArray(int update_piece,
int update_num_pieces,
int update_ghost_level,
int* whole_extent,
vtkExtentTranslator* translator);
// computes the ghost arrays for a given dataset. The zeroExt argument
// specifies the extent of the region which ghost level = 0.
virtual void GenerateGhostLevelArray(int zeroExt[6]);
//BTX
// Description:
......
......@@ -76,9 +76,9 @@ public:
{this->SplitMode = vtkExtentTranslator::BLOCK_MODE;}
void SetSplitModeToXSlab()
{this->SplitMode = vtkExtentTranslator::X_SLAB_MODE;}
void SetSplitModeToYSlab()
void SetSplitModeToYSlab()
{this->SplitMode = vtkExtentTranslator::Y_SLAB_MODE;}
void SetSplitModeToZSlab()
void SetSplitModeToZSlab()
{this->SplitMode = vtkExtentTranslator::Z_SLAB_MODE;}
vtkGetMacro(SplitMode,int);
......@@ -90,16 +90,15 @@ public:
// use this to tell the translator which dimensions to split.
void SetSplitPath(int len, int *splitpath);
//BTX
// Don't change the numbers here - they are used in the code
// to indicate array indices.
enum Modes {
enum Modes
{
X_SLAB_MODE=0,
Y_SLAB_MODE=1,
Z_SLAB_MODE=2,
BLOCK_MODE= 3
};
//ETX
protected:
vtkExtentTranslator();
......
......@@ -57,6 +57,7 @@ vtkInformationKeyMacro(vtkAlgorithm, PORT_REQUIREMENTS_FILLED, Integer);
vtkInformationKeyMacro(vtkAlgorithm, INPUT_PORT, Integer);
vtkInformationKeyMacro(vtkAlgorithm, INPUT_CONNECTION, Integer);
vtkInformationKeyMacro(vtkAlgorithm, INPUT_ARRAYS_TO_PROCESS, InformationVector);
vtkInformationKeyMacro(vtkAlgorithm, CAN_PRODUCE_SUB_EXTENT, Integer);
vtkExecutive* vtkAlgorithm::DefaultExecutivePrototype = 0;
......
......@@ -218,6 +218,13 @@ public:
static vtkInformationIntegerKey* INPUT_PORT();
static vtkInformationIntegerKey* INPUT_CONNECTION();
// Description:
// This key tells the executive that a particular output port
// is capable of producing an arbitrary subextent of the whole
// extent. Many image sources and readers fall into this category
// but some such as the legacy structured data readers cannot
// support this feature.
static vtkInformationIntegerKey* CAN_PRODUCE_SUB_EXTENT();
// Description:
// Set the input data arrays that this algorithm will
......
......@@ -60,10 +60,7 @@ int vtkCastToConcrete::RequestInformation(
outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()),
6);
outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
inInfo->Get(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES()));
outInfo->Set(vtkStreamingDemandDrivenPipeline::EXTENT_TRANSLATOR(),
inInfo->Get(vtkStreamingDemandDrivenPipeline::EXTENT_TRANSLATOR()));
return 1;
}
......
......@@ -35,6 +35,7 @@ PURPOSE. See the above copyright notice for more information.
#include "vtkRectilinearGrid.h"
#include "vtkSmartPointer.h"
#include "vtkStructuredGrid.h"
#include "vtkTrivialProducer.h"
#include "vtkUniformGrid.h"
vtkStandardNewMacro(vtkCompositeDataPipeline);
......@@ -373,7 +374,7 @@ void vtkCompositeDataPipeline::ExecuteSimpleAlgorithm(
r->Set(vtkExecutive::ALGORITHM_AFTER_FORWARD(), 1);
// Store the information (whole_extent and maximum_number_of_pieces)
// Store the information (whole_extent)
// before looping. Otherwise, executeinformation will cause
// changes (because we pretend that the max. number of pieces is
// one to process the whole block)
......@@ -395,9 +396,7 @@ void vtkCompositeDataPipeline::ExecuteSimpleAlgorithm(
// ExecuteDataStart() should NOT Initialize() the composite output.
this->InLocalLoop = 0;
// Restore the extent information and force it to be
// copied to the output. Composite sources should set
// MAXIMUM_NUMBER_OF_PIECES to -1 anyway (and handle
// piece requests properly).
// copied to the output.
this->PopInformation(inInfo);
r->Set(REQUEST_INFORMATION());
this->CopyDefaultInformation(r, vtkExecutive::RequestDownstream,
......@@ -445,8 +444,7 @@ vtkDataObject* vtkCompositeDataPipeline::ExecuteSimpleAlgorithmForBlock(
inInfo->Remove(vtkDataObject::DATA_OBJECT());
inInfo->Set(vtkDataObject::DATA_OBJECT(), dobj);
// Process the whole dataset
this->CopyFromDataToInformation(dobj, inInfo);
vtkTrivialProducer::FillOutputDataInformation(dobj, inInfo);
}
request->Set(REQUEST_DATA_OBJECT());
......@@ -457,13 +455,6 @@ vtkDataObject* vtkCompositeDataPipeline::ExecuteSimpleAlgorithmForBlock(
request->Set(REQUEST_INFORMATION());
// Berk TODO: Replace with a trivial producer
// // Make sure that pipeline informations is in sync with the data
// if (dobj)
// {
// dobj->CopyInformationToPipeline(request, 0, inInfo, 1);
// }
this->Superclass::ExecuteInformation(request, inInfoVec, outInfoVec);
request->Remove(REQUEST_INFORMATION());
......@@ -555,24 +546,30 @@ int vtkCompositeDataPipeline::NeedToExecuteData(
inInfoVec,outInfoVec);
}
// Does the superclass want to execute?
if(this->vtkDemandDrivenPipeline::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());
// If the output is not a composite dataset, let the superclass handle
// NeedToExecuteData
if (!vtkCompositeDataSet::SafeDownCast(dataObject))
{
return this->Superclass::NeedToExecuteData(outputPort,
inInfoVec,outInfoVec);
}
// First do the basic checks.
if(this->vtkDemandDrivenPipeline::NeedToExecuteData(
outputPort,inInfoVec,outInfoVec))
{
return 1;
}
// Now handle composite stuff.
vtkInformation* dataInfo = dataObject->GetInformation();
// Check the unstructured extent. If we do not have the requested
......@@ -874,42 +871,11 @@ void vtkCompositeDataPipeline::ResetPipelineInformation(int port,
info->Remove(LOAD_REQUESTED_BLOCKS());
}
//----------------------------------------------------------------------------
void vtkCompositeDataPipeline::CopyFromDataToInformation(
vtkDataObject* dobj, vtkInformation* inInfo)
{
if (dobj->IsA("vtkImageData"))
{
inInfo->Set(
WHOLE_EXTENT(), static_cast<vtkImageData*>(dobj)->GetExtent(), 6);
}
else if (dobj->IsA("vtkStructuredGrid"))
{
inInfo->Set(
WHOLE_EXTENT(), static_cast<vtkStructuredGrid*>(dobj)->GetExtent(), 6);
}
else if (dobj->IsA("vtkRectilinearGrid"))
{
inInfo->Set(
WHOLE_EXTENT(), static_cast<vtkRectilinearGrid*>(dobj)->GetExtent(), 6);
}
else if (dobj->IsA("vtkUniformGrid"))
{
inInfo->Set(
WHOLE_EXTENT(), static_cast<vtkUniformGrid*>(dobj)->GetExtent(), 6);
}
else
{
inInfo->Set(MAXIMUM_NUMBER_OF_PIECES(), 1);
}
}
//----------------------------------------------------------------------------
void vtkCompositeDataPipeline::PushInformation(vtkInformation* inInfo)
{
vtkDebugMacro(<< "PushInformation " << inInfo);
this->InformationCache->CopyEntry(inInfo, WHOLE_EXTENT());
this->InformationCache->CopyEntry(inInfo, MAXIMUM_NUMBER_OF_PIECES());
}
//----------------------------------------------------------------------------
......@@ -917,7 +883,6 @@ void vtkCompositeDataPipeline::PopInformation(vtkInformation* inInfo)
{
vtkDebugMacro(<< "PopInformation " << inInfo);
inInfo->CopyEntry(this->InformationCache, WHOLE_EXTENT());
inInfo->CopyEntry(this->InformationCache, MAXIMUM_NUMBER_OF_PIECES());
}
//----------------------------------------------------------------------------
......@@ -1036,8 +1001,6 @@ vtkCompositeDataSet* vtkCompositeDataPipeline::CreateOutputCompositeDataSet(
// Set the input to be vtkUniformGrid.
inInfo->Remove(vtkDataObject::DATA_OBJECT());
inInfo->Set(vtkDataObject::DATA_OBJECT(), tempInput);
// Process the whole dataset
this->CopyFromDataToInformation(tempInput, inInfo);
// The request is forwarded upstream through the pipeline.
request->Set(vtkExecutive::FORWARD_DIRECTION(), vtkExecutive::RequestUpstream);
// Algorithms process this request after it is forwarded.
......
......@@ -118,8 +118,6 @@ protected:
vtkInformationVector** inInfoVec,
vtkInformationVector* outInfoVec);
virtual void CopyFromDataToInformation(
vtkDataObject* dobj, vtkInformation* inInfo);
virtual void PushInformation(vtkInformation*);
virtual void PopInformation (vtkInformation*);
......
......@@ -92,29 +92,6 @@ int vtkCompositeDataSetAlgorithm::ProcessRequest(
// execute information
if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
{
if(request->Has(vtkStreamingDemandDrivenPipeline::FROM_OUTPUT_PORT()))
{
int outputPort = request->Get(
vtkStreamingDemandDrivenPipeline::FROM_OUTPUT_PORT());
vtkInformation* info = outputVector->GetInformationObject(outputPort);
if (info)
{
info->Set(
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1);
}
}
else
{
for (int outIdx=0; outIdx < this->GetNumberOfOutputPorts(); outIdx++)
{
vtkInformation* info = outputVector->GetInformationObject(outIdx);
if (info)
{
info->Set(
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1);
}
}
}
return this->RequestInformation(request, inputVector, outputVector);
}
......
......@@ -93,29 +93,6 @@ int vtkHierarchicalBoxDataSetAlgorithm::ProcessRequest(
// execute information
if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
{
if(request->Has(vtkStreamingDemandDrivenPipeline::FROM_OUTPUT_PORT()))
{
int outputPort = request->Get(
vtkStreamingDemandDrivenPipeline::FROM_OUTPUT_PORT());
vtkInformation* info = outputVector->GetInformationObject(outputPort);
if (info)
{
info->Set(
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1);
}
}
else
{
for (int outIdx=0; outIdx < this->GetNumberOfOutputPorts(); outIdx++)
{
vtkInformation* info = outputVector->GetInformationObject(outIdx);
if (info)
{
info->Set(
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1);
}
}
}
return this->RequestInformation(request, inputVector, outputVector);
}
......
......@@ -92,29 +92,6 @@ int vtkMultiBlockDataSetAlgorithm::ProcessRequest(
// execute information
if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
{
if(request->Has(vtkStreamingDemandDrivenPipeline::FROM_OUTPUT_PORT()))
{
int outputPort = request->Get(
vtkStreamingDemandDrivenPipeline::FROM_OUTPUT_PORT());
vtkInformation* info = outputVector->GetInformationObject(outputPort);
if (info)
{
info->Set(
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1);
}
}
else
{
for (int outIdx=0; outIdx < this->GetNumberOfOutputPorts(); outIdx++)
{
vtkInformation* info = outputVector->GetInformationObject(outIdx);
if (info)
{
info->Set(
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1);
}
}
}
return this->RequestInformation(request, inputVector, outputVector);
}
......
......@@ -201,16 +201,6 @@ int vtkMultiTimeStepAlgorithm::ProcessRequest(
// execute information
if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
{
if(request->Has(vtkStreamingDemandDrivenPipeline::FROM_OUTPUT_PORT()))
{
int outputPort = request->Get(
vtkStreamingDemandDrivenPipeline::FROM_OUTPUT_PORT());
vtkInformation* info = outputVector->GetInformationObject(outputPort);
if (info)
{
info->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1);
}
}
// Upstream changed, clear the cache.
this->Cache.clear();
return this->RequestInformation(request, inputVector, outputVector);
......
......@@ -29,7 +29,6 @@
#define VTK_UPDATE_EXTENT_COMBINE 1
#define VTK_UPDATE_EXTENT_REPLACE 2
class vtkExtentTranslator;
class vtkInformationDoubleKey;
class vtkInformationDoubleVectorKey;
class vtkInformationIdTypeKey;
......@@ -73,18 +72,6 @@ public:
int PropagateTime(int outputPort);
int UpdateTimeDependentInformation(int outputPort);
// Description:
// Set/Get the maximum number of pieces that can be requested from
// the given port. The maximum number of pieces is meta data for
// unstructured data sets. It gets set by the source during the
// update information call. A value of -1 indicates that there is
// no maximum.
int SetMaximumNumberOfPieces(int port, int n);
static int SetMaximumNumberOfPieces(vtkInformation *, int n);
int GetMaximumNumberOfPieces(int port);
static int GetMaximumNumberOfPieces(vtkInformation *);
// Description:
// Set/Get the whole extent of an output port. The whole extent is
// meta data for structured data sets. It gets set by the algorithm
......@@ -139,14 +126,6 @@ public:
int SetRequestExactExtent(int port, int flag);
int GetRequestExactExtent(int port);
// Description:
// Get/Set the object that will translate pieces into structured
// extents for an output port.
int SetExtentTranslator(int port, vtkExtentTranslator* translator);
static int SetExtentTranslator(vtkInformation *, vtkExtentTranslator* translator);
vtkExtentTranslator* GetExtentTranslator(int port);
static vtkExtentTranslator* GetExtentTranslator(vtkInformation *info);
// Description:
// Set/Get the whole bounding box of an output port data object.
// The whole whole bounding box is meta data for data sets. It gets
......@@ -170,10 +149,6 @@ public:
// to keep executing it.
static vtkInformationIntegerKey* CONTINUE_EXECUTING();
// Description:
// Key to store an extent translator in pipeline information.
static vtkInformationObjectBaseKey* EXTENT_TRANSLATOR();
// Description:
// Keys to store an update request in pipeline information.
static vtkInformationIntegerKey* UPDATE_EXTENT_INITIALIZED();
......@@ -182,16 +157,23 @@ public:
static vtkInformationIntegerKey* UPDATE_NUMBER_OF_PIECES();
static vtkInformationIntegerKey* UPDATE_NUMBER_OF_GHOST_LEVELS();
// Description:
// Key that tells the pipeline that a particular algorithm
// can or cannot handle piece request. If a filter cannot handle
// piece requests and is asked for a piece, the executive will
// flag an error. If a structured data source cannot handle piece
// requests but can produce sub-extents (CAN_PRODUCE_SUB_EXTENT),
// the executive will use an extent translator to split the extent
// into pieces. Otherwise, if a source cannot handle piece requests,
// the executive will ask for the whole data for piece 0 and not
// execute the source for other pieces.
static vtkInformationIntegerKey* CAN_HANDLE_PIECE_REQUEST();
// Description:
// Key for combining the update extents requested by all consumers,
// so that the final extent that is produced satisfies all consumers.
static vtkInformationIntegerVectorKey* COMBINED_UPDATE_EXTENT();
// Description:
// This is set if the extent was set through extent translation.
// GenerateGhostLevelArray() is called only when this is set.
static vtkInformationIntegerKey* UPDATE_EXTENT_TRANSLATED();
// Description:
// Key to store the whole extent provided in pipeline information.
static vtkInformationIntegerVectorKey* WHOLE_EXTENT();
......@@ -202,11 +184,6 @@ public:
// any requested size.
static vtkInformationIntegerKey* UNRESTRICTED_UPDATE_EXTENT();
// Description:
// Key to store the maximum number of pieces provided in pipeline
// information.
static vtkInformationIntegerKey* MAXIMUM_NUMBER_OF_PIECES();
// Description:
// Key to store the bounding box of the entire data set in pipeline
// information.
......@@ -234,7 +211,7 @@ public:
// Description:
// Whether there are time dependent meta information
// if there is, the pipe will perform two extra passes
// if there is, the pipeline will perform two extra passes
// to gather the time dependent information
static vtkInformationIntegerKey* TIME_DEPENDENT_INFORMATION();
......
......@@ -41,6 +41,8 @@ vtkTrivialProducer::vtkTrivialProducer()
this->SetNumberOfInputPorts(0);
this->SetNumberOfOutputPorts(1);
this->Output = 0;
this->WholeExtent[0] = this->WholeExtent[2] = this->WholeExtent[4] = 0;
this->WholeExtent[1] = this->WholeExtent[3] = this->WholeExtent[5] = -1;
}
//----------------------------------------------------------------------------
......@@ -109,6 +111,38 @@ int vtkTrivialProducer::FillOutputPortInformation(int, vtkInformation* info)
return 1;
}
//----------------------------------------------------------------------------
void vtkTrivialProducer::FillOutputDataInformation(vtkDataObject* output,
vtkInformation* outInfo)
{
vtkInformation* dataInfo = output->GetInformation();
if(dataInfo->Get(vtkDataObject::DATA_EXTENT_TYPE()) == VTK_3D_EXTENT)
{
int extent[6];
dataInfo->Get(vtkDataObject::DATA_EXTENT(), extent);
outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
extent, 6);
}
if (output->IsA("vtkImageData"))
{
vtkImageData* img = static_cast<vtkImageData*>(output);
double spacing[3];
img->GetSpacing(spacing);
outInfo->Set(vtkDataObject::SPACING(), spacing[0], spacing[1], spacing[2]);
double origin[3];
img->GetOrigin(origin);
outInfo->Set(vtkDataObject::ORIGIN(), origin[0], origin[1], origin[2]);
vtkDataObject::SetPointDataActiveScalarInfo(outInfo,
img->GetScalarType(),
img->GetNumberOfScalarComponents());
}
}
//----------------------------------------------------------------------------
int
vtkTrivialProducer::ProcessRequest(vtkInformation* request,
......@@ -119,41 +153,27 @@ vtkTrivialProducer::ProcessRequest(vtkInformation* request,
this->Output)
{
vtkInformation* outputInfo = outputVector->GetInformationObject(0);
vtkInformation* dataInfo = this->Output->GetInformation();
if(dataInfo->Get(vtkDataObject::DATA_EXTENT_TYPE()) == VTK_PIECES_EXTENT)
{
// There is no real source to change the output data, so we can
// produce exactly one piece.