vtkXMLPolyDataReader.cxx 16 KB
Newer Older
1 2 3 4 5
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkXMLPolyDataReader.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 16 17 18 19 20 21
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkXMLPolyDataReader.h"
#include "vtkObjectFactory.h"
#include "vtkXMLDataElement.h"
#include "vtkPolyData.h"
#include "vtkIdTypeArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkCellArray.h"
22 23
#include "vtkInformation.h"
#include "vtkStreamingDemandDrivenPipeline.h"
24

25
#include <cassert>
26

27 28 29 30 31 32 33 34 35 36 37 38 39
vtkStandardNewMacro(vtkXMLPolyDataReader);

//----------------------------------------------------------------------------
vtkXMLPolyDataReader::vtkXMLPolyDataReader()
{
  this->VertElements = 0;
  this->LineElements = 0;
  this->StripElements = 0;
  this->PolyElements = 0;
  this->TotalNumberOfVerts = 0;
  this->TotalNumberOfLines = 0;
  this->TotalNumberOfStrips = 0;
  this->TotalNumberOfPolys = 0;
40 41 42

  // TimeStep
  this->VertsTimeStep = -1;
Francois Bertel's avatar
Francois Bertel committed
43
  this->VertsOffset = static_cast<unsigned long>(-1);
44
  this->LinesTimeStep = -1;
Francois Bertel's avatar
Francois Bertel committed
45
  this->LinesOffset = static_cast<unsigned long>(-1);
46
  this->StripsTimeStep = -1;
Francois Bertel's avatar
Francois Bertel committed
47
  this->StripsOffset = static_cast<unsigned long>(-1);
48
  this->PolysTimeStep = -1;
Francois Bertel's avatar
Francois Bertel committed
49
  this->PolysOffset = static_cast<unsigned long>(-1);
50 51 52 53 54
}

//----------------------------------------------------------------------------
vtkXMLPolyDataReader::~vtkXMLPolyDataReader()
{
55
  if (this->NumberOfPieces)
56 57 58
    {
    this->DestroyPieces();
    }
59 60 61 62 63 64 65 66 67 68 69
}

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

//----------------------------------------------------------------------------
vtkPolyData* vtkXMLPolyDataReader::GetOutput()
{
70
  return this->GetOutput(0);
71 72
}

73 74 75
//----------------------------------------------------------------------------
vtkPolyData* vtkXMLPolyDataReader::GetOutput(int idx)
{
76
  return vtkPolyData::SafeDownCast(this->GetOutputDataObject(idx));
77 78
}

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
//----------------------------------------------------------------------------
vtkIdType vtkXMLPolyDataReader::GetNumberOfVerts()
{
  return this->TotalNumberOfVerts;
}

//----------------------------------------------------------------------------
vtkIdType vtkXMLPolyDataReader::GetNumberOfLines()
{
  return this->TotalNumberOfLines;
}

//----------------------------------------------------------------------------
vtkIdType vtkXMLPolyDataReader::GetNumberOfStrips()
{
  return this->TotalNumberOfStrips;
}

//----------------------------------------------------------------------------
vtkIdType vtkXMLPolyDataReader::GetNumberOfPolys()
{
  return this->TotalNumberOfPolys;
}

//----------------------------------------------------------------------------
const char* vtkXMLPolyDataReader::GetDataSetName()
{
  return "PolyData";
}

//----------------------------------------------------------------------------
110 111
void vtkXMLPolyDataReader::GetOutputUpdateExtent(
  int& piece, int& numberOfPieces, int& ghostLevel)
