vtkXMLMultiBlockDataReader.cxx 10.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*=========================================================================

  Program:   ParaView
  Module:    vtkXMLMultiBlockDataReader.cxx

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 "vtkXMLMultiBlockDataReader.h"

17
#include "vtkCompositeDataSet.h"
18
#include "vtkCompositeDataPipeline.h"
19
#include "vtkDataArraySelection.h"
20
#include "vtkDataSet.h"
21
#include "vtkInformation.h"
22
#include "vtkInformationVector.h"
23
#include "vtkMultiBlockDataSet.h"
Burlen Loring's avatar
ENH:  
Burlen Loring committed
24
#include "vtkMultiPieceDataSet.h"
25
#include "vtkObjectFactory.h"
26 27
#include "vtkSmartPointer.h"
#include "vtkXMLDataElement.h"
28 29 30 31

vtkStandardNewMacro(vtkXMLMultiBlockDataReader);

//----------------------------------------------------------------------------
32
vtkXMLMultiBlockDataReader::vtkXMLMultiBlockDataReader() = default;
33 34

//----------------------------------------------------------------------------
35
vtkXMLMultiBlockDataReader::~vtkXMLMultiBlockDataReader() = default;
36 37 38 39 40 41 42 43 44 45 46

//----------------------------------------------------------------------------
void vtkXMLMultiBlockDataReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}

//----------------------------------------------------------------------------
int vtkXMLMultiBlockDataReader::FillOutputPortInformation(
  int vtkNotUsed(port), vtkInformation* info)
{
47
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
48 49 50 51 52 53 54 55 56
  return 1;
}

//----------------------------------------------------------------------------
const char* vtkXMLMultiBlockDataReader::GetDataSetName()
{
  return "vtkMultiBlockDataSet";
}

57 58 59
//----------------------------------------------------------------------------
// This version does not support multiblock of multiblocks, so our work is
// simple.
60 61
void vtkXMLMultiBlockDataReader::ReadVersion0(vtkXMLDataElement* element,
  vtkCompositeDataSet* composite, const char* filePath,
62 63 64 65 66
  unsigned int &dataSetIndex)
{
  vtkMultiBlockDataSet* mblock = vtkMultiBlockDataSet::SafeDownCast(composite);
  unsigned int numElems = element->GetNumberOfNestedElements();
  for (unsigned int cc=0; cc < numElems; ++cc)
67
  {
68
    vtkXMLDataElement* childXML = element->GetNestedElement(cc);
69
    if (!childXML || !childXML->GetName() ||
70
      strcmp(childXML->GetName(), "DataSet") != 0)
71
    {
72
      continue;
73
    }
74 75 76 77
    int group = 0;
    int index = 0;
    if (childXML->GetScalarAttribute("group", group) &&
      childXML->GetScalarAttribute("dataset", index))
78
    {
79 80
      vtkSmartPointer<vtkDataSet> dataset;
      if (this->ShouldReadDataSet(dataSetIndex))
81
      {
82
        dataset.TakeReference(this->ReadDataset(childXML, filePath));
83
      }
84 85 86
      vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(
        mblock->GetBlock(group));
      if (!block)
87
      {
88 89 90 91
        block = vtkMultiBlockDataSet::New();
        mblock->SetBlock(group, block);
        block->Delete();
      }
92
      block->SetBlock(index, dataset);
93
    }
94 95
    dataSetIndex++;
  }
96 97 98
}

