vtkXMLPUnstructuredDataReader.cxx 12.8 KB
Newer Older
1 2 3 4 5
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkXMLPUnstructuredDataReader.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
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkXMLPUnstructuredDataReader.h"
#include "vtkXMLDataElement.h"
#include "vtkXMLUnstructuredDataReader.h"
#include "vtkPointSet.h"
#include "vtkCellArray.h"
20
#include "vtkInformation.h"
21
#include "vtkInformationVector.h"
22
#include "vtkStreamingDemandDrivenPipeline.h"
23 24 25 26 27 28 29 30 31 32


//----------------------------------------------------------------------------
vtkXMLPUnstructuredDataReader::vtkXMLPUnstructuredDataReader()
{
  this->TotalNumberOfPoints = 0;
  this->TotalNumberOfCells = 0;
}

//----------------------------------------------------------------------------
33
vtkXMLPUnstructuredDataReader::~vtkXMLPUnstructuredDataReader() = default;
34 35 36 37 38 39 40 41 42 43

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

//----------------------------------------------------------------------------
vtkPointSet* vtkXMLPUnstructuredDataReader::GetOutputAsPointSet()
{
44
  return vtkPointSet::SafeDownCast( this->GetOutputDataObject(0) );
45 46 47 48 49 50
}

//----------------------------------------------------------------------------
vtkPointSet* vtkXMLPUnstructuredDataReader::GetPieceInputAsPointSet(int piece)
{
  vtkXMLDataReader* reader = this->PieceReaders[piece];
51
  if (!reader)
52
  {
53
    return nullptr;
54
  }
55
  if (reader->GetNumberOfOutputPorts() < 1)
56
  {
57
    return nullptr;
58
  }
59
  return static_cast<vtkPointSet*>(reader->GetExecutive()->GetOutputData(0));
60 61 62 63 64 65
}

//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::SetupOutputTotals()
{
  this->TotalNumberOfPoints = 0;
66
  for (int i = this->StartPiece; i < this->EndPiece; ++i)
67
  {
68
    if(this->PieceReaders[i])
69
    {
70
      this->TotalNumberOfPoints += this->PieceReaders[i]->GetNumberOfPoints();
71
    }
72
  }
73 74 75 76 77 78
  this->StartPoint = 0;
}

//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::SetupNextPiece()
{
79
  if (this->PieceReaders[this->Piece])
80
  {
81
    this->StartPoint += this->PieceReaders[this->Piece]->GetNumberOfPoints();
82
  }
83 84 85 86 87 88 89 90 91 92 93 94 95 96
}

//----------------------------------------------------------------------------
vtkIdType vtkXMLPUnstructuredDataReader::GetNumberOfPoints()
{
  return this->TotalNumberOfPoints;
}

//----------------------------------------------------------------------------
vtkIdType vtkXMLPUnstructuredDataReader::GetNumberOfCells()
{
  return this->TotalNumberOfCells;
}

97 98 99
//----------------------------------------------------------------------------
vtkIdType vtkXMLPUnstructuredDataReader::GetNumberOfPointsInPiece(int piece)
{
100
  if (this->PieceReaders[piece])
101
  {
102
    return this->PieceReaders[piece]->GetNumberOfPoints();
103
  }
104
  else
105
  {
106
    return 0;
107
  }
108 109 110 111 112
}

//----------------------------------------------------------------------------
vtkIdType vtkXMLPUnstructuredDataReader::GetNumberOfCellsInPiece(int piece)
{
113
  if (this->PieceReaders[piece])
114
  {
115
    return this->PieceReaders[piece]->GetNumberOfCells();
116
  }
117
  else
118
  {
119
    return 0;
120
  }
121 122
}

123 124 125
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::SetupEmptyOutput()
{
126
  this->GetCurrentOutput()->Initialize();
127 128
}

129
//----------------------------------------------------------------------------
130 131
// Note that any changes (add or removing information) made to this method
// should be replicated in CopyOutputInformation
132 133
void vtkXMLPUnstructuredDataReader::SetupOutputInformation(
  vtkInformation *outInfo)
134
{
135
  this->Superclass::SetupOutputInformation(outInfo);
136

Berk Geveci's avatar
Berk Geveci committed
137
  outInfo->Set(CAN_HANDLE_PIECE_REQUEST(), 1);
138 139
}

140
//----------------------------------------------------------------------------
141 142
void vtkXMLPUnstructuredDataReader::CopyOutputInformation(
  vtkInformation *outInfo, int port)
143
{
144
  this->Superclass::CopyOutputInformation(outInfo, port);
145 146 147 148 149 150 151

  vtkInformation *localInfo =
    this->GetExecutive()->GetOutputInformation( port );
  if (localInfo->Has(CAN_HANDLE_PIECE_REQUEST()))
  {
    outInfo->CopyEntry(localInfo, CAN_HANDLE_PIECE_REQUEST());
  }
152
}
153 154 155 156 157

