I have been working through the vtkTimeSourceExample.h
and would am having trouble.
I have this Janky (technical term) file reader that I would like to generate a xdmf3
file or vtu
file for all the files to be read in. reading in one file at a time works, but I want to read all of them and write to a single file.
Currently I am deriving a class from vtkUnstructuredGridAlgorithm
and setting the number of inputs to zero. I would like update the vtkUnstructuredGrid
based on a map of timesteps and filenames.
e.g.
vtkSmartPointer<GridGen> thingy = vtkSmartPointer<GridGen>::New();
thingy->SetTime(std:vector<double> times);
thingy->SetFileMap(std::map<double, std::string>)
vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
writer->SetFileName("blarg.vtu");
writer->SetNumberOfTimeSteps(filemap.size());
writer->SetInputConnection(0, thingy->GetOutputPort(0));
writer->Start():
for(int i = 0; i < times.size(); ++i ) {
writer->WriteNextTime(times.at(i));
writer->Stop():
The question is what needs to be in RequestData
, RequestInformation
, and do I even need RequestUpdateExtent
?
so far I have
class GridGen : public vtkUnstructuredGridAlgorithm {
public:
static GridGen* New();
vtkTypeMacro(GridGen, vtkUnstructuredGridAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "FileName id: " << (this->m_nsteps ? this->m_nsteps : 'A') << std::endl;
}
vtkSetMacro(HasTimeDependentData, bool);
void SetTime(vtkSmartPointer<vtkDoubleArray> time)
{
this->m_nsteps = time->GetNumberOfTuples();
this->m_steps.resize(this->m_nsteps);
for(int i = 0; i < this->m_nsteps; ++i)
{
this->m_steps.at(i) = time->GetValue(i);
}
}
void SetFilemap(std::map<double, std::string> filemap) {
this->m_filemap = filemap;
}
void SetTimeInstance(double time) {
this->m_time = time;
}
protected:
GridGen()
{
this->SetNumberOfInputPorts(0);
this->m_time = 0;
this->m_index = 0;
this->m_nsteps = 1;
this->m_time_vector.push_back(0);
this->m_steps;
this->HasTimeDependentData = true;
}
~GridGen() override = default;
void SetNumberOfInputs() {
this->SetNumberOfInputPorts(this->m_nsteps);
}
int RequestInformation(
vtkInformation* reqInfo, vtkInformationVector** inVector, vtkInformationVector* outVector) {
std::cout << " got here yo" << std::endl;
if (!this->Superclass::RequestInformation(reqInfo, inVector, outVector)) {
std::cout<< "Is there no output?" << std::endl;
return 0;
}
vtkInformation* info = outVector->GetInformationObject(0);
// tell the caller that I can provide time varying data and
// tell it what range of times I can deal with
double tRange[2];
tRange[0] = this->m_steps.front();
tRange[1] = this->m_steps.back();
info->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), tRange, 2);
// tell the caller if this filter can provide values ONLY at discrete times
info->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(), &m_steps[0], static_cast<int>(this->m_steps.size()));
info->Set(CAN_HANDLE_PIECE_REQUEST(), 1);
return 1;
}
int RequestData(vtkInformation* vtkNotUsed(reqInfo),
vtkInformationVector** vtkNotUsed(inputVector),
vtkInformationVector* outputVector)
{
std::cout << " got here yo yo" << std::endl;
vtkInformation* outInfo = outputVector->GetInformationObject(0);
vtkUnstructuredGrid* output = vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
if (!output) {
std::cout<< "Is there no output?" << std::endl;
return 0;
}
outputVector->GetInformationObject(0)->Set(
vtkStreamingDemandDrivenPipeline::TIME_DEPENDENT_INFORMATION(), 1);
std::cout << "Has TD: "
<< outputVector->GetInformationObject(0)->Get(
vtkStreamingDemandDrivenPipeline::TIME_DEPENDENT_INFORMATION())
<< std::endl;
std::cout << "capr" << std::endl;
// determine what time is being asked for
double reqTime = 0.0;
double reqTS(0);
if(outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS())){
std::cout << " has time steps" << std::endl;
double * test = outInfo->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
std::cout << *test << std::endl;
}
else{
std::cout << " does not have time steps" << std::endl;
}
if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()))
{
std::cout << " yes update time step" << std::endl;
// reqNTS = outInfo->Length
// (vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
reqTS = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
// TODO: produce multiblock output when multiple time steps are asked for
// for now just answer the first one
reqTime = reqTS;
}
else{
outInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP(), 1);
std::cout << "not updating" << std::endl;
}
std::cout << "reqTime " << reqTime << " m_time " << this->m_time<< std::endl;
outInfo->Set(vtkDataObject::DATA_TIME_STEP(), this->m_time);
if (outInfo->Has(vtkDataObject::DATA_TIME_STEP()))
{
std::cout << " yes update time step" << std::endl;
}
output->GetInformation()->Set(vtkDataObject::DATA_TIME_STEP(), this->m_steps.at(this->m_index));
std::cout << output->GetInformation()->Get(vtkDataObject::DATA_TIME_STEP()) << std::endl;
double timeStep = this->m_steps.at(this->m_index);
char *szBuffer = new char[this->m_filemap[timeStep].size()+1];
strcpy(szBuffer, this->m_filemap[timeStep].c_str());
vtkSmartPointer<vtkUnstructuredGrid> grid = ReadFileTest(szBuffer, TRUE, FALSE);
output->SetPoints(grid->GetPoints());
output->SetCells(grid->GetCellTypesArray(), grid->GetCells());
for(int i = 0; i < grid->GetPointData()->GetNumberOfArrays(); ++i)
{
output->GetPointData()->AddArray(grid->GetPointData()->GetArray(i));
}
for(int i = 0; i < grid->GetCellData()->GetNumberOfArrays(); ++i)
{
output->GetCellData()->AddArray(grid->GetCellData()->GetArray(i));
}
// this->AddInputData(this->m_index, output);
this->m_index += 1;
return 1;
}
private:
GridGen(const GridGen&) = delete;
void operator=(const GridGen&) = delete;
std::vector<double> m_time_vector;
std::map<double, std::string> m_filemap;
int m_nsteps;
int m_index;
std::vector<double> m_steps;
double m_time;
bool HasTimeDependentData;
};