112
{
113 114
  vtkInformation* outInfo = this->GetCurrentOutputInformation();
  piece = outInfo->Get(
115 116 117
    vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
  numberOfPieces = outInfo->Get(
    vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
118
  ghostLevel = outInfo->Get(
119
    vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
120 121 122 123 124 125 126
}

//----------------------------------------------------------------------------
void vtkXMLPolyDataReader::SetupOutputTotals()
{
  this->Superclass::SetupOutputTotals();
  // Find the total size of the output.
127

128 129 130 131 132
  this->TotalNumberOfCells = 0;
  this->TotalNumberOfVerts = 0;
  this->TotalNumberOfLines = 0;
  this->TotalNumberOfStrips = 0;
  this->TotalNumberOfPolys = 0;
133
  for (int i = this->StartPiece; i < this->EndPiece; ++i)
134 135 136 137 138 139 140 141 142 143
    {
    this->TotalNumberOfCells += (this->NumberOfVerts[i] +
                                 this->NumberOfLines[i] +
                                 this->NumberOfStrips[i] +
                                 this->NumberOfPolys[i]);
    this->TotalNumberOfVerts += this->NumberOfVerts[i];
    this->TotalNumberOfLines += this->NumberOfLines[i];
    this->TotalNumberOfStrips += this->NumberOfStrips[i];
    this->TotalNumberOfPolys += this->NumberOfPolys[i];
    }
144

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
  // Data reading will start at the beginning of the output.
  this->StartVert = 0;
  this->StartLine = 0;
  this->StartStrip = 0;
  this->StartPoly = 0;
}

//----------------------------------------------------------------------------
void vtkXMLPolyDataReader::SetupPieces(int numPieces)
{
  this->Superclass::SetupPieces(numPieces);
  this->NumberOfVerts = new vtkIdType[numPieces];
  this->NumberOfLines = new vtkIdType[numPieces];
  this->NumberOfStrips = new vtkIdType[numPieces];
  this->NumberOfPolys = new vtkIdType[numPieces];
  this->VertElements = new vtkXMLDataElement*[numPieces];
  this->LineElements = new vtkXMLDataElement*[numPieces];
  this->StripElements = new vtkXMLDataElement*[numPieces];
  this->PolyElements = new vtkXMLDataElement*[numPieces];
164
  for (int i = 0; i < numPieces; ++i)
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    {
    this->VertElements[i] = 0;
    this->LineElements[i] = 0;
    this->StripElements[i] = 0;
    this->PolyElements[i] = 0;
    }
}

//----------------------------------------------------------------------------
void vtkXMLPolyDataReader::DestroyPieces()
{
  delete [] this->PolyElements;
  delete [] this->StripElements;
  delete [] this->LineElements;
  delete [] this->VertElements;
  delete [] this->NumberOfPolys;
  delete [] this->NumberOfStrips;
  delete [] this->NumberOfLines;
  delete [] this->NumberOfVerts;
  this->Superclass::DestroyPieces();
}

187 188 189
//----------------------------------------------------------------------------
vtkIdType vtkXMLPolyDataReader::GetNumberOfCellsInPiece(int piece)
{
190 191 192
  return (this->NumberOfVerts[piece] +
          this->NumberOfLines[piece] +
          this->NumberOfStrips[piece] +
193 194 195
          this->NumberOfPolys[piece]);
}

196 197 198 199
//----------------------------------------------------------------------------
void vtkXMLPolyDataReader::SetupOutputData()
{
  this->Superclass::SetupOutputData();
200
  vtkPolyData* output = vtkPolyData::SafeDownCast(this->GetCurrentOutput());
201 202

  // Setup the output's cell arrays.
203 204 205 206
  vtkCellArray* outVerts = vtkCellArray::New();
  vtkCellArray* outLines = vtkCellArray::New();
  vtkCellArray* outStrips = vtkCellArray::New();
  vtkCellArray* outPolys = vtkCellArray::New();
207

208 209 210 211
  output->SetVerts(outVerts);
  output->SetLines(outLines);
  output->SetStrips(outStrips);
  output->SetPolys(outPolys);
212

213 214 215 216 217 218 219 220 221
  outPolys->Delete();
  outStrips->Delete();
  outLines->Delete();
  outVerts->Delete();
}

//----------------------------------------------------------------------------
int vtkXMLPolyDataReader::ReadPiece(vtkXMLDataElement* ePiece)
{
222
  if (!this->Superclass::ReadPiece(ePiece))
223 224 225
    {
    return 0;
    }
226

227 228
  if (!ePiece->GetScalarAttribute("NumberOfVerts",
    this->NumberOfVerts[this->Piece]))
229 230 231
    {
    this->NumberOfVerts[this->Piece] = 0;
    }
232 233
  if (!ePiece->GetScalarAttribute("NumberOfLines",
    this->NumberOfLines[this->Piece]))
234 235 236
    {
    this->NumberOfLines[this->Piece] = 0;
    }
237 238
  if (!ePiece->GetScalarAttribute("NumberOfStrips",
    this->NumberOfStrips[this->Piece]))
239 240 241
    {
    this->NumberOfStrips[this->Piece] = 0;
    }
242 243
  if (!ePiece->GetScalarAttribute("NumberOfPolys",
    this->NumberOfPolys[this->Piece]))
244 245 246
    {
    this->NumberOfPolys[this->Piece] = 0;
    }
247

248
  // Find the cell elements in the piece.
249
  for (int i = 0; i < ePiece->GetNumberOfNestedElements(); ++i)
250 251
    {
    vtkXMLDataElement* eNested = ePiece->GetNestedElement(i);
252 253
    if ((strcmp(eNested->GetName(), "Verts") == 0)
      && (eNested->GetNumberOfNestedElements() > 1))
254 255 256
      {
      this->VertElements[this->Piece] = eNested;
      }
257 258
    if ((strcmp(eNested->GetName(), "Lines") == 0)
      && (eNested->GetNumberOfNestedElements() > 1))
259 260 261
      {
      this->LineElements[this->Piece] = eNested;
      }
262 263
    if ((strcmp(eNested->GetName(), "Strips") == 0)
      && (eNested->GetNumberOfNestedElements() > 1))
264 265 266
      {
      this->StripElements[this->Piece] = eNested;
      }
267 268
    if ((strcmp(eNested->GetName(), "Polys") == 0)
      && (eNested->GetNumberOfNestedElements() > 1))
269 270 271 272
      {
      this->PolyElements[this->Piece] = eNested;
      }
    }
273

274 275 276 277 278 279
  return 1;
}

//----------------------------------------------------------------------------
void vtkXMLPolyDataReader::SetupNextPiece()
{
280
  this->Superclass::SetupNextPiece();
281
  this->StartVert += this->NumberOfVerts[this->Piece];
282
  this->StartLine += this->NumberOfLines[this->Piece];
283 284 285 286 287 288 289
  this->StartStrip += this->NumberOfStrips[this->Piece];
  this->StartPoly += this->NumberOfPolys[this->Piece];
}

//----------------------------------------------------------------------------
int vtkXMLPolyDataReader::ReadPieceData()
{
290 291 292 293
  // 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 =
294 295 296 297
    ((this->NumberOfPointArrays + 1) *
    this->GetNumberOfPointsInPiece(this->Piece) +
    this->NumberOfCellArrays *
    this->GetNumberOfCellsInPiece(this->Piece));
298

299 300 301 302 303
  // Total amount of data in this piece comes from point/cell data
  // arrays and the point/cell specifications themselves (cell
  // specifications for vtkPolyData take two data arrays split across
  // cell types).
  vtkIdType totalPieceSize =
304 305
    superclassPieceSize + 2 * this->GetNumberOfCellsInPiece(this->Piece);
  if (totalPieceSize == 0)
306 307 308
    {
    totalPieceSize = 1;
    }
309

310 311
  // Split the progress range based on the approximate fraction of
  // data that will be read by each step in this method.
312
  float progressRange[2] = { 0.f, 0.f };
313 314 315
  this->GetProgressRange(progressRange);
  float fractions[6] =
    {
316 317 318 319 320 321 322 323 324 325 326 327
    0,
    static_cast<float>(superclassPieceSize) / totalPieceSize,
    (static_cast<float>(superclassPieceSize) +
      this->NumberOfVerts[this->Piece]) / totalPieceSize,
    (static_cast<float>(superclassPieceSize) +
      this->NumberOfVerts[this->Piece] +
      this->NumberOfLines[this->Piece]) / totalPieceSize,
    (static_cast<float>(superclassPieceSize) +
      this->NumberOfVerts[this->Piece] +
      this->NumberOfLines[this->Piece] +
      this->NumberOfStrips[this->Piece]) / totalPieceSize,
    1
328
    };
329

330 331
  // Set the range of progress for the superclass.
  this->SetProgressRange(progressRange, 0, fractions);
332

333
  // Let the superclass read its data.
334
  if (!this->Superclass::ReadPieceData())
335 336 337
    {
    return 0;
    }
338

339
  vtkPolyData* output = vtkPolyData::SafeDownCast(this->GetCurrentOutput());
340

341 342
  // Set the range of progress for the Verts.
  this->SetProgressRange(progressRange, 1, fractions);
343

344
  // Read the Verts.
345
  vtkXMLDataElement* eVerts = this->VertElements[this->Piece];
346
  if (eVerts)
347
    {
348
//    int needToRead = this->CellsNeedToReadTimeStep(eNested,
349
//      this->VertsTimeStep, this->VertsOffset);
350
//    if (needToRead)
351
      {
352
      // Read the array.
353 354
      if (!this->ReadCellArray(this->NumberOfVerts[this->Piece],
        this->TotalNumberOfVerts, eVerts, output->GetVerts()))
355
        {
356
        return 0;
357 358
        }
      }
359
    }
360

361 362
  // Set the range of progress for the Lines.
  this->SetProgressRange(progressRange, 2, fractions);
363

364
  // Read the Lines.
365
  vtkXMLDataElement* eLines = this->LineElements[this->Piece];
366
  if (eLines)
367
    {
368
//    int needToRead = this->CellsNeedToReadTimeStep(eNested,
369
//      this->LinesTimeStep, this->LinesOffset);
370
//    if (needToRead)
371
      {
372
      // Read the array.
373 374
      if (!this->ReadCellArray(this->NumberOfLines[this->Piece],
        this->TotalNumberOfLines, eLines, output->GetLines()))
375
        {
376
        return 0;
377 378
        }
      }
379
    }
380

381 382
  // Set the range of progress for the Strips.
  this->SetProgressRange(progressRange, 3, fractions);
383

384
  // Read the Strips.
385
  vtkXMLDataElement* eStrips = this->StripElements[this->Piece];
386
  if (eStrips)
387
    {
388
//    int needToRead = this->CellsNeedToReadTimeStep(eNested,
389
//      this->StripsTimeStep, this->StripsOffset);
390
//    if (needToRead)
391
      {
392
      // Read the array.
393 394
      if (!this->ReadCellArray(this->NumberOfStrips[this->Piece],
        this->TotalNumberOfStrips, eStrips, output->GetStrips()))
395
        {
396
        return 0;
397 398
        }
      }
399
    }
400

401 402
  // Set the range of progress for the Polys.
  this->SetProgressRange(progressRange, 4, fractions);
403

404
  // Read the Polys.
405
  vtkXMLDataElement* ePolys = this->PolyElements[this->Piece];
406
  if (ePolys)
407
    {
408
//    int needToRead = this->CellsNeedToReadTimeStep(eNested,
409
//      this->PolysTimeStep, this->PolysOffset);
410
//    if (needToRead)
411
      {
412
      // Read the array.
413 414
      if (!this->ReadCellArray(this->NumberOfPolys[this->Piece],
        this->TotalNumberOfPolys, ePolys, output->GetPolys()))
415
        {
416
        return 0;
417
        }
418 419
      }
    }
420

421 422 423 424 425
  return 1;
}

//----------------------------------------------------------------------------
int vtkXMLPolyDataReader::ReadArrayForCells(vtkXMLDataElement* da,
Utkarsh Ayachit's avatar
ENH:  
Utkarsh Ayachit committed
426
                                            vtkAbstractArray* outArray)
427
{
428 429
  // Split progress range according to the fraction of data that will
  // be read for each type of cell.
430
  float progressRange[2] = { 0.f, 0.f };
431
  this->GetProgressRange(progressRange);
432
  int total = this->TotalNumberOfCells ? this->TotalNumberOfCells : 1;
433 434
  float fractions[5] =
    {
435 436 437 438 439 440 441 442
    0,
    static_cast<float>(this->NumberOfVerts[this->Piece]) / total,
    static_cast<float>(this->NumberOfVerts[this->Piece] +
      this->NumberOfLines[this->Piece]) / total,
    static_cast<float>(this->NumberOfVerts[this->Piece] +
      this->NumberOfLines[this->Piece] +
      this->NumberOfStrips[this->Piece]) / total,
    1
443
    };
444

445
  vtkIdType components = outArray->GetNumberOfComponents();
446

447 448
  // Set range of progress for the Verts.
  this->SetProgressRange(progressRange, 0, fractions);
449

450 451 452
  // Read the cell data for the Verts in the piece.
  vtkIdType inStartCell = 0;
  vtkIdType outStartCell = this->StartVert;
453
  vtkIdType numCells = this->NumberOfVerts[this->Piece];
454 455 456
  if (!this->ReadArrayValues(
        da, outStartCell * components, outArray,
        inStartCell * components, numCells * components, CELL_DATA))
457 458 459
    {
    return 0;
    }
460

461 462
  // Set range of progress for the Lines.
  this->SetProgressRange(progressRange, 1, fractions);
463

464 465 466
  // Read the cell data for the Lines in the piece.
  inStartCell += numCells;
  outStartCell = this->TotalNumberOfVerts + this->StartLine;
467
  numCells = this->NumberOfLines[this->Piece];
468 469 470
  if (!this->ReadArrayValues(
        da, outStartCell * components, outArray,
        inStartCell * components, numCells * components, CELL_DATA))
471 472 473
    {
    return 0;
    }
474

475 476
  // Set range of progress for the Strips.
  this->SetProgressRange(progressRange, 2, fractions);
477

478 479
  // Read the cell data for the Strips in the piece.
  inStartCell += numCells;
480 481 482
  outStartCell =
    this->TotalNumberOfVerts + this->TotalNumberOfLines + this->StartStrip;

483
  numCells = this->NumberOfStrips[this->Piece];
484
  if (!this->ReadArrayValues(da, outStartCell * components, outArray,
485
      inStartCell * components, numCells * components, CELL_DATA))
486 487 488
    {
    return 0;
    }
489

490 491
  // Set range of progress for the Polys.
  this->SetProgressRange(progressRange, 3, fractions);
492

493 494
  // Read the cell data for the Polys in the piece.
  inStartCell += numCells;
495 496 497 498
  outStartCell =
    this->TotalNumberOfVerts + this->TotalNumberOfLines +
    this->TotalNumberOfStrips + this->StartPoly;

499
  numCells = this->NumberOfPolys[this->Piece];
500
  if (!this->ReadArrayValues(da, outStartCell * components, outArray,
501
      inStartCell * components, numCells * components, CELL_DATA))
502 503 504
    {
    return 0;
    }
505

506 507
  return 1;
}
508 509

//----------------------------------------------------------------------------
510
int vtkXMLPolyDataReader::FillOutputPortInformation(int, vtkInformation* info)
511 512 513 514
{
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData");
  return 1;
}