//----------------------------------------------------------------------------
Burlen Loring's avatar
ENH:  
Burlen Loring committed
99
void vtkXMLMultiBlockDataReader::ReadComposite(vtkXMLDataElement* element,
100
  vtkCompositeDataSet* composite, const char* filePath,
101 102 103
  unsigned int &dataSetIndex)
{
  vtkMultiBlockDataSet* mblock = vtkMultiBlockDataSet::SafeDownCast(composite);
Burlen Loring's avatar
ENH:  
Burlen Loring committed
104 105
  vtkMultiPieceDataSet* mpiece = vtkMultiPieceDataSet::SafeDownCast(composite);
  if (!mblock && !mpiece)
106
  {
luz.paz's avatar
luz.paz committed
107
    vtkErrorMacro("Unsupported composite dataset.");
108
    return;
109
  }
110 111

  if (this->GetFileMajorVersion() < 1)
112
  {
113 114 115
    // Read legacy file.
    this->ReadVersion0(element, composite, filePath, dataSetIndex);
    return;
116
  }
117 118 119

  unsigned int maxElems = element->GetNumberOfNestedElements();
  for (unsigned int cc=0; cc < maxElems; ++cc)
120
  {
121 122
    vtkXMLDataElement* childXML = element->GetNestedElement(cc);
    if (!childXML || !childXML->GetName())
123
    {
124
      continue;
125
    }
126 127 128

    int index = 0;
    if (!childXML->GetScalarAttribute("index", index))
129
    // if index not in the structure file, then
Burlen Loring's avatar
ENH:  
Burlen Loring committed
130
    // set up to add at the end
131
    {
Burlen Loring's avatar
ENH:  
Burlen Loring committed
132
      if (mblock)
133
      {
Burlen Loring's avatar
ENH:  
Burlen Loring committed
134
        index = mblock->GetNumberOfBlocks();
135
      }
Burlen Loring's avatar
ENH:  
Burlen Loring committed
136
      else if (mpiece)
137
      {
Burlen Loring's avatar
ENH:  
Burlen Loring committed
138
        index = mpiece->GetNumberOfPieces();
139
      }
140
    }
Burlen Loring's avatar
ENH:  
Burlen Loring committed
141
    // child is a leaf node, read and insert.
142 143
    const char* tagName = childXML->GetName();
    if (strcmp(tagName, "DataSet") == 0)
144
    {
145
      vtkSmartPointer<vtkDataObject> childDS;
146
      const char* name = nullptr;
147
      if (this->ShouldReadDataSet(dataSetIndex))
148
      {
Burlen Loring's avatar
ENH:  
Burlen Loring committed
149
        // Read
150
        childDS.TakeReference(this->ReadDataObject(childXML, filePath));
151
        name = childXML->GetAttribute("name");
152
      }
Burlen Loring's avatar
ENH:  
Burlen Loring committed
153 154
      // insert
      if (mblock)
155
      {
Burlen Loring's avatar
ENH:  
Burlen Loring committed
156
        mblock->SetBlock(index, childDS);
157
        mblock->GetMetaData(index)->Set(vtkCompositeDataSet::NAME(), name);
158
      }
Burlen Loring's avatar
ENH:  
Burlen Loring committed
159
      else if (mpiece)
160
      {
Burlen Loring's avatar
ENH:  
Burlen Loring committed
161
        mpiece->SetPiece(index, childDS);
162
        mpiece->GetMetaData(index)->Set(vtkCompositeDataSet::NAME(), name);
163
      }
164 165
      dataSetIndex++;
    }
Burlen Loring's avatar
ENH:  
Burlen Loring committed
166
    // Child is a multiblock dataset itself. Create it.
167
    else if (mblock != nullptr
Burlen Loring's avatar
ENH:  
Burlen Loring committed
168
             && strcmp(tagName, "Block") == 0)
169
    {
170
      vtkMultiBlockDataSet* childDS = vtkMultiBlockDataSet::New();
171
      this->ReadComposite(childXML, childDS, filePath, dataSetIndex);
172
      const char* name = childXML->GetAttribute("name");
173
      mblock->SetBlock(index, childDS);
174
      mblock->GetMetaData(index)->Set(vtkCompositeDataSet::NAME(), name);
175
      childDS->Delete();
176
    }
Burlen Loring's avatar
ENH:  
Burlen Loring committed
177
    // Child is a multipiece dataset. Create it.
178
    else if (mblock!=nullptr
Burlen Loring's avatar
ENH:  
Burlen Loring committed
179
             && strcmp(tagName, "Piece") == 0)
180
    {
181
      vtkMultiPieceDataSet* childDS = vtkMultiPieceDataSet::New();
Burlen Loring's avatar
ENH:  
Burlen Loring committed
182
      this->ReadComposite(childXML, childDS, filePath, dataSetIndex);
183
      const char* name = childXML->GetAttribute("name");
Burlen Loring's avatar
ENH:  
Burlen Loring committed
184
      mblock->SetBlock(index, childDS);
185
      mblock->GetMetaData(index)->Set(vtkCompositeDataSet::NAME(), name);
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
186
      childDS->Delete();
187
    }
Burlen Loring's avatar
ENH:  
Burlen Loring committed
188
    else
189
    {
Burlen Loring's avatar
ENH:  
Burlen Loring committed
190 191
      vtkErrorMacro("Syntax error in file.");
      return;
192
    }
193
  }
194
}
195 196 197 198 199 200 201

namespace
{
  vtkInformation* CreateMetaDataIfNecessary(vtkMultiBlockDataSet* mblock,
                                            vtkMultiPieceDataSet* mpiece,
                                            int index)
  {
202
    vtkInformation* piece_metadata = nullptr;
203
    if (mblock)
204
    {
205
      mblock->SetBlock(index, nullptr);
206
      piece_metadata = mblock->GetMetaData(index);
207
    }
208
    else if (mpiece)
209
    {
210
      mpiece->SetPiece(index, nullptr);
211
      piece_metadata = mpiece->GetMetaData(index);
212
    }
213 214 215 216 217 218 219 220
    return piece_metadata;
  }

}

//----------------------------------------------------------------------------
int vtkXMLMultiBlockDataReader::FillMetaData(vtkCompositeDataSet* metadata,
                                             vtkXMLDataElement* element,
221
                                             const std::string &filePath,
222 223 224 225 226 227 228
                                             unsigned int &dataSetIndex)
{
  vtkMultiBlockDataSet* mblock = vtkMultiBlockDataSet::SafeDownCast(metadata);
  vtkMultiPieceDataSet* mpiece = vtkMultiPieceDataSet::SafeDownCast(metadata);

  unsigned int maxElems = element->GetNumberOfNestedElements();
  for (unsigned int cc=0; cc < maxElems; ++cc)
229
  {
230 231
    vtkXMLDataElement* childXML = element->GetNestedElement(cc);
    if (!childXML || !childXML->GetName())
232
    {
233
      continue;
234
    }
235 236 237 238 239

    int index = 0;
    if (!childXML->GetScalarAttribute("index", index))
    // if index not in the structure file, then
    // set up to add at the end
240
    {
241
      if (mblock)
242
      {
243
        index = mblock->GetNumberOfBlocks();
244
      }
245
      else if (mpiece)
246
      {
247 248
        index = mpiece->GetNumberOfPieces();
      }
249
    }
250 251 252
    // child is a leaf node, read and insert.
    const char* tagName = childXML->GetName();
    if (strcmp(tagName, "DataSet") == 0)
253
    {
254 255 256
      vtkInformation* piece_metadata = CreateMetaDataIfNecessary(mblock, mpiece, index);
      double bounding_box[6];
      if (childXML->GetVectorAttribute("bounding_box", 6, bounding_box) == 6)
257
      {
258
        if (piece_metadata)
259
        {
260
          piece_metadata->Set(
261
            vtkDataObject::BOUNDING_BOX(),
262 263
            bounding_box, 6);
        }
264
      }
265 266
      int extent[6];
      if (childXML->GetVectorAttribute("extent", 6, extent) == 6)
267
      {
268
        if (piece_metadata)
269
        {
270 271 272 273 274
          piece_metadata->Set(
            vtkDataObject::PIECE_EXTENT(),
            extent, 6);
        }
      }
275 276 277 278
      if (this->ShouldReadDataSet(dataSetIndex))
      {
        this->SyncDataArraySelections(this, childXML, filePath);
      }
279 280
      dataSetIndex++;
    }
281
    // Child is a multiblock dataset itself. Create it.
282
    else if (mblock != nullptr
283
             && strcmp(tagName, "Block") == 0)
284
    {
285
      vtkMultiBlockDataSet* childDS = vtkMultiBlockDataSet::New();
286
      this->FillMetaData(childDS, childXML, filePath, dataSetIndex);
287
      if (mblock)
288
      {
289
        mblock->SetBlock(index, childDS);
290
      }
291
      else if (mpiece)
292
      {
293 294 295
        vtkErrorMacro("Multipiece data can't have composite children.");
        return 0;
      }
296 297
      childDS->Delete();
    }
298
    // Child is a multipiece dataset. Create it.
299
    else if (mblock!=nullptr
300
             && strcmp(tagName, "Piece") == 0)
301
    {
302
      vtkMultiPieceDataSet* childDS = vtkMultiPieceDataSet::New();
303
      this->FillMetaData(childDS, childXML, filePath, dataSetIndex);
304 305 306 307
      mblock->SetBlock(index, childDS);
      childDS->Delete();
      int whole_extent[6];
      if (childXML->GetVectorAttribute("whole_extent", 6, whole_extent) == 6)
308
      {
309 310 311 312 313
        vtkInformation* piece_metadata = mblock->GetMetaData(index);
        piece_metadata->Set(
          vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
          whole_extent, 6);
      }
314
    }
315
    else
316
    {
317 318 319
      vtkErrorMacro("Syntax error in file.");
      return 0;
    }
320
  }
321 322 323 324 325 326 327 328 329 330 331 332
  return 1;
}

//----------------------------------------------------------------------------
int vtkXMLMultiBlockDataReader::RequestInformation(
  vtkInformation *request,
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  this->Superclass::RequestInformation(request, inputVector, outputVector);

  if (this->GetFileMajorVersion() < 1)
333
  {
334
    return 1;
335
  }
336

337
  const std::string filePath = this->GetFilePath();
338 339 340 341
  vtkInformation* info = outputVector->GetInformationObject(0);
  vtkSmartPointer<vtkMultiBlockDataSet> metadata =
    vtkSmartPointer<vtkMultiBlockDataSet>::New();
  unsigned int dataSetIndex = 0;
342
  if (!this->FillMetaData(metadata, this->GetPrimaryElement(), filePath, dataSetIndex))
343
  {
344
    return 0;
345
  }
346 347 348 349 350
  info->Set(vtkCompositeDataPipeline::COMPOSITE_DATA_META_DATA(),
            metadata);

  return 1;
}