Skip to content
Snippets Groups Projects
Commit 5b502262 authored by Cory Quammen's avatar Cory Quammen
Browse files

vtkXMLMultiBlockDataReader: fix when reading nested multipiece datasets

When a vtkMultiBlockDataSet contains a vtkMultiPieceDataSet,
vtkXMLPMultiBlockDataWriter will split each piece into another
vtkMultiPieceDataSet. As a result, the written XML data file will
contain nested "Piece" elements. Since vtkMultiPieceDataSets are not
hierarchical, this dataset cannot be recreated as described.

To fix, have the reader replace the top-level vtkMultiPieceDataSet
with a vtkMultiBlockDataSet instead when nested Piece elements are
found.

Modified test to exercise writing out a vtkMultiPieceDataSet block and
read it back in.
parent d2310987
No related branches found
No related tags found
No related merge requests found
......@@ -43,6 +43,13 @@ else:
# | |-- [0,1,..nranks](0,1,...nranks)
# | |-- [0,1,..nranks](0,1,...nranks)
# | ... (up to total number of ranks)
# |
# |-- <MP> # level where a multipiece dataset is present on all ranks
# | |
# | |-- [0,1,..nranks](0,1,...nranks)
# | |-- [0,1,..nranks](0,1,...nranks)
# | |-- [0,1,..nranks](0,1,...nranks)
# | ... (up to total number of ranks)
def createDataSet(empty):
......@@ -62,12 +69,20 @@ def createData(non_null_ranks, non_empty_ranks, num_ranks):
mb.SetBlock(i, createDataSet(i not in non_empty_ranks))
return mb
def createMP(num_pieces):
mp = vtk.vtkMultiPieceDataSet()
mp.SetNumberOfPieces(num_pieces)
for i in range(num_pieces):
mp.SetPiece(i, createDataSet(False))
return mp
def createMB(piece, num_pieces):
output = vtk.vtkMultiBlockDataSet()
output.SetNumberOfBlocks(3)
output.SetNumberOfBlocks(4)
output.SetBlock(0, createData([piece], [piece], num_pieces))
output.SetBlock(1, createData(range(num_pieces), [piece], num_pieces))
output.SetBlock(2, createData(range(num_pieces), range(num_pieces), num_pieces))
output.SetBlock(3, createMP(num_pieces))
return output
writer = vtk.vtkXMLPMultiBlockDataWriter()
......@@ -104,6 +119,6 @@ if rank == 0:
# set of files, let's just look at the files we wrote out.
files = os.listdir(prefix)
expected_file_count = nranks + nranks + (nranks*nranks)
expected_file_count = nranks + nranks + 2*(nranks*nranks)
print ("Expecting %d files for the leaf nodes" % expected_file_count)
assert (len(files) == expected_file_count)
......@@ -172,7 +172,20 @@ void vtkXMLMultiBlockDataReader::ReadComposite(vtkXMLDataElement* element,
// Child is a multipiece dataset. Create it.
else if (mblock != nullptr && strcmp(tagName, "Piece") == 0)
{
vtkMultiPieceDataSet* childDS = vtkMultiPieceDataSet::New();
// Look ahead to see if there is a nested Piece structure, which can happen when
// the dataset pieces in a vtkMultiPieceDataSet are themselves split into
// vtkMultiPieceDataSets when saved in parallel.
vtkCompositeDataSet* childDS;
if (childXML->FindNestedElementWithName("Piece"))
{
// Create a multiblock to handle a multipiece child
childDS = vtkMultiBlockDataSet::New();
}
else
{
// Child is not multipiece, so it is safe to create a vtkMultiPieceDataSet
childDS = vtkMultiPieceDataSet::New();
}
this->ReadComposite(childXML, childDS, filePath, dataSetIndex);
const char* name = childXML->GetAttribute("name");
mblock->SetBlock(index, childDS);
......@@ -284,7 +297,21 @@ int vtkXMLMultiBlockDataReader::FillMetaData(vtkCompositeDataSet* metadata,
// Child is a multipiece dataset. Create it.
else if (mblock != nullptr && strcmp(tagName, "Piece") == 0)
{
vtkMultiPieceDataSet* childDS = vtkMultiPieceDataSet::New();
// Look ahead to see if there is a nested Piece structure, which can happen when
// the dataset pieces in a vtkMultiPieceDataSet are themselves split into
// vtkMultiPieceDataSets when saved in parallel.
vtkCompositeDataSet* childDS;
if (childXML->FindNestedElementWithName("Piece"))
{
// Create a multiblock to handle a multipiece child
childDS = vtkMultiBlockDataSet::New();
}
else
{
// Child is not multipiece, so it is safe to create a vtkMultiPieceDataSet
childDS = vtkMultiPieceDataSet::New();
}
this->FillMetaData(childDS, childXML, filePath, dataSetIndex);
mblock->SetBlock(index, childDS);
childDS->Delete();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment