vtkXMLUnstructuredGridReader.cxx 13.5 KB
Newer Older
1 2 3 4 5
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkXMLUnstructuredGridReader.cxx

6
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 8 9
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

10 11
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 13 14 15
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkXMLUnstructuredGridReader.h"
16 17

#include "vtkCellArray.h"
18
#include "vtkIdTypeArray.h"
19 20
#include "vtkObjectFactory.h"
#include "vtkUnsignedCharArray.h"
21 22
#include "vtkUnstructuredGrid.h"
#include "vtkXMLDataElement.h"
23 24
#include "vtkInformation.h"
#include "vtkStreamingDemandDrivenPipeline.h"
25

26
#include <cassert>
27

28 29 30 31 32 33
vtkStandardNewMacro(vtkXMLUnstructuredGridReader);

//----------------------------------------------------------------------------
vtkXMLUnstructuredGridReader::vtkXMLUnstructuredGridReader()
{
  this->CellElements = 0;
34
  this->NumberOfCells = 0;
35
  this->CellsTimeStep = -1;
Francois Bertel's avatar
Francois Bertel committed
36
  this->CellsOffset   = static_cast<unsigned long>(-1); // almost invalid state
37 38 39 40 41
}

//----------------------------------------------------------------------------
vtkXMLUnstructuredGridReader::~vtkXMLUnstructuredGridReader()
{
42 43 44 45
  if(this->NumberOfPieces)
    {
    this->DestroyPieces();
    }
46 47 48 49 50 51 52 53 54 55 56
}

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

//----------------------------------------------------------------------------
vtkUnstructuredGrid* vtkXMLUnstructuredGridReader::GetOutput()
{
57
  return this->GetOutput(0);
58 59
}

60 61 62
//----------------------------------------------------------------------------
vtkUnstructuredGrid* vtkXMLUnstructuredGridReader::GetOutput(int idx)
{
63
  return vtkUnstructuredGrid::SafeDownCast( this->GetOutputDataObject(idx) );
64 65
}

66 67 68 69 70 71 72 73 74 75 76
//----------------------------------------------------------------------------
const char* vtkXMLUnstructuredGridReader::GetDataSetName()
{
  return "UnstructuredGrid";
}

