Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

403 lines
13 KiB

2 years ago
/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkXMLPUnstructuredDataReader.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm 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 "vtkXMLPUnstructuredDataReader.h"
#include "vtkXMLDataElement.h"
#include "vtkXMLUnstructuredDataReader.h"
#include "vtkPointSet.h"
#include "vtkCellArray.h"
#include "vtkInformation.h"
#include "vtkStreamingDemandDrivenPipeline.h"
vtkCxxRevisionMacro(vtkXMLPUnstructuredDataReader, "$Revision: 1.18 $");
//----------------------------------------------------------------------------
vtkXMLPUnstructuredDataReader::vtkXMLPUnstructuredDataReader()
{
this->TotalNumberOfPoints = 0;
this->TotalNumberOfCells = 0;
}
//----------------------------------------------------------------------------
vtkXMLPUnstructuredDataReader::~vtkXMLPUnstructuredDataReader()
{
}
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
//----------------------------------------------------------------------------
vtkPointSet* vtkXMLPUnstructuredDataReader::GetOutputAsPointSet()
{
return vtkPointSet::SafeDownCast( this->GetOutputDataObject(0) );
}
//----------------------------------------------------------------------------
vtkPointSet* vtkXMLPUnstructuredDataReader::GetPieceInputAsPointSet(int piece)
{
vtkXMLDataReader* reader = this->PieceReaders[piece];
if(!reader) { return 0; }
if(reader->GetNumberOfOutputPorts() < 1) { return 0; }
return static_cast<vtkPointSet*>(reader->GetExecutive()->GetOutputData(0));
}
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::SetupOutputTotals()
{
int i;
this->TotalNumberOfPoints = 0;
for(i=this->StartPiece; i < this->EndPiece; ++i)
{
if(this->PieceReaders[i])
{
this->TotalNumberOfPoints += this->PieceReaders[i]->GetNumberOfPoints();
}
}
this->StartPoint = 0;
}
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::SetupNextPiece()
{
if(this->PieceReaders[this->Piece])
{
this->StartPoint += this->PieceReaders[this->Piece]->GetNumberOfPoints();
}
}
//----------------------------------------------------------------------------
vtkIdType vtkXMLPUnstructuredDataReader::GetNumberOfPoints()
{
return this->TotalNumberOfPoints;
}
//----------------------------------------------------------------------------
vtkIdType vtkXMLPUnstructuredDataReader::GetNumberOfCells()
{
return this->TotalNumberOfCells;
}
//----------------------------------------------------------------------------
vtkIdType vtkXMLPUnstructuredDataReader::GetNumberOfPointsInPiece(int piece)
{
if(this->PieceReaders[piece])
{
return this->PieceReaders[piece]->GetNumberOfPoints();
}
else
{
return 0;
}
}
//----------------------------------------------------------------------------
vtkIdType vtkXMLPUnstructuredDataReader::GetNumberOfCellsInPiece(int piece)
{
if(this->PieceReaders[piece])
{
return this->PieceReaders[piece]->GetNumberOfCells();
}
else
{
return 0;
}
}
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::SetupEmptyOutput()
{
// No pieces means no input.
this->GetOutputAsDataSet(0)->SetUpdateExtent(0, 0);
}
//----------------------------------------------------------------------------
// Note that any changes (add or removing information) made to this method
// should be replicated in CopyOutputInformation
void vtkXMLPUnstructuredDataReader::SetupOutputInformation(vtkInformation *outInfo)
{
this->Superclass::SetupOutputInformation(outInfo);
// Set the maximum number of pieces that can be provided by this
// reader.
outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), this->NumberOfPieces);
}
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::CopyOutputInformation(vtkInformation *outInfo, int port)
{
this->Superclass::CopyOutputInformation(outInfo, port);
outInfo->CopyEntry( this->GetExecutive()->GetOutputInformation( port ),
vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES() );
}
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::SetupOutputData()
{
this->Superclass::SetupOutputData();
// Create the points array.
vtkPoints* points = vtkPoints::New();
if(this->PPointsElement)
{
vtkDataArray* a = this->CreateDataArray(this->PPointsElement->GetNestedElement(0));
if(a)
{
a->SetNumberOfTuples(this->GetNumberOfPoints());
points->SetData(a);
a->Delete();
}
else
{
this->DataError = 1;
}
}
this->GetOutputAsPointSet()->SetPoints(points);
points->Delete();
}
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::SetupUpdateExtent(int piece,
int numberOfPieces,
int ghostLevel)
{
this->UpdatePiece = piece;
this->UpdateNumberOfPieces = numberOfPieces;
this->UpdateGhostLevel = ghostLevel;
// If more pieces are requested than available, just return empty
// pieces for the extra ones.
if(this->UpdateNumberOfPieces > this->NumberOfPieces)
{
this->UpdateNumberOfPieces = this->NumberOfPieces;
}
// Find the range of pieces to read.
if(this->UpdatePiece < this->UpdateNumberOfPieces)
{
this->StartPiece = ((this->UpdatePiece*this->NumberOfPieces) /
this->UpdateNumberOfPieces);
this->EndPiece = (((this->UpdatePiece+1)*this->NumberOfPieces) /
this->UpdateNumberOfPieces);
}
else
{
this->StartPiece = 0;
this->EndPiece = 0;
}
// Update the information of the pieces we need.
int i;
for(i=this->StartPiece; i < this->EndPiece; ++i)
{
if(this->CanReadPiece(i))
{
this->PieceReaders[i]->UpdateInformation();
vtkXMLUnstructuredDataReader* pReader =
static_cast<vtkXMLUnstructuredDataReader*>(this->PieceReaders[i]);
pReader->SetupUpdateExtent(0, 1, this->UpdateGhostLevel);
}
}
// Find the total size of the output.
this->SetupOutputTotals();
}
//----------------------------------------------------------------------------
int
vtkXMLPUnstructuredDataReader::ReadPrimaryElement(vtkXMLDataElement* ePrimary)
{
if(!this->Superclass::ReadPrimaryElement(ePrimary)) { return 0; }
// Find the PPoints element.
this->PPointsElement = 0;
int i;
int numNested = ePrimary->GetNumberOfNestedElements();
for(i=0;i < numNested; ++i)
{
vtkXMLDataElement* eNested = ePrimary->GetNestedElement(i);
if((strcmp(eNested->GetName(), "PPoints") == 0) &&
(eNested->GetNumberOfNestedElements() == 1))
{
this->PPointsElement = eNested;
}
}
// 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.
return 1;
}
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::ReadXMLData()
{
// Get the update request.
int piece;
int numberOfPieces;
int ghostLevel;
this->GetOutputUpdateExtent(piece, numberOfPieces, ghostLevel);
vtkDebugMacro("Updating piece " << piece << " of " << numberOfPieces
<< " with ghost level " << ghostLevel);
// Setup the range of pieces that will be read.
this->SetupUpdateExtent(piece, numberOfPieces, ghostLevel);
// If there are no data to read, stop now.
if(this->StartPiece == this->EndPiece)
{
return;
}
vtkDebugMacro("Reading piece range [" << this->StartPiece
<< ", " << this->EndPiece << ") from file.");
// Let superclasses read data. This also allocates output data.
this->Superclass::ReadXMLData();
// Split current progress range based on fraction contributed by
// each piece.
float progressRange[2] = {0,0};
this->GetProgressRange(progressRange);
// Calculate the cumulative fraction of data contributed by each
// piece (for progress).
float* fractions = new float[this->EndPiece-this->StartPiece+1];
int i;
fractions[0] = 0;
for(i=this->StartPiece; i < this->EndPiece; ++i)
{
int index = i-this->StartPiece;
fractions[index+1] = (fractions[index] +
this->GetNumberOfPointsInPiece(i) +
this->GetNumberOfCellsInPiece(i));
}
if(fractions[this->EndPiece-this->StartPiece] == 0)
{
fractions[this->EndPiece-this->StartPiece] = 1;
}
for(i=this->StartPiece; i < this->EndPiece; ++i)
{
int index = i-this->StartPiece;
fractions[index+1] = fractions[index+1] / fractions[this->EndPiece-this->StartPiece];
}
// Read the data needed from each piece.
for(i=this->StartPiece; (i < this->EndPiece && !this->AbortExecute &&
!this->DataError); ++i)
{
// Set the range of progress for this piece.
this->SetProgressRange(progressRange, i-this->StartPiece, fractions);
if(!this->Superclass::ReadPieceData(i))
{
// An error occurred while reading the piece.
this->DataError = 1;
}
this->SetupNextPiece();
}
delete [] fractions;
}
//----------------------------------------------------------------------------
int vtkXMLPUnstructuredDataReader::ReadPieceData()
{
// Use the internal reader to read the piece.
vtkPointSet* input = this->GetPieceInputAsPointSet(this->Piece);
input->SetUpdateExtent(0, 1, this->UpdateGhostLevel);
input->Update();
vtkPointSet* output = this->GetOutputAsPointSet();
// If there are some points, but no PPoints element, report the
// error.
if(!this->PPointsElement && (this->GetNumberOfPoints() > 0))
{
vtkErrorMacro("Could not find PPoints element with 1 array.");
return 0;
}
if (!input->GetPoints())
{
return 0;
}
// Copy the points array.
this->CopyArrayForPoints(input->GetPoints()->GetData(),
output->GetPoints()->GetData());
// Let the superclass read the data it wants.
return this->Superclass::ReadPieceData();
}
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::CopyArrayForPoints(vtkDataArray* inArray,
vtkDataArray* outArray)
{
if(!this->PieceReaders[this->Piece])
{
return;
}
if (inArray == NULL || outArray == NULL)
{
return;
}
vtkIdType numPoints = this->PieceReaders[this->Piece]->GetNumberOfPoints();
vtkIdType components = outArray->GetNumberOfComponents();
vtkIdType tupleSize = inArray->GetDataTypeSize()*components;
memcpy(outArray->GetVoidPointer(this->StartPoint*components),
inArray->GetVoidPointer(0), numPoints*tupleSize);
}
//----------------------------------------------------------------------------
void vtkXMLPUnstructuredDataReader::CopyCellArray(vtkIdType totalNumberOfCells,
vtkCellArray* inCells,
vtkCellArray* outCells)
{
// Allocate memory in the output connectivity array.
vtkIdType curSize = 0;
if(outCells->GetData())
{
curSize = outCells->GetData()->GetNumberOfTuples();
}
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;
// Copy the connectivity data.
while(in < end)
{
vtkIdType length = *in++;
*out++ = length;
// Copy the point indices, but increment them for the appended
// version's index.
vtkIdType j;
for(j=0;j < length; ++j)
{
out[j] = in[j]+this->StartPoint;
}
in += length;
out += length;
}
}