Commit 8c486d25 authored by David Thompson's avatar David Thompson

ENH: Add a new filter, vtkAppendCompositeDataLeaves, which takes multiple

     input composite datasets with the same structure and outputs a
     composite dataset (again with the same structure) whose leaves
     contain all the cells of the input datasets at the corresponding
     input leaves.
ENH: Make the ExodusII reader output multiblock datasets.
parent 04661750
......@@ -7,6 +7,7 @@ SET(KIT_LIBS vtkFiltering verdict )
SET( Kit_SRCS
vtkAppendCompositeDataLeaves.cxx
vtkAppendFilter.cxx
vtkAppendPolyData.cxx
vtkAppendSelection.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkAppendCompositeDataLeaves.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 "vtkAppendCompositeDataLeaves.h"
#include "vtkAppendFilter.h"
#include "vtkAppendPolyData.h"
#include "vtkCell.h"
#include "vtkCellData.h"
#include "vtkCompositeDataIterator.h"
#include "vtkCompositeDataSet.h"
#include "vtkDataSetAttributes.h"
#include "vtkDataSetCollection.h"
#include "vtkExecutive.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkUnstructuredGrid.h"
vtkCxxRevisionMacro(vtkAppendCompositeDataLeaves, "1.1");
vtkStandardNewMacro(vtkAppendCompositeDataLeaves);
//----------------------------------------------------------------------------
vtkAppendCompositeDataLeaves::vtkAppendCompositeDataLeaves()
{
this->AppendFieldData = 0;
this->AppendUG = 0;
this->AppendPD = 0;
}
//----------------------------------------------------------------------------
vtkAppendCompositeDataLeaves::~vtkAppendCompositeDataLeaves()
{
if ( this->AppendUG )
this->AppendUG->Delete();
if ( this->AppendPD )
this->AppendPD->Delete();
}
//----------------------------------------------------------------------------
vtkCompositeDataSet* vtkAppendCompositeDataLeaves::GetInput( int idx )
{
if ( idx >= this->GetNumberOfInputConnections( 0 ) || idx < 0 )
{
return 0;
}
return vtkCompositeDataSet::SafeDownCast(
this->GetExecutive()->GetInputData( 0, idx ) );
}
//----------------------------------------------------------------------------
// Remove a dataset from the list of data to append.
void vtkAppendCompositeDataLeaves::RemoveInput( vtkDataSet* ds )
{
vtkAlgorithmOutput* algOutput = 0;
if ( ds )
{
algOutput = ds->GetProducerPort();
}
this->RemoveInputConnection( 0, algOutput );
}
//----------------------------------------------------------------------------
int vtkAppendCompositeDataLeaves::RequestDataObject(
vtkInformation*,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector )
{
vtkInformation* inInfo = inputVector[0]->GetInformationObject( 0 );
if ( ! inInfo )
{
return 0;
}
vtkCompositeDataSet* input = vtkCompositeDataSet::SafeDownCast(
inInfo->Get( vtkDataObject::DATA_OBJECT() ) );
if ( input )
{
this->GetOutputPortInformation( 0 )->Set(
vtkDataObject::DATA_EXTENT_TYPE(), input->GetExtentType() );
// for each output
for ( int i = 0; i < this->GetNumberOfOutputPorts(); ++ i )
{
vtkInformation* info = outputVector->GetInformationObject( i );
vtkCompositeDataSet *output = vtkCompositeDataSet::SafeDownCast(
info->Get( vtkDataObject::DATA_OBJECT() ) );
if ( ! output || ! output->IsA( input->GetClassName() ) )
{
vtkCompositeDataSet* newOutput = input->NewInstance();
newOutput->SetPipelineInformation( info );
newOutput->Delete();
}
}
return 1;
}
return 0;
}
//----------------------------------------------------------------------------
// Append data sets into single unstructured grid
int vtkAppendCompositeDataLeaves::RequestData(
vtkInformation* vtkNotUsed(request),
vtkInformationVector** vtkNotUsed(inputVector),
vtkInformationVector* outputVector)
{
int numInputs = this->GetNumberOfInputConnections( 0 );
if ( numInputs <= 0 )
{
// Fail silently when there are no inputs.
return 1;
}
// get the output info object
vtkInformation* outInfo = outputVector->GetInformationObject( 0 );
// get the ouptut
vtkCompositeDataSet* output = vtkCompositeDataSet::SafeDownCast(
outInfo->Get( vtkDataObject::DATA_OBJECT() ) );
vtkDebugMacro(<<"Copying structure to output");
vtkCompositeDataSet* anInput = vtkCompositeDataSet::SafeDownCast(
this->GetInput( 0 ) );
output->CopyStructure( anInput );
vtkDebugMacro(<<"Appending data together");
vtkCompositeDataIterator* iter = output->NewIterator();
iter->VisitOnlyLeavesOn();
iter->SkipEmptyNodesOff(); // We're iterating over the output, whose leaves are all empty.
int idx = 0;
int i;
static bool first = true;
for ( iter->InitTraversal(); ! iter->IsDoneWithTraversal(); iter->GoToNextItem(), ++idx )
{
// Loop over all inputs at this "spot" in the composite data.
vtkDataObject* obj = 0;
for ( i = 0; i < numInputs && ! obj; ++ i )
{
obj = this->GetInput( i )->GetDataSet( iter );
}
if ( ! obj )
{
continue; // no input had a non-NULL dataset
}
vtkUnstructuredGrid* ug = vtkUnstructuredGrid::SafeDownCast( obj );
if ( ug )
{
this->AppendUnstructuredGrids( i - 1, numInputs, iter, output );
continue;
}
vtkPolyData* pd = vtkPolyData::SafeDownCast( obj );
if ( pd )
{
this->AppendPolyData( i - 1, numInputs, iter, output );
continue;
}
if ( first )
{
first = false;
vtkWarningMacro(
<< "Input " << i << " was of type \""
<< obj->GetClassName() << "\" which is not handled\n" );
}
}
first = true;
iter->Delete();
return 1;
}
//----------------------------------------------------------------------------
int vtkAppendCompositeDataLeaves::FillInputPortInformation( int, vtkInformation* info )
{
info->Set( vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkCompositeDataSet" );
info->Set( vtkAlgorithm::INPUT_IS_REPEATABLE(), 1 );
return 1;
}
//----------------------------------------------------------------------------
void vtkAppendCompositeDataLeaves::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf( os, indent );
os << indent << "AppendFieldData: " << this->AppendFieldData << "\n";
os << indent << "AppendUG: " << this->AppendUG << "\n";
os << indent << "AppendPD: " << this->AppendPD << "\n";
}
//----------------------------------------------------------------------------
void vtkAppendCompositeDataLeaves::AppendUnstructuredGrids(
int i, int numInputs, vtkCompositeDataIterator* iter, vtkCompositeDataSet* output )
{
if ( this->AppendUG )
{
this->AppendUG->Delete();
}
this->AppendUG = vtkAppendFilter::New();
vtkUnstructuredGrid* ug = vtkUnstructuredGrid::New();
output->SetDataSet( iter, ug );
ug->Delete();
for ( int idx = i; idx < numInputs; ++ idx )
{
vtkCompositeDataSet* icdset = this->GetInput( idx );
if ( icdset )
{
vtkUnstructuredGrid* iudset = vtkUnstructuredGrid::SafeDownCast( icdset->GetDataSet( iter ) );
if ( iudset )
{
this->AppendUG->AddInput( iudset );
}
}
}
this->AppendUG->Update();
ug->ShallowCopy( this->AppendUG->GetOutput() );
this->AppendFieldDataArrays( i, numInputs, iter, ug );
}
//----------------------------------------------------------------------------
void vtkAppendCompositeDataLeaves::AppendPolyData(
int i, int numInputs, vtkCompositeDataIterator* iter, vtkCompositeDataSet* output )
{
if ( this->AppendPD )
{
this->AppendPD->Delete();
}
this->AppendPD = vtkAppendPolyData::New();
vtkPolyData* pd = vtkPolyData::New();
output->SetDataSet( iter, pd );
pd->Delete();
for ( int idx = i; idx < numInputs; ++ idx )
{
vtkCompositeDataSet* icdset = this->GetInput( idx );
if ( icdset )
{
vtkPolyData* ipdset = vtkPolyData::SafeDownCast( icdset->GetDataSet( iter ) );
if ( ipdset )
{
this->AppendPD->AddInput( ipdset );
}
}
}
this->AppendPD->Update();
pd->ShallowCopy( this->AppendPD->GetOutput() );
this->AppendFieldDataArrays( i, numInputs, iter, pd );
}
//----------------------------------------------------------------------------
void vtkAppendCompositeDataLeaves::AppendFieldDataArrays(
int i, int numInputs, vtkCompositeDataIterator* iter, vtkDataSet* odset )
{
if ( ! this->AppendFieldData )
return;
vtkFieldData* ofd = odset->GetFieldData();
for ( int idx = i; idx < numInputs; ++ idx )
{
vtkCompositeDataSet* icdset = this->GetInput( idx );
if ( icdset )
{
vtkDataObject* idobj = icdset->GetDataSet( iter );
if ( idobj )
{
vtkFieldData* ifd = idobj->GetFieldData();
int numArr = ifd->GetNumberOfArrays();
for ( int a = 0; a < numArr; ++ a )
{
vtkAbstractArray* arr = ifd->GetAbstractArray( a );
if ( ofd->HasArray( arr->GetName() ) )
{
// Do something?
}
else
{
ofd->AddArray( arr );
}
}
}
}
}
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkAppendCompositeDataLeaves.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 vtkAppendCompositeDataLeaves - appends one or more composite datasets with the same structure together into a single output composite dataset
// .SECTION Description
// vtkAppendCompositeDataLeaves is a filter that takes input composite datasets with the same
// structure: (1) the same number of entries and -- if any children are composites -- the
// same constraint holds from them; and (2) the same type of dataset at each position.
// It then creates an output dataset with the same structure whose leaves contain all the
// cells from the datasets at the corresponding leaves of the input datasets.
//
// Currently, only input polydata and unstructured grids are handled; other types of
// leaf datasets will be ignored and their positions in the output dataset will be NULL pointers.
// Point attributes (i.e., scalars, vectors, normals, field data, etc.) are extracted
// and appended only if all datasets have the point attributes available.
// (For example, if one dataset has scalars but another does not, scalars will
// not be appended.)
//
// .SECTION See Also
// vtkAppendPolyData vtkAppendFilter
#ifndef __vtkAppendCompositeDataLeaves_h
#define __vtkAppendCompositeDataLeaves_h
#include "vtkCompositeDataSetAlgorithm.h"
class vtkAppendFilter;
class vtkAppendPolyData;
class vtkCompositeDataIterator;
class vtkDataSet;
class vtkPolyData;
class vtkUnstructuredGrid;
class VTK_GRAPHICS_EXPORT vtkAppendCompositeDataLeaves : public vtkCompositeDataSetAlgorithm
{
public:
static vtkAppendCompositeDataLeaves* New();
vtkTypeRevisionMacro(vtkAppendCompositeDataLeaves,vtkCompositeDataSetAlgorithm);
void PrintSelf( ostream& os, vtkIndent indent );
// Description:
// Get any input of this filter.
//BTX
vtkCompositeDataSet* GetInput( int idx );
vtkCompositeDataSet* GetInput()
{ return this->GetInput( 0 ); }
//ETX
// Description:
// Remove a dataset from the list of data to append.
void RemoveInput( vtkDataSet* in );
// Description:
// Set/get whether the field data of each dataset in the composite dataset is copied to the output.
// If AppendFieldData is non-zero, then field data arrays from all the inputs are added
// to the output. If there are duplicates, the array on the first input encountered is taken.
vtkSetMacro(AppendFieldData,int);
vtkGetMacro(AppendFieldData,int);
vtkBooleanMacro(AppendFieldData,int);
protected:
vtkAppendCompositeDataLeaves();
~vtkAppendCompositeDataLeaves();
// Description:
// Since vtkCompositeDataSet is an abstract class and we output the same types as the input,
// we must override the default implementation.
virtual int RequestDataObject( vtkInformation*, vtkInformationVector**, vtkInformationVector* );
// Description:
// Iterates over the datasets and appends corresponding notes.
virtual int RequestData( vtkInformation*, vtkInformationVector**, vtkInformationVector* );
// Description:
// The input is repeatable, so we override the default implementation.
virtual int FillInputPortInformation( int port, vtkInformation* info );
// Description:
// When leaf nodes are unstructured grids, this uses a vtkAppendFilter to merge them.
virtual void AppendUnstructuredGrids( int i, int numInputs, vtkCompositeDataIterator* iter, vtkCompositeDataSet* output );
// Description:
// When leaf nodes are polydata, this uses a vtkAppendPolyData to merge them.
virtual void AppendPolyData( int i, int numInputs, vtkCompositeDataIterator* iter, vtkCompositeDataSet* output );
// Description:
// Both AppendUnstructuredGrids and AppendPolyData call AppendFieldDataArrays. If
// AppendFieldData is non-zero, then field data arrays from all the inputs are added
// to the output. If there are duplicates, the array on the first input encountered
// is taken.
virtual void AppendFieldDataArrays( int i, int numInputs, vtkCompositeDataIterator* iter, vtkDataSet* dset );
int AppendFieldData;
vtkAppendFilter* AppendUG;
vtkAppendPolyData* AppendPD;
private:
vtkAppendCompositeDataLeaves ( const vtkAppendCompositeDataLeaves& ); // Not implemented.
void operator = ( const vtkAppendCompositeDataLeaves& ); // Not implemented.
};
#endif // __vtkAppendCompositeDataLeaves_h
......@@ -106,13 +106,18 @@ IF(VTK_HAS_EXODUS)
SET(Kit_SRCS ${Kit_SRCS}
vtkExodusIICache.cxx
vtkExodusIIReader.cxx
vtkPExodusIIReader.cxx
vtkPExodusReader.cxx
vtkExodusReader.cxx
vtkDSPFilterDefinition.cxx
vtkExodusModel.cxx
vtkDSPFilterGroup.cxx
)
IF(VTK_USE_PARALLEL)
SET(Kit_SRCS ${Kit_SRCS}
vtkPExodusIIReader.cxx
vtkPExodusReader.cxx
)
SET(KIT_LIBS ${KIT_LIBS} vtkParallel)
ENDIF(VTK_USE_PARALLEL)
ENDIF(VTK_HAS_EXODUS)
IF (WIN32)
......
......@@ -50,6 +50,13 @@ public:
ObjectId = objId;
ArrayId = arrId;
}
vtkExodusIICacheKey( const vtkExodusIICacheKey& src )
{
Time = src.Time;
ObjectType = src.ObjectType;
ObjectId = src.ObjectId;
ArrayId = src.ArrayId;
}
bool match( const vtkExodusIICacheKey&other, const vtkExodusIICacheKey& pattern ) const
{
if ( pattern.Time && this->Time != other.Time )
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -36,22 +36,24 @@
#ifndef __vtkExodusIIReader_h
#define __vtkExodusIIReader_h
#include "vtkUnstructuredGridAlgorithm.h"
#include "vtkMultiBlockDataSetAlgorithm.h"
class vtkIntArray;
class vtkFloatArray;
class vtkDataArray;
class vtkDataSet;
class vtkPoints;
class vtkExodusIIReaderPrivate;
class vtkExodusModel;
class vtkExodusIICache;
class vtkMultiProcessController;
class vtkPoints;
class vtkUnstructuredGrid;
class VTK_HYBRID_EXPORT vtkExodusIIReader : public vtkUnstructuredGridAlgorithm
class VTK_HYBRID_EXPORT vtkExodusIIReader : public vtkMultiBlockDataSetAlgorithm
{
public:
static vtkExodusIIReader *New();
vtkTypeRevisionMacro(vtkExodusIIReader,vtkUnstructuredGridAlgorithm);
vtkTypeRevisionMacro(vtkExodusIIReader,vtkMultiBlockDataSetAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
......@@ -164,7 +166,7 @@ public:
EDGE_SET_CONN = 90, //!< edge set connectivity
NODE_SET_CONN = 89, //!< node set connectivity
NODAL_COORDS = 88, //!< raw nodal coordinates (not the "squeezed" version)
GLOBAL_OBJECT_ID = 87, //!< assembled object id (old BlockId) array
OBJECT_ID = 87, //!< object id (old BlockId) array
GLOBAL_ELEMENT_ID = 86, //!< assembled, zero-padded element id array
GLOBAL_NODE_ID = 85, //!< assembled, zero-padded nodal id array
ELEMENT_ID = 84, //!< element id map (old-style elem_num_map or first new-style elem map) array
......@@ -379,7 +381,7 @@ public:
// Description:
// There is a great deal of model information lost when an Exodus II
// file is read in to a vtkUnstructuredGrid. Turn this option ON
// file is read in to a vtkMultiBlockDataSet. Turn this option ON
// if you want this metadata to be read in to a vtkExodusModel object.
// The default is OFF.
......@@ -623,25 +625,30 @@ public:
void SetElementSetResultArrayStatus(const char* name, int flag)
{ this->SetObjectArrayStatus(ELEM_SET, name, flag); }
/**!\brief Fast path
*
* The following are set using the fast-path keys found in
* vtkPExodusIIReader's input information.
* Fast-path keys are meant to be used by an filter that
* works with temporal data. Rather than re-executing the pipeline
* for each timestep, since the exodus reader, as part of its API, contains
* a faster way to read temporal data, algorithms may use these
* keys to request temporal data.
* See also: vtkExtractArraysOverTime.
*/
//@{
// Description:
// The following are set using the fast-path keys found in
// vtkPExodusIIReader's input information.
// Fast-path keys are meant to be used by an filter that
// works with temporal data. Rather than re-executing the pipeline
// for each timestep, since the exodus reader, as part of its API, contains
// a faster way to read temporal data, algorithms may use these
// keys to request temporal data.
// See also: vtkExtractArraysOverTime.
// Set the fast-path keys. All three must be set for the fast-path
// option to work.
// Possible argument values: "POINT","CELL","EDGE","FACE"
void SetFastPathObjectType(const char *type);
// Description:
// Possible argument values: "INDEX","GLOBAL"
// "GLOBAL" means the id refers to a global id
// "INDEX" means the id refers to an index into the VTK array
void SetFastPathIdType(const char *type);
void SetFastPathObjectId(vtkIdType id);
//@}
// Description:
// Reset the user-specified parameters and flush internal arrays
......@@ -670,6 +677,13 @@ public:
// TimeStepRange accordingly.
virtual void UpdateTimeInformation();
// Description:
// Sends metadata (that read from the input file, not settings modified
// through this API) from the rank 0 node to all other processes in a job.
virtual void Broadcast( vtkMultiProcessController* ctrl );
virtual void Dump();
protected:
vtkExodusIIReader();
~vtkExodusIIReader();
......@@ -685,8 +699,6 @@ protected:
virtual void SetMetadata( vtkExodusIIReaderPrivate* );
vtkGetObjectMacro(Metadata,vtkExodusIIReaderPrivate);
virtual void Dump();
// Description:
// Returns true if XMLFileName has already been set. Otherwise, look for the XML
// metadata file in the same directory as the data file(s) using the following
......@@ -697,6 +709,21 @@ protected:
// Return true if found, false otherwise
bool FindXMLFile();
// Time query function. Called by ExecuteInformation().
// Fills the TimestepValues array.
void GetAllTimes(vtkInformationVector*);
// Description:
// Populates the TIME_STEPS and TIME_RANGE keys based on file metadata.
void AdvertiseTimeSteps( vtkInformation* outputInfo );
virtual void SetExodusModel( vtkExodusModel* em );
int ProcessRequest( vtkInformation *, vtkInformationVector **, vtkInformationVector *);
int RequestInformation( vtkInformation *, vtkInformationVector **, vtkInformationVector *);
int RequestData( vtkInformation *, vtkInformationVector **, vtkInformationVector *);
//int RequestDataOverTime( vtkInformation *, vtkInformationVector **, vtkInformationVector *);
// Parameters for controlling what is read in.
char* FileName;
char* XMLFileName;
......@@ -715,21 +742,10 @@ protected:
// Metadata containing a description of the currently open file.
vtkExodusIIReaderPrivate* Metadata;
// Time query function. Called by ExecuteInformation().
// Fills the TimestepValues array.
void GetAllTimes(vtkInformationVector*);
vtkExodusModel *ExodusModel;
int PackExodusModelOntoOutput;
int ExodusModelMetadata;
int ProcessRequest( vtkInformation *, vtkInformationVector **, vtkInformationVector *);
int RequestInformation( vtkInformation *, vtkInformationVector **, vtkInformationVector *);
int RequestData( vtkInformation *, vtkInformationVector **, vtkInformationVector *);
//int RequestDataOverTime( vtkInformation *, vtkInformationVector **, vtkInformationVector *);
virtual void SetExodusModel( vtkExodusModel* em );
private:
vtkExodusIIReader(const vtkExodusIIReader&); // Not implemented
void operator=(const vtkExodusIIReader&); // Not implemented
......
This diff is collapsed.
......@@ -42,6 +42,7 @@
#include <vtkstd/vector> // Required for vector
class vtkTimerLog;
class vtkMultiProcessController;
class VTK_HYBRID_EXPORT vtkPExodusIIReader : public vtkExodusIIReader
{
......@@ -50,6 +51,13 @@ public:
vtkTypeRevisionMacro(vtkPExodusIIReader,vtkExodusIIReader);
void PrintSelf( ostream& os, vtkIndent indent );
// Description:
// Set/get the communication object used to relay a list of files
// from the rank 0 process to all others. This is the only interprocess
// communication required by vtkPExodusIIReader.
void SetController(vtkMultiProcessController* c);
vtkGetObjectMacro(Controller, vtkMultiProcessController);
// Description:
// These methods tell the reader that the data is ditributed across
// multiple files. This is for distributed execution. It this case,
......@@ -112,6 +120,11 @@ public:
// of times that ALL readers can actually read.
virtual void UpdateTimeInformation();
// Description:
// Sends metadata (that read from the input file, not settings modified
// through this API) from the rank 0 node to all other processes in a job.
virtual void Broadcast( vtkMultiProcessController* ctrl );
protected:
vtkPExodusIIReader();
~vtkPExodusIIReader();
......@@ -128,6 +141,9 @@ protected:
// **KEN** Previous discussions concluded with std classes in header
// files is bad. Perhaps we should change ReaderList.
vtkMultiProcessController* Controller;
vtkIdType ProcRank;
vtkIdType ProcSize;
char* FilePattern;
char* CurrentFilePattern;
char* FilePrefix;
......
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