Commit 6e0acf3b authored by Berk Geveci's avatar Berk Geveci

Added support for reading/writing time from field data.

Simple change to XML readers and writers that adds the optional
support of using a field array called TimeValue to provide time
values (vtkStreamingDemandDrivenPipeline::TIME_STEPS()) to
the pipeline.
parent 3056e465
Field Data as Time Meta-Data in VTK XML File Formats
====================================================
As of VTK 8.2, VTK XML readers and writers support embedding time
meta-data as a field array. This is demonstrated best with an example:
<VTKFile type="PolyData" version="1.0" byte_order="LittleEndian" header_type="UInt64">
<PolyData>
<FieldData>
<DataArray type="Float64" Name="TimeValue" NumberOfTuples="1">1.24
</DataArray>
</FieldData>
...
</VTKFile>
Here TimeValue is a regular double precision array that has a single value of 1.24.
The XML readers will treat this array in a special way. When they encounter this array
during the meta-data stage (`RequestInformation()`), they will read the value from
this array and generate a `vtkStreamingDemandDrivenPipeline::TIME_STEPS()` key
in the output information containing this value.
In addition, the XML writers will generate a field array of name TimeValue in the
output, if they encounter time value in their input (`vtkDataObject::DATA_TIME_STEP()`).
This is done even if the data does not have a TimeValue array. Furthermore, even such
an array exists, it will be replaced with one that contains the value from
`vtkDataObject::DATA_TIME_STEP()` to make sure that the value is consistent with the
pipeline value.
This change may appear pointless on its own as a single time value is not very useful.
Its main use is when reading file series as it is done by ParaView's file (time) series
readers.
......@@ -18,6 +18,7 @@
#include "vtkCompositeDataPipeline.h"
#include "vtkCompositeDataSet.h"
#include "vtkDataObjectTreeIterator.h"
#include "vtkDoubleArray.h"
#include "vtkErrorCode.h"
#include "vtkExecutive.h"
#include "vtkFieldData.h"
......@@ -336,10 +337,25 @@ int vtkXMLCompositeDataWriter::WriteData()
{
this->DataMode = vtkXMLWriter::Binary;
}
vtkFieldData *fieldData = this->GetInput()->GetFieldData();
if (fieldData && fieldData->GetNumberOfArrays())
vtkDataObject* input = this->GetInput();
vtkFieldData *fieldData = input->GetFieldData();
vtkInformation* meta = input->GetInformation();
bool hasTime = meta->Has(vtkDataObject::DATA_TIME_STEP()) ? true : false;
if ((fieldData && fieldData->GetNumberOfArrays()) || hasTime)
{
this->WriteFieldDataInline(fieldData, indent);
vtkNew<vtkFieldData> fieldDataCopy;
fieldDataCopy->ShallowCopy(fieldData);
if (hasTime)
{
vtkNew<vtkDoubleArray> time;
time->SetNumberOfTuples(1);
time->SetTypedComponent(0, 0, meta->Get(vtkDataObject::DATA_TIME_STEP()));
time->SetName("TimeValue");
fieldDataCopy->AddArray(time);
}
this->WriteFieldDataInline(fieldDataCopy, indent);
}
this->DataMode = dataMode;
......
......@@ -16,6 +16,7 @@
#include "vtkArrayIteratorIncludes.h"
#include "vtkCallbackCommand.h"
#include "vtkDataArray.h"
#include "vtkDataArraySelection.h"
#include "vtkDataCompressor.h"
#include "vtkDataSet.h"
......@@ -490,6 +491,35 @@ int vtkXMLReader::ReadXMLInformation()
this->ReadError = 1;
}
if (this->FieldDataElement) // read the field data information
{
for (int i = 0; i < this->FieldDataElement->GetNumberOfNestedElements(); i++)
{
vtkXMLDataElement* eNested = this->FieldDataElement->GetNestedElement(i);
const char* name = eNested->GetAttribute("Name");
if (name && strncmp(name, "TimeValue", 9) == 0)
{
vtkAbstractArray* array = this->CreateArray(eNested);
array->SetNumberOfTuples(1);
if (!this->ReadArrayValues(eNested, 0, array, 0, 1))
{
this->DataError = 1;
}
vtkDataArray* da = vtkDataArray::SafeDownCast(array);
if (da)
{
double val = da->GetComponent(0, 0);
vtkInformation* info = this->GetCurrentOutputInformation();
info->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(), &val, 1);
double range[2] = {val, val};
info->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), range, 2);
}
array->Delete();
}
}
}
// Close the input stream to prevent resource leaks.
this->CloseStream();
......@@ -510,30 +540,32 @@ int vtkXMLReader::RequestInformation(vtkInformation *request,
int outputPort =
request->Get( vtkDemandDrivenPipeline::FROM_OUTPUT_PORT() );
outputPort = outputPort >= 0 ? outputPort : 0;
this->SetupOutputInformation
(outputVector->GetInformationObject(outputPort) );
// this->NumberOfTimeSteps has been set during the
// this->ReadXMLInformation()
int numTimesteps = this->GetNumberOfTimeSteps();
this->TimeStepRange[0] = 0;
this->TimeStepRange[1] = (numTimesteps > 0 ? numTimesteps-1 : 0);
if (numTimesteps != 0)
vtkInformation* outInfo = outputVector->GetInformationObject(0);
this->SetupOutputInformation(outInfo);
if (!outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_RANGE()))
{
std::vector<double> timeSteps(numTimesteps);
for (int i = 0; i < numTimesteps; i++)
// this->NumberOfTimeSteps has been set during the
// this->ReadXMLInformation()
int numTimesteps = this->GetNumberOfTimeSteps();
this->TimeStepRange[0] = 0;
this->TimeStepRange[1] = (numTimesteps > 0 ? numTimesteps-1 : 0);
if (numTimesteps != 0)
{
timeSteps[i] = i;
std::vector<double> timeSteps(numTimesteps);
for (int i = 0; i < numTimesteps; i++)
{
timeSteps[i] = i;
}
outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),
&timeSteps[0],
numTimesteps);
double timeRange[2];
timeRange[0] = timeSteps[0];
timeRange[1] = timeSteps[numTimesteps-1];
outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(),
timeRange, 2);
}
vtkInformation* outInfo = outputVector->GetInformationObject(0);
outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),
&timeSteps[0],
numTimesteps);
double timeRange[2];
timeRange[0] = timeSteps[0];
timeRange[1] = timeSteps[numTimesteps-1];
outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(),
timeRange, 2);
}
}
else
......
......@@ -23,6 +23,7 @@
#include "vtkCellData.h"
#include "vtkCommand.h"
#include "vtkDataArray.h"
#include "vtkDoubleArray.h"
#include "vtkDataSet.h"
#include "vtkErrorCode.h"
#include "vtkInformation.h"
......@@ -2474,20 +2475,35 @@ void vtkXMLWriter::WriteArrayInline(
//----------------------------------------------------------------------------
void vtkXMLWriter::WriteFieldData(vtkIndent indent)
{
vtkFieldData *fieldData = this->GetInput()->GetFieldData();
if (!fieldData || !fieldData->GetNumberOfArrays())
vtkDataObject* input = this->GetInput();
vtkFieldData *fieldData = input->GetFieldData();
vtkInformation* meta = input->GetInformation();
bool hasTime = meta->Has(vtkDataObject::DATA_TIME_STEP()) ? true : false;
if ((!fieldData || !fieldData->GetNumberOfArrays()) && !hasTime)
{
return;
}
vtkNew<vtkFieldData> fieldDataCopy;
fieldDataCopy->ShallowCopy(fieldData);
if (hasTime)
{
vtkNew<vtkDoubleArray> time;
time->SetNumberOfTuples(1);
time->SetTypedComponent(0, 0, meta->Get(vtkDataObject::DATA_TIME_STEP()));
time->SetName("TimeValue");
fieldDataCopy->AddArray(time);
}
if (this->DataMode == vtkXMLWriter::Appended)
{
this->WriteFieldDataAppended(fieldData, indent, this->FieldDataOM);
this->WriteFieldDataAppended(fieldDataCopy, indent, this->FieldDataOM);
}
else
{
// Write the point data arrays.
this->WriteFieldDataInline(fieldData, indent);
this->WriteFieldDataInline(fieldDataCopy, indent);
}
}
......
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