//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::SetupOutputData()
{
  this->Superclass::SetupOutputData();
158

159 160
  // Create the points array.
  vtkPoints* points = vtkPoints::New();
161
  if (this->PPointsElement)
162
  {
Utkarsh Ayachit's avatar
ENH:  
Utkarsh Ayachit committed
163 164
    vtkAbstractArray* aa = this->CreateArray(
      this->PPointsElement->GetNestedElement(0));
165
    vtkDataArray* a = vtkArrayDownCast<vtkDataArray>(aa);
166
    if (a)
167
    {
168
      a->SetNumberOfTuples(this->GetNumberOfPoints());
169 170
      points->SetData(a);
      a->Delete();
171
    }
172
    else
173
    {
174
      if (aa)
175
      {
176
        aa->Delete();
177
      }
178
      this->DataError = 1;
179
    }
180
  }
181
  vtkPointSet::SafeDownCast(this->GetCurrentOutput())->SetPoints(points);
182 183 184 185
  points->Delete();
}

//----------------------------------------------------------------------------
186 187
void vtkXMLPUnstructuredDataReader::SetupUpdateExtent(
  int piece, int numberOfPieces, int ghostLevel)
188 189 190 191
{
  this->UpdatePiece = piece;
  this->UpdateNumberOfPieces = numberOfPieces;
  this->UpdateGhostLevel = ghostLevel;
192

193 194
  // If more pieces are requested than available, just return empty
  // pieces for the extra ones.
195
  if (this->UpdateNumberOfPieces > this->NumberOfPieces)
196
  {
197
    this->UpdateNumberOfPieces = this->NumberOfPieces;
198
  }
199

200
  // Find the range of pieces to read.
201
  if (this->UpdatePiece < this->UpdateNumberOfPieces)
202
  {
203 204 205 206
    this->StartPiece = ((this->UpdatePiece*this->NumberOfPieces) /
                        this->UpdateNumberOfPieces);
    this->EndPiece = (((this->UpdatePiece+1)*this->NumberOfPieces) /
                      this->UpdateNumberOfPieces);
207
  }
208
  else
209
  {
210 211
    this->StartPiece = 0;
    this->EndPiece = 0;
212
  }
213

214
  // Update the information of the pieces we need.
215
  for (int i = this->StartPiece; i < this->EndPiece; ++i)
216
  {
217
    if(this->CanReadPiece(i))
218
    {
219 220 221 222 223
      this->PieceReaders[i]->UpdateInformation();
      vtkXMLUnstructuredDataReader* pReader =
        static_cast<vtkXMLUnstructuredDataReader*>(this->PieceReaders[i]);
      pReader->SetupUpdateExtent(0, 1, this->UpdateGhostLevel);
    }
224
  }
225

226
  // Find the total size of the output.
227
  this->SetupOutputTotals();
228 229 230
}

//----------------------------------------------------------------------------
231
int vtkXMLPUnstructuredDataReader::ReadPrimaryElement(vtkXMLDataElement* ePri)
232
{
233
  if(!this->Superclass::ReadPrimaryElement(ePri)) { return 0; }
234

235
  // Find the PPoints element.
236
  this->PPointsElement = nullptr;
237 238
  int numNested = ePri->GetNumberOfNestedElements();
  for (int i = 0;i < numNested; ++i)
239
  {
240 241 242
    vtkXMLDataElement* eNested = ePri->GetNestedElement(i);
    if ((strcmp(eNested->GetName(), "PPoints") == 0) &&
      (eNested->GetNumberOfNestedElements() == 1))
243
    {
244 245
      this->PPointsElement = eNested;
    }
246
  }
247

248 249 250
  // If PPoints element was not found, we must assume there are 0
  // points.  If there are found to be points later, the error will be
  // reported by ReadPieceData.
251

252 253 254 255 256 257 258
  return 1;
}

