Commit 02f949cb authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

Handle mismatch is chosen and available arrays.

vtkXMLDataReader had asserts that checked for extact match between
arrays enabled using the array selection API and then the arrays
actually read (present) in the file. This caused issues when reading
composite datasets with partial arrays following the change in
56f1f110 (see paraview/paraview#18189).

Updating the code in vtkXMLDataReader so that it can handle a mismatch
in fields. The limitation was unreasonable anyways.
parent 1fffa689
...@@ -30,10 +30,21 @@ ...@@ -30,10 +30,21 @@
#include <cassert> #include <cassert>
#include <map> // needed for std::map
class vtkXMLDataReader::MapStringToInt : public std::map<std::string, int>
{
};
class vtkXMLDataReader::MapStringToInt64 : public std::map<std::string, vtkTypeInt64>
{
};
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
vtkXMLDataReader::vtkXMLDataReader() vtkXMLDataReader::vtkXMLDataReader()
: PointDataTimeStep(new vtkXMLDataReader::MapStringToInt())
, PointDataOffset(new vtkXMLDataReader::MapStringToInt64())
, CellDataTimeStep(new vtkXMLDataReader::MapStringToInt())
, CellDataOffset(new vtkXMLDataReader::MapStringToInt64())
{ {
this->NumberOfPieces = 0; this->NumberOfPieces = 0;
this->PointDataElements = nullptr; this->PointDataElements = nullptr;
...@@ -47,11 +58,6 @@ vtkXMLDataReader::vtkXMLDataReader() ...@@ -47,11 +58,6 @@ vtkXMLDataReader::vtkXMLDataReader()
this->DataProgressObserver = vtkCallbackCommand::New(); this->DataProgressObserver = vtkCallbackCommand::New();
this->DataProgressObserver->SetCallback(&vtkXMLDataReader::DataProgressCallbackFunction); this->DataProgressObserver->SetCallback(&vtkXMLDataReader::DataProgressCallbackFunction);
this->DataProgressObserver->SetClientData(this); this->DataProgressObserver->SetClientData(this);
this->PointDataTimeStep = nullptr;
this->PointDataOffset = nullptr;
this->CellDataTimeStep = nullptr;
this->CellDataOffset = nullptr;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -66,16 +72,6 @@ vtkXMLDataReader::~vtkXMLDataReader() ...@@ -66,16 +72,6 @@ vtkXMLDataReader::~vtkXMLDataReader()
this->DestroyPieces(); this->DestroyPieces();
} }
this->DataProgressObserver->Delete(); this->DataProgressObserver->Delete();
if (this->NumberOfPointArrays)
{
delete[] this->PointDataTimeStep;
delete[] this->PointDataOffset;
}
if (this->NumberOfCellArrays)
{
delete[] this->CellDataTimeStep;
delete[] this->CellDataOffset;
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -270,16 +266,21 @@ void vtkXMLDataReader::SetupOutputData() ...@@ -270,16 +266,21 @@ void vtkXMLDataReader::SetupOutputData()
// from one piece because all pieces have the same set of arrays. // from one piece because all pieces have the same set of arrays.
vtkXMLDataElement* ePointData = this->PointDataElements[0]; vtkXMLDataElement* ePointData = this->PointDataElements[0];
vtkXMLDataElement* eCellData = this->CellDataElements[0]; vtkXMLDataElement* eCellData = this->CellDataElements[0];
this->NumberOfPointArrays = 0; this->NumberOfPointArrays = 0;
this->PointDataTimeStep->clear();
this->PointDataOffset->clear();
if (ePointData) if (ePointData)
{ {
for (int i = 0; i < ePointData->GetNumberOfNestedElements(); i++) for (int i = 0; i < ePointData->GetNumberOfNestedElements(); i++)
{ {
vtkXMLDataElement* eNested = ePointData->GetNestedElement(i); vtkXMLDataElement* eNested = ePointData->GetNestedElement(i);
if (this->PointDataArrayIsEnabled(eNested) && const char* ename = eNested->GetAttribute("Name");
!pointData->HasArray(eNested->GetAttribute("Name"))) if (this->PointDataArrayIsEnabled(eNested) && !pointData->HasArray(ename))
{ {
this->NumberOfPointArrays++; this->NumberOfPointArrays++;
(*this->PointDataTimeStep)[ename] = -1;
(*this->PointDataOffset)[ename] = -1;
vtkAbstractArray* array = this->CreateArray(eNested); vtkAbstractArray* array = this->CreateArray(eNested);
if (array) if (array)
{ {
...@@ -294,18 +295,20 @@ void vtkXMLDataReader::SetupOutputData() ...@@ -294,18 +295,20 @@ void vtkXMLDataReader::SetupOutputData()
} }
} }
} }
assert(this->NumberOfPointArrays == this->PointDataArraySelection->GetNumberOfArraysEnabled());
this->NumberOfCellArrays = 0; this->NumberOfCellArrays = 0;
this->CellDataTimeStep->clear();
this->CellDataOffset->clear();
if (eCellData) if (eCellData)
{ {
for (int i = 0; i < eCellData->GetNumberOfNestedElements(); i++) for (int i = 0; i < eCellData->GetNumberOfNestedElements(); i++)
{ {
vtkXMLDataElement* eNested = eCellData->GetNestedElement(i); vtkXMLDataElement* eNested = eCellData->GetNestedElement(i);
if (this->CellDataArrayIsEnabled(eNested) && const char* ename = eNested->GetAttribute("Name");
!cellData->HasArray(eNested->GetAttribute("Name"))) if (this->CellDataArrayIsEnabled(eNested) && !cellData->HasArray(ename))
{ {
this->NumberOfCellArrays++; this->NumberOfCellArrays++;
(*this->CellDataTimeStep)[ename] = -1;
(*this->CellDataOffset)[ename] = -1;
vtkAbstractArray* array = this->CreateArray(eNested); vtkAbstractArray* array = this->CreateArray(eNested);
if (array) if (array)
{ {
...@@ -320,41 +323,10 @@ void vtkXMLDataReader::SetupOutputData() ...@@ -320,41 +323,10 @@ void vtkXMLDataReader::SetupOutputData()
} }
} }
} }
assert(this->NumberOfCellArrays == this->CellDataArraySelection->GetNumberOfArraysEnabled());
// Setup attribute indices for the point data and cell data. // Setup attribute indices for the point data and cell data.
this->ReadAttributeIndices(ePointData, pointData); this->ReadAttributeIndices(ePointData, pointData);
this->ReadAttributeIndices(eCellData, cellData); this->ReadAttributeIndices(eCellData, cellData);
// Since NumberOfCellArrays and NumberOfPointArrays are valid
// lets allocate PointDataTimeStep, CellDataTimeStep, PointDataOffset
// CellDataOffset
if (this->NumberOfPointArrays)
{
delete [] this->PointDataTimeStep;
delete [] this->PointDataOffset;
this->PointDataTimeStep = new int[this->NumberOfPointArrays];
this->PointDataOffset = new vtkTypeInt64[this->NumberOfPointArrays];
for (int i = 0; i < this->NumberOfPointArrays; i++)
{
this->PointDataTimeStep[i] = -1;
this->PointDataOffset[i] = -1;
}
}
if (this->NumberOfCellArrays)
{
delete [] this->CellDataTimeStep;
delete [] this->CellDataOffset;
this->CellDataTimeStep = new int[this->NumberOfCellArrays];
this->CellDataOffset = new vtkTypeInt64[this->NumberOfCellArrays];
for (int i = 0; i < this->NumberOfCellArrays; i++)
{
this->CellDataTimeStep[i] = -1;
this->CellDataOffset[i] = -1;
}
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -579,7 +551,6 @@ int vtkXMLDataReader::PointDataNeedToReadTimeStep(vtkXMLDataElement *eNested) ...@@ -579,7 +551,6 @@ int vtkXMLDataReader::PointDataNeedToReadTimeStep(vtkXMLDataElement *eNested)
{ {
// First thing need to find the id of this dataarray from its name: // First thing need to find the id of this dataarray from its name:
const char* name = eNested->GetAttribute("Name"); const char* name = eNested->GetAttribute("Name");
int idx = this->PointDataArraySelection->GetEnabledArrayIndex(name);
// Easy case no timestep: // Easy case no timestep:
int numTimeSteps = eNested->GetVectorAttribute("TimeStep", int numTimeSteps = eNested->GetVectorAttribute("TimeStep",
...@@ -592,7 +563,7 @@ int vtkXMLDataReader::PointDataNeedToReadTimeStep(vtkXMLDataElement *eNested) ...@@ -592,7 +563,7 @@ int vtkXMLDataReader::PointDataNeedToReadTimeStep(vtkXMLDataElement *eNested)
} }
if (!numTimeSteps && !this->NumberOfTimeSteps) if (!numTimeSteps && !this->NumberOfTimeSteps)
{ {
assert(this->PointDataTimeStep[idx] == -1); //No timestep in this file assert(this->PointDataTimeStep->at(name) == -1); // No timestep in this file
return 1; return 1;
} }
// else TimeStep was specified but no TimeValues associated were found // else TimeStep was specified but no TimeValues associated were found
...@@ -611,11 +582,11 @@ int vtkXMLDataReader::PointDataNeedToReadTimeStep(vtkXMLDataElement *eNested) ...@@ -611,11 +582,11 @@ int vtkXMLDataReader::PointDataNeedToReadTimeStep(vtkXMLDataElement *eNested)
vtkTypeInt64 offset; vtkTypeInt64 offset;
if (eNested->GetScalarAttribute("offset", offset)) if (eNested->GetScalarAttribute("offset", offset))
{ {
if (this->PointDataOffset[idx] != offset) if (this->PointDataOffset->at(name) != offset)
{ {
// save the pointsOffset // save the pointsOffset
assert(this->PointDataTimeStep[idx] == -1); //cannot have mixture of binary and appended assert(this->PointDataTimeStep->at(name) == -1); // cannot have mixture of binary and appended
this->PointDataOffset[idx] = offset; this->PointDataOffset->at(name) = offset;
return 1; return 1;
} }
} }
...@@ -623,20 +594,20 @@ int vtkXMLDataReader::PointDataNeedToReadTimeStep(vtkXMLDataElement *eNested) ...@@ -623,20 +594,20 @@ int vtkXMLDataReader::PointDataNeedToReadTimeStep(vtkXMLDataElement *eNested)
{ {
// No offset is specified this is a binary file // No offset is specified this is a binary file
// First thing to check if numTimeSteps == 0: // First thing to check if numTimeSteps == 0:
if (!numTimeSteps && this->NumberOfTimeSteps && this->PointDataTimeStep[idx] == -1) if (!numTimeSteps && this->NumberOfTimeSteps && this->PointDataTimeStep->at(name) == -1)
{ {
// Update last PointsTimeStep read // Update last PointsTimeStep read
this->PointDataTimeStep[idx] = this->CurrentTimeStep; (*this->PointDataTimeStep)[name] = this->CurrentTimeStep;
return 1; return 1;
} }
int isLastTimeInArray = vtkXMLReader::IsTimeStepInArray( int isLastTimeInArray = vtkXMLReader::IsTimeStepInArray(
this->PointDataTimeStep[idx], this->TimeSteps, numTimeSteps); this->PointDataTimeStep->at(name), this->TimeSteps, numTimeSteps);
// If no time is specified or if time is specified and match then read // If no time is specified or if time is specified and match then read
if (isCurrentTimeInArray && !isLastTimeInArray) if (isCurrentTimeInArray && !isLastTimeInArray)
{ {
// CurrentTimeStep is in TimeSteps but Last is not := need to read // CurrentTimeStep is in TimeSteps but Last is not := need to read
// Update last PointsTimeStep read // Update last PointsTimeStep read
this->PointDataTimeStep[idx] = this->CurrentTimeStep; this->PointDataTimeStep->at(name) = this->CurrentTimeStep;
return 1; return 1;
} }
} }
...@@ -649,7 +620,6 @@ int vtkXMLDataReader::CellDataNeedToReadTimeStep(vtkXMLDataElement *eNested) ...@@ -649,7 +620,6 @@ int vtkXMLDataReader::CellDataNeedToReadTimeStep(vtkXMLDataElement *eNested)
{ {
// First thing need to find the id of this dataarray from its name: // First thing need to find the id of this dataarray from its name:
const char* name = eNested->GetAttribute("Name"); const char* name = eNested->GetAttribute("Name");
int idx = this->CellDataArraySelection->GetEnabledArrayIndex(name);
// Easy case no timestep: // Easy case no timestep:
int numTimeSteps = eNested->GetVectorAttribute("TimeStep", int numTimeSteps = eNested->GetVectorAttribute("TimeStep",
...@@ -662,7 +632,7 @@ int vtkXMLDataReader::CellDataNeedToReadTimeStep(vtkXMLDataElement *eNested) ...@@ -662,7 +632,7 @@ int vtkXMLDataReader::CellDataNeedToReadTimeStep(vtkXMLDataElement *eNested)
} }
if (!numTimeSteps && !this->NumberOfTimeSteps) if (!numTimeSteps && !this->NumberOfTimeSteps)
{ {
assert(this->CellDataTimeStep[idx] == -1); //No timestep in this file assert(this->CellDataTimeStep->at(name) == -1); // No timestep in this file
return 1; return 1;
} }
// else TimeStep was specified but no TimeValues associated were found // else TimeStep was specified but no TimeValues associated were found
...@@ -681,11 +651,11 @@ int vtkXMLDataReader::CellDataNeedToReadTimeStep(vtkXMLDataElement *eNested) ...@@ -681,11 +651,11 @@ int vtkXMLDataReader::CellDataNeedToReadTimeStep(vtkXMLDataElement *eNested)
vtkTypeInt64 offset; vtkTypeInt64 offset;
if (eNested->GetScalarAttribute("offset", offset)) if (eNested->GetScalarAttribute("offset", offset))
{ {
if (this->CellDataOffset[idx] != offset) if (this->CellDataOffset->at(name) != offset)
{ {
// save the pointsOffset // save the pointsOffset
assert(this->CellDataTimeStep[idx] == -1); //cannot have mixture of binary and appended assert(this->CellDataTimeStep->at(name) == -1); // cannot have mixture of binary and appended
this->CellDataOffset[idx] = offset; this->CellDataOffset->at(name) = offset;
return 1; return 1;
} }
} }
...@@ -693,20 +663,20 @@ int vtkXMLDataReader::CellDataNeedToReadTimeStep(vtkXMLDataElement *eNested) ...@@ -693,20 +663,20 @@ int vtkXMLDataReader::CellDataNeedToReadTimeStep(vtkXMLDataElement *eNested)
{ {
// No offset is specified this is a binary file // No offset is specified this is a binary file
// First thing to check if numTimeSteps == 0: // First thing to check if numTimeSteps == 0:
if (!numTimeSteps && this->NumberOfTimeSteps && this->CellDataTimeStep[idx] == -1) if (!numTimeSteps && this->NumberOfTimeSteps && this->CellDataTimeStep->at(name) == -1)
{ {
// Update last CellDataTimeStep read // Update last CellDataTimeStep read
this->CellDataTimeStep[idx] = this->CurrentTimeStep; this->CellDataTimeStep->at(name) = this->CurrentTimeStep;
return 1; return 1;
} }
int isLastTimeInArray = vtkXMLReader::IsTimeStepInArray( int isLastTimeInArray = vtkXMLReader::IsTimeStepInArray(
this->CellDataTimeStep[idx], this->TimeSteps, numTimeSteps); this->CellDataTimeStep->at(name), this->TimeSteps, numTimeSteps);
// If no time is specified or if time is specified and match then read // If no time is specified or if time is specified and match then read
if (isCurrentTimeInArray && !isLastTimeInArray) if (isCurrentTimeInArray && !isLastTimeInArray)
{ {
// CurrentTimeStep is in TimeSteps but Last is not := need to read // CurrentTimeStep is in TimeSteps but Last is not := need to read
// Update last CellsTimeStep read // Update last CellsTimeStep read
this->CellDataTimeStep[idx] = this->CurrentTimeStep; this->CellDataTimeStep->at(name) = this->CurrentTimeStep;
return 1; return 1;
} }
} }
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include "vtkIOXMLModule.h" // For export macro #include "vtkIOXMLModule.h" // For export macro
#include "vtkXMLReader.h" #include "vtkXMLReader.h"
#include <memory> // for std::unique_ptr
class VTKIOXML_EXPORT vtkXMLDataReader : public vtkXMLReader class VTKIOXML_EXPORT vtkXMLDataReader : public vtkXMLReader
{ {
public: public:
...@@ -108,25 +110,27 @@ protected: ...@@ -108,25 +110,27 @@ protected:
// The observer to report progress from reading data from XMLParser. // The observer to report progress from reading data from XMLParser.
vtkCallbackCommand* DataProgressObserver; vtkCallbackCommand* DataProgressObserver;
private:
class MapStringToInt;
class MapStringToInt64;
// Specify the last time step read, useful to know if we need to rearead data // Specify the last time step read, useful to know if we need to rearead data
// //PointData // //PointData
int *PointDataTimeStep; std::unique_ptr<MapStringToInt> PointDataTimeStep;
vtkTypeInt64 *PointDataOffset; std::unique_ptr<MapStringToInt64> PointDataOffset;
int PointDataNeedToReadTimeStep(vtkXMLDataElement *eNested); int PointDataNeedToReadTimeStep(vtkXMLDataElement *eNested);
//CellData //CellData
int *CellDataTimeStep; std::unique_ptr<MapStringToInt> CellDataTimeStep;
vtkTypeInt64 *CellDataOffset; std::unique_ptr<MapStringToInt64> CellDataOffset;
int CellDataNeedToReadTimeStep(vtkXMLDataElement *eNested); int CellDataNeedToReadTimeStep(vtkXMLDataElement *eNested);
private:
vtkXMLDataReader(const vtkXMLDataReader&) = delete; vtkXMLDataReader(const vtkXMLDataReader&) = delete;
void operator=(const vtkXMLDataReader&) = delete; void operator=(const vtkXMLDataReader&) = delete;
void ConvertGhostLevelsToGhostType( void ConvertGhostLevelsToGhostType(
FieldType type, vtkAbstractArray* data, vtkIdType startIndex, FieldType type, vtkAbstractArray* data, vtkIdType startIndex,
vtkIdType numValues) override; vtkIdType numValues) override;
}; };
#endif #endif
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