Commit 4d1d2fa4 authored by Berk Geveci's avatar Berk Geveci Committed by Kitware Robot

Merge topic 'port-legacy-to-new'

e9bc920d Ported all legacy readers to the new reader architecture.
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Utkarsh Ayachit's avatarUtkarsh Ayachit <utkarsh.ayachit@kitware.com>
Merge-request: !4618
parents 5352a9dc e9bc920d
......@@ -42,6 +42,7 @@ SET(Module_SRCS
vtkRectilinearGridAlgorithm.cxx
vtkScalarTree.cxx
vtkSimpleImageToImageFilter.cxx
vtkSimpleReader.cxx
vtkSimpleScalarTree.cxx
vtkSpanSpace.cxx
vtkSphereTree.cxx
......
......@@ -17,6 +17,7 @@
#include "vtkInformation.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkReaderExecutive.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include <vector>
......@@ -41,6 +42,12 @@ vtkParallelReader::~vtkParallelReader()
delete this->Internal;
}
//----------------------------------------------------------------------------
vtkExecutive* vtkParallelReader::CreateDefaultExecutive()
{
return vtkReaderExecutive::New();
}
//----------------------------------------------------------------------------
void vtkParallelReader::PrintSelf(ostream& os, vtkIndent indent)
{
......
......@@ -90,6 +90,8 @@ protected:
vtkParallelReader();
~vtkParallelReader() override;
vtkExecutive* CreateDefaultExecutive() override;
/**
* A subclass can override this method to provide an actual
* time value for a given file (this method is called for
......
......@@ -41,12 +41,40 @@ public:
void PrintSelf(ostream& os, vtkIndent indent) override;
/**
* Provide meta-data for the pipeline. These include things like
* time steps and whole extent. Subclasses may have specialized
* This can be overridden by a subclass to create an output that
* is determined by the file being read. If the output is known at
* compile time, it is easier to override FillOutputPortInformation()
* to set vtkDataObject::DATA_TYPE_NAME(). The subclass should compare
* the new output type with the type of the currentOutput argument and
* return currentOutput without changing its reference count if the
* types are same.
*/
virtual vtkDataObject* CreateOutput(vtkDataObject* currentOutput)
{
return currentOutput;
}
/**
* Provide meta-data for the pipeline. This meta-data cannot vary over
* time as this method will not be called when only a request is changed.
* These include things like time steps. Subclasses may have specialized
* interfaces making this simpler.
*/
virtual int ReadMetaData(vtkInformation* metadata) = 0;
/**
* Provide meta-data for the pipeline. This meta-data can vary over time
* as this method will be called after a request is changed (such as time)
* These include things like whole extent. Subclasses may have specialized
* interfaces making this simpler.
*/
virtual int ReadTimeDependentMetaData(
int /*timestep*/, vtkInformation* /*metadata*/)
{
return 1;
}
/**
* Read the mesh (connectivity) for a given set of data partitioning,
* number of ghost levels and time step (index). The reader populates
......
......@@ -54,40 +54,62 @@ int vtkReaderExecutive::CallAlgorithm(vtkInformation* request, int direction,
{
return 0;
}
if (request->Has(REQUEST_INFORMATION()))
using vtkSDDP = vtkStreamingDemandDrivenPipeline;
vtkInformation* reqs = outInfo->GetInformationObject(0);
int hasTime = reqs->Has(vtkSDDP::UPDATE_TIME_STEP());
double* steps =
reqs->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
int timeIndex = 0;
if (hasTime && steps)
{
double requestedTimeStep =
reqs->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
int length =
reqs->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
// find the first time value larger than requested time value
// this logic could be improved
int cnt = 0;
while (cnt < length-1 && steps[cnt] < requestedTimeStep)
{
cnt++;
}
timeIndex = cnt;
}
if (request->Has(REQUEST_DATA_OBJECT()))
{
vtkDataObject* currentOutput = vtkDataObject::GetData(outInfo);
vtkDataObject* output = reader->CreateOutput(currentOutput);
if (output)
{
result = 1;
if (output != currentOutput)
{
outInfo->GetInformationObject(0)->Set(
vtkDataObject::DATA_OBJECT(), output);
output->Delete();
}
}
}
else if (request->Has(REQUEST_INFORMATION()))
{
result = reader->ReadMetaData(outInfo->GetInformationObject(0));
}
else if (request->Has(REQUEST_TIME_DEPENDENT_INFORMATION()))
{
result = reader->ReadTimeDependentMetaData(
timeIndex, outInfo->GetInformationObject(0));
}
else if (request->Has(REQUEST_DATA()))
{
typedef vtkStreamingDemandDrivenPipeline vtkSDDP;
vtkInformation* reqs = outInfo->GetInformationObject(0);
int piece = reqs->Has(vtkSDDP::UPDATE_PIECE_NUMBER()) ?
reqs->Get(vtkSDDP::UPDATE_PIECE_NUMBER()) : 0 ;
int npieces = reqs->Has(vtkSDDP::UPDATE_NUMBER_OF_PIECES()) ?
reqs->Get(vtkSDDP::UPDATE_NUMBER_OF_PIECES()) : 1;
int nghosts = reqs->Get(UPDATE_NUMBER_OF_GHOST_LEVELS());
int hasTime = reqs->Has(vtkSDDP::UPDATE_TIME_STEP());
double* steps =
reqs->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
int timeIndex = 0;
if (hasTime && steps)
{
double requestedTimeStep =
reqs->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
int length =
reqs->Length(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
// find the first time value larger than requested time value
// this logic could be improved
int cnt = 0;
while (cnt < length-1 && steps[cnt] < requestedTimeStep)
{
cnt++;
}
timeIndex = cnt;
}
vtkDataObject* output = vtkDataObject::GetData(outInfo);
result = reader->ReadMesh(
piece, npieces, nghosts, timeIndex, output);
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSimpleReader.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 "vtkSimpleReader.h"
#include "vtkInformation.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkReaderExecutive.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include <vector>
#include <numeric>
struct vtkSimpleReaderInternal
{
using FileNamesType = std::vector<std::string>;
FileNamesType FileNames;
};
//----------------------------------------------------------------------------
vtkSimpleReader::vtkSimpleReader()
{
this->Internal = new vtkSimpleReaderInternal;
this->CurrentFileIndex = -1;
this->HasTemporalMetaData = false;
}
//----------------------------------------------------------------------------
vtkSimpleReader::~vtkSimpleReader()
{
delete this->Internal;
}
//----------------------------------------------------------------------------
vtkExecutive* vtkSimpleReader::CreateDefaultExecutive()
{
return vtkReaderExecutive::New();
}
//----------------------------------------------------------------------------
void vtkSimpleReader::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
//----------------------------------------------------------------------------
void vtkSimpleReader::AddFileName(const char* fname)
{
if(fname == nullptr || strlen(fname) == 0)
{
return;
}
this->Internal->FileNames.push_back(fname);
this->Modified();
}
//----------------------------------------------------------------------------
void vtkSimpleReader::ClearFileNames()
{
this->Internal->FileNames.clear();
this->Modified();
}
//----------------------------------------------------------------------------
int vtkSimpleReader::GetNumberOfFileNames() const
{
return static_cast<int>(this->Internal->FileNames.size());
}
//----------------------------------------------------------------------------
const char* vtkSimpleReader::GetFileName(int i) const
{
return this->Internal->FileNames[i].c_str();
}
//----------------------------------------------------------------------------
const char* vtkSimpleReader::GetCurrentFileName() const
{
if (this->CurrentFileIndex < 0 ||
this->CurrentFileIndex >= (int)this->Internal->FileNames.size())
{
return nullptr;
}
return this->Internal->FileNames[this->CurrentFileIndex].c_str();
}
//----------------------------------------------------------------------------
int vtkSimpleReader::ReadTimeDependentMetaData(
int timestep, vtkInformation* metadata)
{
if(!this->HasTemporalMetaData)
{
return 1;
}
int nTimes = static_cast<int>(this->Internal->FileNames.size());
if (timestep >= nTimes)
{
vtkErrorMacro("Cannot read time step " << timestep << ". Only " <<
nTimes << " time steps are available.");
return 0;
}
return this->ReadMetaDataSimple(
this->Internal->FileNames[timestep], metadata);
}
//----------------------------------------------------------------------------
int vtkSimpleReader::ReadMetaData(vtkInformation* metadata)
{
if(this->HasTemporalMetaData)
{
metadata->Set(
vtkStreamingDemandDrivenPipeline::TIME_DEPENDENT_INFORMATION(), 1);
}
else
{
if (!this->Internal->FileNames.empty())
{
// Call the meta-data function on the first file.
int retval =
this->ReadMetaDataSimple(this->Internal->FileNames[0], metadata);
if (!retval)
{
return retval;
}
}
}
if(this->Internal->FileNames.empty())
{
// No file names specified. No meta-data. There is still
// no need to return with an error.
return 1;
}
size_t nTimes = this->Internal->FileNames.size();
std::vector<double> times(nTimes);
bool hasTime = true;
auto iter = times.begin();
for(const auto& fname: this->Internal->FileNames)
{
auto time = this->GetTimeValue(fname);
if (vtkMath::IsNan(time))
{
hasTime = false;
break;
}
*iter++ = time;
}
if (!hasTime)
{
std::iota(times.begin(), times.end(), 0);
}
double timeRange[2];
timeRange[0] = times[0];
timeRange[1] = times[nTimes - 1];
metadata->Set(
vtkStreamingDemandDrivenPipeline::TIME_STEPS(), &times[0], (int)nTimes);
metadata->Set(
vtkStreamingDemandDrivenPipeline::TIME_RANGE(), timeRange, 2);
return 1;
}
//----------------------------------------------------------------------------
int vtkSimpleReader::ReadMesh(
int piece, int, int, int timestep, vtkDataObject* output)
{
// Not a parallel reader. Cannot handle anything other than the first piece,
// which will have everyhing.
if (piece > 0)
{
return 1;
}
int nTimes = static_cast<int>(this->Internal->FileNames.size());
if (timestep >= nTimes)
{
vtkErrorMacro("Cannot read time step " << timestep << ". Only " <<
nTimes << " time steps are available.");
return 0;
}
if (this->ReadMeshSimple(
this->Internal->FileNames[timestep], output))
{
this->CurrentFileIndex = timestep;
return 1;
}
return 0;
}
//----------------------------------------------------------------------------
int vtkSimpleReader::ReadPoints(
int piece, int , int , int timestep, vtkDataObject* output)
{
// Not a parallel reader. Cannot handle anything other than the first piece,
// which will have everyhing.
if (piece > 0)
{
return 1;
}
int nTimes = static_cast<int>(this->Internal->FileNames.size());
if (timestep >= nTimes)
{
vtkErrorMacro("Cannot read time step " << timestep << ". Only " <<
nTimes << " time steps are available.");
return 0;
}
return this->ReadPointsSimple(
this->Internal->FileNames[timestep], output);
}
//----------------------------------------------------------------------------
int vtkSimpleReader::ReadArrays(
int piece, int , int , int timestep, vtkDataObject* output)
{
// Not a parallel reader. Cannot handle anything other than the first piece,
// which will have everyhing.
if (piece > 0)
{
return 1;
}
int nTimes = static_cast<int>(this->Internal->FileNames.size());
if (timestep >= nTimes)
{
vtkErrorMacro("Cannot read time step " << timestep << ". Only " <<
nTimes << " time steps are available.");
return 0;
}
return this->ReadArraysSimple(
this->Internal->FileNames[timestep], output);
}
//----------------------------------------------------------------------------
double vtkSimpleReader::GetTimeValue(const std::string&)
{
return vtkMath::Nan();
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkSimpleReader.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.
=========================================================================*/
/**
* @class vtkSimpleReader
* @brief Superclass for algorithms that are not time or parallel aware
*
*/
#ifndef vtkSimpleReader_h
#define vtkSimpleReader_h
#include "vtkCommonExecutionModelModule.h" // For export macro
#include "vtkReaderAlgorithm.h"
#include <string> // needed for std::string in the interface
struct vtkSimpleReaderInternal;
class VTKCOMMONEXECUTIONMODEL_EXPORT vtkSimpleReader : public vtkReaderAlgorithm
{
public:
vtkTypeMacro(vtkSimpleReader,vtkReaderAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent) override;
/**
* Add a filename to be read. Since this superclass handles
* file series to support time, multiple filenames can be added.
* Note that the time values are either integers growing sequentially,
* or are obtained from individual files as supported by the subclass.
*/
void AddFileName(const char* fname);
/**
* Removes all filenames stored by the reader.
*/
void ClearFileNames();
/**
* Returns the number of filenames stored by the reader.
*/
int GetNumberOfFileNames() const;
/**
* Returns a particular filename stored by the reader.
*/
const char* GetFileName(int i) const;
/**
* Returns the filename that was last loaded by the reader.
* This is set internally in ReadMesh()
*/
const char* GetCurrentFileName() const;
//@{
/**
* This is the superclass API overridden by this class
* to provide time support internally. Subclasses should
* not normally have to override these methods.
*/
int ReadTimeDependentMetaData(
int timestep, vtkInformation* metadata) override;
int ReadMetaData(vtkInformation* metadata) override;
int ReadMesh(
int piece, int npieces, int nghosts, int timestep,
vtkDataObject* output) override;
int ReadPoints(
int piece, int npieces, int nghosts, int timestep,
vtkDataObject* output) override;
int ReadArrays(
int piece, int npieces, int nghosts, int timestep,
vtkDataObject* output) override;
//@}
/**
* A subclass can override this method to provide an actual
* time value for a given file (this method is called for
* each filename stored by the reader). If time values is not
* available, the subclass does not have to override. This
* will return vtkMath::NaN() if no time value is present
* in the file.
*/
virtual double GetTimeValue(const std::string& fname);
/**
* A subclass can override this method to provide meta data
* specific to a particular file. In order for this method
* to be called, HasTemporalMetaData has to be set to true.
*/
virtual int ReadMetaDataSimple(const std::string& /*fname*/,
vtkInformation* /*metadata*/)
{
return 1;
}
/**
* A method that needs to be override by the subclass to provide
* the mesh (topology). Note that the filename is passed to this
* method and should be used by the subclass. The subclass directly
* adds the structure/topology to the provided data object.
*/
virtual int ReadMeshSimple(const std::string& fname,
vtkDataObject* output) = 0;
/**
* A method that needs to be override by the subclass to provide
* the point coordinates. Note that the filename is passed to this
* method and should be used by the subclass. The subclass directly
* adds the coordinates to the provided data object.
*/
virtual int ReadPointsSimple(const std::string& fname,
vtkDataObject* output) = 0;
/**
* A method that needs to be override by the subclass to provide
* data arrays. Note that the filename is passed to this
* method and should be used by the subclass. The subclass directly
* adds data arrays to the provided data object.
*/
virtual int ReadArraysSimple(const std::string& fname,
vtkDataObject* output) = 0;
protected:
vtkSimpleReader();
~vtkSimpleReader() override;
vtkExecutive* CreateDefaultExecutive() override;
int CurrentFileIndex;
bool HasTemporalMetaData;
private:
vtkSimpleReader(const vtkSimpleReader&) = delete;
void operator=(const vtkSimpleReader&) = delete;
vtkSimpleReaderInternal* Internal;
};
#endif
......@@ -176,27 +176,40 @@ int vtkStreamingDemandDrivenPipeline
return result;
}
// Look for specially supported requests.
// Look for specially supported requests.
if(request->Has(REQUEST_TIME_DEPENDENT_INFORMATION()))
{
int result = 1;
int outputPort = -1;
if(request->Has(FROM_OUTPUT_PORT()))
{
outputPort = request->Get(FROM_OUTPUT_PORT());
}
int N2E = 1;
if(outputPort>=0)
int N2E = this->Superclass::NeedToExecuteData(outputPort, inInfoVec,outInfoVec);
if(!N2E && outputPort>=0)
{
vtkInformation* outInfo = outInfoVec->GetInformationObject(outputPort);
if(!outInfo->Has(TIME_DEPENDENT_INFORMATION()))
vtkDataObject* dataObject = outInfo->Get(vtkDataObject::DATA_OBJECT());
if (outInfo->Has(TIME_DEPENDENT_INFORMATION()))
{
N2E = this->NeedToExecuteBasedOnTime(outInfo,dataObject);
}
else
{
N2E = 0;
}
}
if(!N2E)
if(N2E)
{
return 1;
if(!this->ForwardUpstream(request))
{
return 0;
}
result = this->CallAlgorithm(request, vtkExecutive::RequestUpstream,
inInfoVec, outInfoVec);
}
return result;
}
if(request->Has(REQUEST_UPDATE_EXTENT()))
......
......@@ -70,53 +70,21 @@ void vtkBiomTableReader::SetOutput(vtkTable *output)
}
//----------------------------------------------------------------------------
// I do not think this should be here, but I do not want to remove it now.
int vtkBiomTableReader::RequestUpdateExtent(
vtkInformation *,
vtkInformationVector **,
vtkInformationVector *outputVector)
int vtkBiomTableReader::ReadMeshSimple(const std::string& fname,
vtkDataObject* doOutput)
{
vtkInformation *outInfo = outputVector->GetInformationObject(0);
int piece, numPieces;
piece = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
numPieces = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
// make sure piece is valid
if (piece < 0 || piece >= numPieces)
{
return 1;
}
return 1;
}
//----------------------------------------------------------------------------
int vtkBiomTableReader::RequestData(
vtkInformation *,
vtkInformationVector **,
vtkInformationVector *outputVector)
{
vtkInformation *outInfo = outputVector->GetInformationObject(0);
// Return all data in the first piece ...
if(outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
{
return 1;
}
vtkDebugMacro(<<"Reading biom table...");
if(this->GetFileName() == nullptr || strcmp(this->GetFileName(), "") == 0)
if(fname.empty())
{
vtkErrorMacro(<<"Input filename not set");
return 1;
}
std::ifstream ifs( this->GetFileName(), std::ifstream::in );
std::ifstream ifs( fname, std::ifstream::in );
if(!ifs.good())
{
vtkErrorMacro(<<"Unable to open " << this->GetFileName() << " for reading");
vtkErrorMacro(<<"Unable to open " << fname << " for reading");
return 1;
}
......@@ -132,7 +100,8 @@ int vtkBiomTableReader::RequestData(
vtkNew<vtkStringArray> rowNames;
rowNames->SetName("name");
this->GetOutput()->AddColumn(rowNames);
vtkTable* output = vtkTable::SafeDownCast(doOutput);
output->AddColumn(rowNames);
for ( int i = 1; i < this->NumberOfColumns + 1; ++i )
{
switch(this->DataType)
......@@ -140,26 +109,26 @@ int vtkBiomTableReader::RequestData(
case VTK_INT:
{
vtkNew<vtkIntArray> intCol;