//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::ReadXMLData()
{
  // Get the update request.
259
  vtkInformation* outInfo = this->GetCurrentOutputInformation();
260 261 262 263 264 265
  int piece = outInfo->Get(
    vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
  int numberOfPieces = outInfo->Get(
    vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES());
  int ghostLevel = outInfo->Get(
    vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
266

267 268
  vtkDebugMacro("Updating piece " << piece << " of " << numberOfPieces
                << " with ghost level " << ghostLevel);
269

270 271
  // Setup the range of pieces that will be read.
  this->SetupUpdateExtent(piece, numberOfPieces, ghostLevel);
272

273
  // If there are no data to read, stop now.
274
  if (this->StartPiece == this->EndPiece)
275
  {
276
    return;
277
  }
278

279
  vtkDebugMacro("Reading piece range [" << this->StartPiece
280 281
                << ", " << this->EndPiece << ") from file.");

282 283
  // Let superclasses read data.  This also allocates output data.
  this->Superclass::ReadXMLData();
284

285 286
  // Split current progress range based on fraction contributed by
  // each piece.
287
  float progressRange[2] = { 0.f, 0.f };
288
  this->GetProgressRange(progressRange);
289

290 291 292 293
  // Calculate the cumulative fraction of data contributed by each
  // piece (for progress).
  float* fractions = new float[this->EndPiece-this->StartPiece+1];
  fractions[0] = 0;
294
  for (int i = this->StartPiece; i < this->EndPiece; ++i)
295
  {
296
    int index = i - this->StartPiece;
297
    fractions[index+1] = (fractions[index] +
298
                          this->GetNumberOfPointsInPiece(i) +
299
                          this->GetNumberOfCellsInPiece(i));
300
  }
301
  if (fractions[this->EndPiece-this->StartPiece] == 0)
302
  {
303
    fractions[this->EndPiece-this->StartPiece] = 1;
304
  }
305
  for (int i = this->StartPiece; i < this->EndPiece; ++i)
306
  {
307
    int index = i-this->StartPiece;
308 309
    fractions[index+1] = fractions[index+1] /
      fractions[this->EndPiece-this->StartPiece];
310
  }
311

312
  // Read the data needed from each piece.
313 314
  for(int i = this->StartPiece;
    (i < this->EndPiece && !this->AbortExecute && !this->DataError); ++i)
315
  {
316
    // Set the range of progress for this piece.
317
    this->SetProgressRange(progressRange, i - this->StartPiece, fractions);
318

319
    if (!this->Superclass::ReadPieceData(i))
320
    {
321 322
      // An error occurred while reading the piece.
      this->DataError = 1;
323
    }
324 325
    this->SetupNextPiece();
  }
326

327
  delete [] fractions;
328 329 330 331
}

//----------------------------------------------------------------------------
int vtkXMLPUnstructuredDataReader::ReadPieceData()
332
{
333
  // Use the internal reader to read the piece.
334
  this->PieceReaders[this->Piece]->UpdatePiece(0, 1, this->UpdateGhostLevel);
Berk Geveci's avatar
Berk Geveci committed
335

336
  vtkPointSet* input = this->GetPieceInputAsPointSet(this->Piece);
337
  vtkPointSet* output = vtkPointSet::SafeDownCast(this->GetCurrentOutput());
338

339 340
  // If there are some points, but no PPoints element, report the
  // error.
341
  if (!this->PPointsElement && (this->GetNumberOfPoints() > 0))
342
  {
343 344
    vtkErrorMacro("Could not find PPoints element with 1 array.");
    return 0;
345
  }
346

347
  if (!input->GetPoints())
348
  {
349
    return 0;
350
  }
351

352
  // Copy the points array.
353 354
  this->CopyArrayForPoints(
    input->GetPoints()->GetData(), output->GetPoints()->GetData());
355

356 357 358 359 360
  // Let the superclass read the data it wants.
  return this->Superclass::ReadPieceData();
}

//----------------------------------------------------------------------------
361 362
void vtkXMLPUnstructuredDataReader::CopyArrayForPoints(
  vtkDataArray* inArray, vtkDataArray* outArray)
363
{
364
  if (!this->PieceReaders[this->Piece])
365
  {
366
    return;
367
  }
368
  if (!inArray || !outArray)
369
  {
Charles Law's avatar
Charles Law committed
370
    return;
371
  }
372

373 374 375 376
  vtkIdType numPoints = this->PieceReaders[this->Piece]->GetNumberOfPoints();
  vtkIdType components = outArray->GetNumberOfComponents();
  vtkIdType tupleSize = inArray->GetDataTypeSize()*components;
  memcpy(outArray->GetVoidPointer(this->StartPoint*components),
377
    inArray->GetVoidPointer(0), numPoints*tupleSize);
378 379 380
}

//----------------------------------------------------------------------------
381 382
void vtkXMLPUnstructuredDataReader::CopyCellArray(
  vtkIdType totalNumberOfCells, vtkCellArray* inCells, vtkCellArray* outCells)
383 384 385
{
  // Allocate memory in the output connectivity array.
  vtkIdType curSize = 0;
386
  if (outCells->GetData())
387
  {
388
    curSize = outCells->GetData()->GetNumberOfTuples();
389
  }
390 391 392 393 394 395
  vtkIdTypeArray* inData = inCells->GetData();
  vtkIdType newSize = curSize+inData->GetNumberOfTuples();
  vtkIdType* in = inData->GetPointer(0);
  vtkIdType* end = inData->GetPointer(inData->GetNumberOfTuples());
  vtkIdType* out = outCells->WritePointer(totalNumberOfCells, newSize);
  out += curSize;
396

397
  // Copy the connectivity data.
398
  while (in < end)
399
  {
400 401 402 403
    vtkIdType length = *in++;
    *out++ = length;
    // Copy the point indices, but increment them for the appended
    // version's index.
404
    for (vtkIdType j = 0; j < length; ++j)
405
    {
406
      out[j] = in[j] + this->StartPoint;
407
    }
408 409
    in += length;
    out += length;
410
  }
411
}
412 413 414 415 416 417 418 419

//----------------------------------------------------------------------------
int vtkXMLPUnstructuredDataReader::RequestInformation(
   vtkInformation *request,
   vtkInformationVector **inputVector,
   vtkInformationVector *outputVector)
{
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
Berk Geveci's avatar
Berk Geveci committed
420
  outInfo->Set(CAN_HANDLE_PIECE_REQUEST(), 1);
421 422
  return this->Superclass::RequestInformation(request, inputVector, outputVector);
}