//----------------------------------------------------------------------------
void vtkXMLUnstructuredGridReader::GetOutputUpdateExtent(int& piece,
                                                         int& numberOfPieces,
                                                         int& ghostLevel)
{
77 78 79 80 81 82 83
  vtkInformation* outInfo = this->GetCurrentOutputInformation();
  piece = outInfo->Get(
      vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
  numberOfPieces = outInfo->Get(
      vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
  ghostLevel = outInfo->Get(
      vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
84 85 86 87 88 89 90 91 92 93 94 95 96
}

//----------------------------------------------------------------------------
void vtkXMLUnstructuredGridReader::SetupOutputTotals()
{
  this->Superclass::SetupOutputTotals();
  // Find the total size of the output.
  int i;
  this->TotalNumberOfCells = 0;
  for(i=this->StartPiece; i < this->EndPiece; ++i)
    {
    this->TotalNumberOfCells += this->NumberOfCells[i];
    }
Mathieu Malaterre's avatar
Mathieu Malaterre committed
97

98 99 100 101 102 103 104 105 106 107
  // Data reading will start at the beginning of the output.
  this->StartCell = 0;
}

//----------------------------------------------------------------------------
void vtkXMLUnstructuredGridReader::SetupPieces(int numPieces)
{
  this->Superclass::SetupPieces(numPieces);
  this->NumberOfCells = new vtkIdType[numPieces];
  this->CellElements = new vtkXMLDataElement*[numPieces];
108
  for(int i=0;i < numPieces; ++i)
109 110 111 112 113 114 115 116 117 118 119 120 121
    {
    this->CellElements[i] = 0;
    }
}

//----------------------------------------------------------------------------
void vtkXMLUnstructuredGridReader::DestroyPieces()
{
  delete [] this->CellElements;
  delete [] this->NumberOfCells;
  this->Superclass::DestroyPieces();
}

122 123 124 125 126 127
//----------------------------------------------------------------------------
vtkIdType vtkXMLUnstructuredGridReader::GetNumberOfCellsInPiece(int piece)
{
  return this->NumberOfCells[piece];
}

128 129 130 131
//----------------------------------------------------------------------------
void vtkXMLUnstructuredGridReader::SetupOutputData()
{
  this->Superclass::SetupOutputData();
Mathieu Malaterre's avatar
Mathieu Malaterre committed
132

133 134
  vtkUnstructuredGrid* output = vtkUnstructuredGrid::SafeDownCast(
      this->GetCurrentOutput());
Mathieu Malaterre's avatar
Mathieu Malaterre committed
135

136 137 138 139
  // Setup the output's cell arrays.
  vtkUnsignedCharArray* cellTypes = vtkUnsignedCharArray::New();
  cellTypes->SetNumberOfTuples(this->GetNumberOfCells());
  vtkCellArray* outCells = vtkCellArray::New();
Mathieu Malaterre's avatar
Mathieu Malaterre committed
140

141
  vtkIdTypeArray* locations = vtkIdTypeArray::New();
142
  locations->SetNumberOfTuples(this->GetNumberOfCells());
Mathieu Malaterre's avatar
Mathieu Malaterre committed
143

144
  output->SetCells(cellTypes, locations, outCells);
Mathieu Malaterre's avatar
Mathieu Malaterre committed
145

146 147 148 149 150 151 152 153
  locations->Delete();
  outCells->Delete();
  cellTypes->Delete();
}

//----------------------------------------------------------------------------
int vtkXMLUnstructuredGridReader::ReadPiece(vtkXMLDataElement* ePiece)
{
154 155 156 157
  if(!this->Superclass::ReadPiece(ePiece))
    {
    return 0;
    }
158
  int i;
Mathieu Malaterre's avatar
Mathieu Malaterre committed
159

160 161 162 163 164 165 166
  if(!ePiece->GetScalarAttribute("NumberOfCells",
                                 this->NumberOfCells[this->Piece]))
    {
    vtkErrorMacro("Piece " << this->Piece
                  << " is missing its NumberOfCells attribute.");
    this->NumberOfCells[this->Piece] = 0;
    return 0;
Mathieu Malaterre's avatar
Mathieu Malaterre committed
167 168
    }

169 170 171 172 173 174 175 176 177 178 179
  // Find the Cells element in the piece.
  this->CellElements[this->Piece] = 0;
  for(i=0; i < ePiece->GetNumberOfNestedElements(); ++i)
    {
    vtkXMLDataElement* eNested = ePiece->GetNestedElement(i);
    if((strcmp(eNested->GetName(), "Cells") == 0)
       && (eNested->GetNumberOfNestedElements() > 0))
      {
      this->CellElements[this->Piece] = eNested;
      }
    }
Mathieu Malaterre's avatar
Mathieu Malaterre committed
180

181 182 183 184 185
  if(!this->CellElements[this->Piece])
    {
    vtkErrorMacro("A piece is missing its Cells element.");
    return 0;
    }
Mathieu Malaterre's avatar
Mathieu Malaterre committed
186

187 188 189 190 191 192
  return 1;
}

//----------------------------------------------------------------------------
void vtkXMLUnstructuredGridReader::SetupNextPiece()
{
Mathieu Malaterre's avatar
Mathieu Malaterre committed
193
  this->Superclass::SetupNextPiece();
194 195 196
  this->StartCell += this->NumberOfCells[this->Piece];
}

197

198 199 200
//----------------------------------------------------------------------------
int vtkXMLUnstructuredGridReader::ReadPieceData()
{
201 202 203 204 205 206
  // The amount of data read by the superclass's ReadPieceData comes
  // from point/cell data and point specifications (we read cell
  // specifications here).
  vtkIdType superclassPieceSize =
    ((this->NumberOfPointArrays+1)*this->GetNumberOfPointsInPiece(this->Piece)+
     this->NumberOfCellArrays*this->GetNumberOfCellsInPiece(this->Piece));
Mathieu Malaterre's avatar
Mathieu Malaterre committed
207

208
  // Total amount of data in this piece comes from cell/face data arrays.
209
  // Three of them are for standard vtkUnstructuredGrid cell specification:
210 211
  // connectivities, offsets and types. Two optional arrays are for face
  // specification of polyhedron cells: faces and face offsets.
212
  // Note: We don't know exactly the array size of cell connectivities and
213
  // faces until we actually read the file. The following progress computation
214
  // assumes that each array cost the same time to read.
215
  vtkIdType totalPieceSize =
216
    superclassPieceSize + 5*this->GetNumberOfCellsInPiece(this->Piece);
217 218 219 220 221 222 223 224 225 226 227
  if(totalPieceSize == 0)
    {
    totalPieceSize = 1;
    }

  // Split the progress range based on the approximate fraction of
  // data that will be read by each step in this method.  The cell
  // specification reads two arrays, and then the cell types array is
  // one more.
  float progressRange[2] = {0,0};
  this->GetProgressRange(progressRange);
228
  float fractions[5] =
229 230 231 232 233
    {
      0,
      float(superclassPieceSize) / totalPieceSize,
      ((float(superclassPieceSize) +
        2*this->GetNumberOfCellsInPiece(this->Piece)) / totalPieceSize),
234 235
      ((float(superclassPieceSize) +
        3*this->GetNumberOfCellsInPiece(this->Piece)) / totalPieceSize),
236 237
      1
    };
Mathieu Malaterre's avatar
Mathieu Malaterre committed
238

239 240
  // Set the range of progress for the superclass.
  this->SetProgressRange(progressRange, 0, fractions);
Mathieu Malaterre's avatar
Mathieu Malaterre committed
241

242
  // Let the superclass read its data.
243 244 245 246
  if(!this->Superclass::ReadPieceData())
    {
    return 0;
    }
Mathieu Malaterre's avatar
Mathieu Malaterre committed
247

248 249
  vtkUnstructuredGrid* output = vtkUnstructuredGrid::SafeDownCast(
      this->GetCurrentOutput());
Mathieu Malaterre's avatar
Mathieu Malaterre committed
250

251 252
  // Set the range of progress for the cell specifications.
  this->SetProgressRange(progressRange, 1, fractions);
Mathieu Malaterre's avatar
Mathieu Malaterre committed
253

254
  // Read the Cells.
255
  vtkXMLDataElement* eCells = this->CellElements[this->Piece];
256
  if(!eCells)
257
    {
258 259 260
    vtkErrorMacro("Cannot find cell arrays in piece " << this->Piece);
    return 0;
    }
261

262 263 264 265 266 267 268 269 270
//  int needToRead = this->CellsNeedToReadTimeStep(eNested,
//    this->CellsTimeStep, this->CellsOffset);
//  if( needToRead )
  {
    // Read the array.
    if(!this->ReadCellArray(this->NumberOfCells[this->Piece],
                            this->TotalNumberOfCells,
                            eCells,
                            output->GetCells()))
271
      {
272
      return 0;
273
      }
274
  }
Mathieu Malaterre's avatar
Mathieu Malaterre committed
275

276
  // Construct the cell locations.
277 278
  vtkIdTypeArray* locations = output->GetCellLocationsArray();
  vtkIdType* locs = locations->GetPointer(this->StartCell);
279 280 281 282 283 284
  vtkIdTypeArray* cellArrayData = output->GetCells()->GetData();
  vtkIdType startLoc = 0;
  if (this->StartCell > 0)
    {
    // this set the startLoc to point to the location in the cellArray where the
    // cell for this piece will start writing.
285 286 287 288 289 290 291 292

    // Id for last written cell:
    vtkIdType lastWrittenCell = this->StartCell - 1;
    vtkIdType locationOfLastWrittenCell = locations->GetValue(lastWrittenCell);
    startLoc = locationOfLastWrittenCell + 1 +
      cellArrayData->GetValue(locationOfLastWrittenCell);
    // startLoc = location-of-last-written-cell + 1 (for put the count for items in the cell)
    //            + (number of items in the cell).
293
    }
294 295 296 297 298 299 300 301
  vtkIdType* begin = output->GetCells()->GetData()->GetPointer(startLoc);
  vtkIdType* cur = begin;
  vtkIdType i;
  for(i=0; i < this->NumberOfCells[this->Piece]; ++i)
    {
    locs[i] = startLoc + cur - begin;
    cur += *cur + 1;
    }
Mathieu Malaterre's avatar
Mathieu Malaterre committed
302

303 304
  // Set the range of progress for the cell types.
  this->SetProgressRange(progressRange, 2, fractions);
Mathieu Malaterre's avatar
Mathieu Malaterre committed
305

306
  // Read the corresponding cell types.
307
  vtkIdType numberOfCells = this->NumberOfCells[this->Piece];
308
  if (numberOfCells > 0)
309
    {
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
    vtkXMLDataElement* eTypes = this->FindDataArrayWithName(eCells, "types");
    if(!eTypes)
      {
      vtkErrorMacro("Cannot read cell types from " << eCells->GetName()
                    << " in piece " << this->Piece
                    << " because the \"types\" array could not be found.");
      return 0;
      }
    vtkAbstractArray* ac2 = this->CreateArray(eTypes);
    vtkDataArray* c2 = vtkDataArray::SafeDownCast(ac2);
    if(!c2 || (c2->GetNumberOfComponents() != 1))
      {
      vtkErrorMacro("Cannot read cell types from " << eCells->GetName()
                    << " in piece " << this->Piece
                    << " because the \"types\" array could not be created"
                    << " with one component.");
      if (ac2) { ac2->Delete(); }
      return 0;
      }
    c2->SetNumberOfTuples(numberOfCells);
    if(!this->ReadArrayValues(eTypes, 0, c2, 0, numberOfCells))
      {
      vtkErrorMacro("Cannot read cell types from " << eCells->GetName()
                    << " in piece " << this->Piece
                    << " because the \"types\" array is not long enough.");
      return 0;
      }
    vtkUnsignedCharArray* cellTypes = this->ConvertToUnsignedCharArray(c2);
    if(!cellTypes)
      {
      vtkErrorMacro("Cannot read cell types from " << eCells->GetName()
                    << " in piece " << this->Piece
                    << " because the \"types\" array could not be converted"
                    << " to a vtkUnsignedCharArray.");
      return 0;
      }
Mathieu Malaterre's avatar
Mathieu Malaterre committed
346

347 348 349
    // Copy the cell type data.
    memcpy(output->GetCellTypesArray()->GetPointer(this->StartCell),
           cellTypes->GetPointer(0), numberOfCells);
Mathieu Malaterre's avatar
Mathieu Malaterre committed
350

351 352
    cellTypes->Delete();
    }
Mathieu Malaterre's avatar
Mathieu Malaterre committed
353

354 355 356 357 358 359 360 361 362 363 364
  // Set the range of progress for the faces.
  this->SetProgressRange(progressRange, 3, fractions);

  //
  // Read face array. Used for polyhedron mesh support.
  // First need to check if faces and faceoffsets arrays are available.
  if (!this->FindDataArrayWithName(eCells, "faces") ||
      !this->FindDataArrayWithName(eCells, "faceoffsets"))
    {
    return 1;
    }
365

366
  // By default vtkUnstructuredGrid does not contain face information, which is
367 368 369
  // only used by polyhedron cells. If so far no polyhedron cells have been
  // added, the pointers to the arrays will be NULL. In this case, we need to
  // initialize the arrays and assign values to the previous non-polyhedron cells.
370 371 372 373
  if (!output->GetFaces() || !output->GetFaceLocations())
    {
    output->InitializeFacesRepresentation(this->StartCell);
    }
374

375 376 377 378 379 380 381 382 383
  // Read face arrays.
  if(!this->ReadFaceArray(this->NumberOfCells[this->Piece],
                          eCells,
                          output->GetFaces(),
                          output->GetFaceLocations()))
    {
    return 0;
    }

384 385 386 387 388
  return 1;
}

//----------------------------------------------------------------------------
int vtkXMLUnstructuredGridReader::ReadArrayForCells(vtkXMLDataElement* da,
Utkarsh Ayachit's avatar
ENH:  
Utkarsh Ayachit committed
389
                                                    vtkAbstractArray* outArray)
390 391
{
  vtkIdType startCell = this->StartCell;
Mathieu Malaterre's avatar
Mathieu Malaterre committed
392
  vtkIdType numCells = this->NumberOfCells[this->Piece];
393
  vtkIdType components = outArray->GetNumberOfComponents();
Utkarsh Ayachit's avatar
ENH:  
Utkarsh Ayachit committed
394 395
  return this->ReadArrayValues(da, startCell*components, outArray,
    0, numCells*components);
396
}
397 398


399
//----------------------------------------------------------------------------
400
int vtkXMLUnstructuredGridReader::FillOutputPortInformation(int, vtkInformation *info)
401
{
402 403
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkUnstructuredGrid");
  return 1;
404
}
405 406