You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/3rd/VTK7.1/source/VTK-7.1.1/IO/XML/vtkXMLUnstructuredDataWrite...

1045 lines
33 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkXMLUnstructuredDataWriter.cxx
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 "vtkXMLUnstructuredDataWriter.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCellIterator.h"
#include "vtkDataArray.h"
#include "vtkDataCompressor.h"
#include "vtkDataSetAttributes.h"
#include "vtkErrorCode.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPointSet.h"
#include "vtkPoints.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkUnsignedCharArray.h"
#define vtkXMLOffsetsManager_DoNotInclude
#include "vtkXMLOffsetsManager.h"
#undef vtkXMLOffsetsManager_DoNotInclude
#include <cassert>
//----------------------------------------------------------------------------
vtkXMLUnstructuredDataWriter::vtkXMLUnstructuredDataWriter()
{
this->NumberOfPieces = 1;
this->WritePiece = -1;
this->GhostLevel = 0;
this->CellPoints = vtkIdTypeArray::New();
this->CellOffsets = vtkIdTypeArray::New();
this->CellPoints->SetName("connectivity");
this->CellOffsets->SetName("offsets");
this->CurrentPiece = 0;
this->FieldDataOM->Allocate(0);
this->PointsOM = new OffsetsManagerGroup;
this->PointDataOM = new OffsetsManagerArray;
this->CellDataOM = new OffsetsManagerArray;
this->Faces = vtkIdTypeArray::New();
this->FaceOffsets = vtkIdTypeArray::New();
this->Faces->SetName("faces");
this->FaceOffsets->SetName("faceoffsets");
}
//----------------------------------------------------------------------------
vtkXMLUnstructuredDataWriter::~vtkXMLUnstructuredDataWriter()
{
this->CellPoints->Delete();
this->CellOffsets->Delete();
this->Faces->Delete();
this->FaceOffsets->Delete();
delete this->PointsOM;
delete this->PointDataOM;
delete this->CellDataOM;
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "NumberOfPieces: " << this->NumberOfPieces << "\n";
os << indent << "WritePiece: " << this->WritePiece << "\n";
os << indent << "GhostLevel: " << this->GhostLevel << "\n";
}
//----------------------------------------------------------------------------
vtkPointSet* vtkXMLUnstructuredDataWriter::GetInputAsPointSet()
{
return static_cast<vtkPointSet*>(this->Superclass::GetInput());
}
//----------------------------------------------------------------------------
int vtkXMLUnstructuredDataWriter::ProcessRequest(vtkInformation* request,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector)
{
if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
{
if((this->WritePiece < 0) || (this->WritePiece >= this->NumberOfPieces))
{
this->SetInputUpdateExtent(
this->CurrentPiece, this->NumberOfPieces, this->GhostLevel);
}
else
{
this->SetInputUpdateExtent(
this->WritePiece, this->NumberOfPieces, this->GhostLevel);
}
return 1;
}
// generate the data
else if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA()))
{
this->SetErrorCode(vtkErrorCode::NoError);
if(!this->Stream && !this->FileName && !this->WriteToOutputString)
{
this->SetErrorCode(vtkErrorCode::NoFileNameError);
vtkErrorMacro("The FileName or Stream must be set first or "
"the output must be written to a string.");
return 0;
}
int numPieces = this->NumberOfPieces;
if (this->WritePiece >= 0)
{
this->CurrentPiece = this->WritePiece;
}
else
{
float wholeProgressRange[2] = {0,1};
this->SetProgressRange(wholeProgressRange, this->CurrentPiece, this->NumberOfPieces);
}
int result = 1;
if ((this->CurrentPiece == 0 && this->CurrentTimeIndex == 0) || this->WritePiece >= 0)
{
// We are just starting to write. Do not call
// UpdateProgressDiscrete because we want a 0 progress callback the
// first time.
this->UpdateProgress(0);
// Initialize progress range to entire 0..1 range.
if (this->WritePiece >= 0)
{
float wholeProgressRange[2] = {0,1};
this->SetProgressRange(wholeProgressRange, 0, 1);
}
if (!this->OpenStream())
{
this->NumberOfPieces = numPieces;
return 0;
}
if (this->GetInputAsDataSet() != NULL &&
(this->GetInputAsDataSet()->GetPointGhostArray() != NULL &&
this->GetInputAsDataSet()->GetCellGhostArray() != NULL))
{
// use the current version for the file.
this->UsePreviousVersion = false;
}
// Write the file.
if (!this->StartFile())
{
this->NumberOfPieces = numPieces;
return 0;
}
if (!this->WriteHeader())
{
this->NumberOfPieces = numPieces;
return 0;
}
this->CurrentTimeIndex = 0;
if( this->DataMode == vtkXMLWriter::Appended && this->FieldDataOM->GetNumberOfElements())
{
// Write the field data arrays.
this->WriteFieldDataAppendedData(this->GetInput()->GetFieldData(),
this->CurrentTimeIndex, this->FieldDataOM);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
this->DeletePositionArrays();
return 0;
}
}
}
if( !(this->UserContinueExecuting == 0)) //if user ask to stop do not try to write a piece
{
result = this->WriteAPiece();
}
if((this->WritePiece < 0) || (this->WritePiece >= this->NumberOfPieces))
{
// Tell the pipeline to start looping.
if (this->CurrentPiece == 0)
{
request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(), 1);
}
this->CurrentPiece++;
}
if (this->CurrentPiece == this->NumberOfPieces || this->WritePiece >= 0)
{
request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
this->CurrentPiece = 0;
// We are done writing all the pieces, lets loop over time now:
this->CurrentTimeIndex++;
if( this->UserContinueExecuting != 1 )
{
if (!this->WriteFooter())
{
this->NumberOfPieces = numPieces;
return 0;
}
if (!this->EndFile())
{
this->NumberOfPieces = numPieces;
return 0;
}
this->CloseStream();
this->CurrentTimeIndex = 0; // Reset
}
}
this->NumberOfPieces = numPieces;
// We have finished writing (at least this piece)
this->SetProgressPartial(1);
return result;
}
return this->Superclass::ProcessRequest(request, inputVector, outputVector);
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::AllocatePositionArrays()
{
this->NumberOfPointsPositions = new vtkTypeInt64[this->NumberOfPieces];
this->PointsOM->Allocate(this->NumberOfPieces, this->NumberOfTimeSteps);
this->PointDataOM->Allocate(this->NumberOfPieces);
this->CellDataOM->Allocate(this->NumberOfPieces);
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::DeletePositionArrays()
{
delete [] this->NumberOfPointsPositions;
this->NumberOfPointsPositions = 0;
}
//----------------------------------------------------------------------------
int vtkXMLUnstructuredDataWriter::WriteHeader()
{
vtkIndent indent = vtkIndent().GetNextIndent();
ostream& os = *(this->Stream);
if(!this->WritePrimaryElement(os, indent))
{
return 0;
}
this->WriteFieldData(indent.GetNextIndent());
if(this->DataMode == vtkXMLWriter::Appended)
{
vtkIndent nextIndent = indent.GetNextIndent();
this->AllocatePositionArrays();
if((this->WritePiece < 0) || (this->WritePiece >= this->NumberOfPieces))
{
// Loop over each piece and write its structure.
int i;
for(i=0; i < this->NumberOfPieces; ++i)
{
// Open the piece's element.
os << nextIndent << "<Piece";
this->WriteAppendedPieceAttributes(i);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
this->DeletePositionArrays();
return 0;
}
os << ">\n";
this->WriteAppendedPiece(i, nextIndent.GetNextIndent());
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
this->DeletePositionArrays();
return 0;
}
// Close the piece's element.
os << nextIndent << "</Piece>\n";
}
}
else
{
// Write just the requested piece.
// Open the piece's element.
os << nextIndent << "<Piece";
this->WriteAppendedPieceAttributes(this->WritePiece);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
this->DeletePositionArrays();
return 0;
}
os << ">\n";
this->WriteAppendedPiece(this->WritePiece, nextIndent.GetNextIndent());
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
this->DeletePositionArrays();
return 0;
}
// Close the piece's element.
os << nextIndent << "</Piece>\n";
}
// Close the primary element.
os << indent << "</" << this->GetDataSetName() << ">\n";
os.flush();
if (os.fail())
{
this->SetErrorCode(vtkErrorCode::OutOfDiskSpaceError);
this->DeletePositionArrays();
return 0;
}
this->StartAppendedData();
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
this->DeletePositionArrays();
return 0;
}
}
return 1;
}
//----------------------------------------------------------------------------
int vtkXMLUnstructuredDataWriter::WriteAPiece()
{
vtkIndent indent = vtkIndent().GetNextIndent();
int result=1;
if(this->DataMode == vtkXMLWriter::Appended)
{
this->WriteAppendedPieceData(this->CurrentPiece);
}
else
{
result = this->WriteInlineMode(indent);
}
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
this->DeletePositionArrays();
result = 0;
}
return result;
}
//----------------------------------------------------------------------------
int vtkXMLUnstructuredDataWriter::WriteFooter()
{
vtkIndent indent = vtkIndent().GetNextIndent();
ostream& os = *(this->Stream);
if(this->DataMode == vtkXMLWriter::Appended)
{
this->DeletePositionArrays();
this->EndAppendedData();
}
else
{
// Close the primary element.
os << indent << "</" << this->GetDataSetName() << ">\n";
os.flush();
if (os.fail())
{
return 0;
}
}
return 1;
}
//----------------------------------------------------------------------------
int vtkXMLUnstructuredDataWriter::WriteInlineMode(vtkIndent indent)
{
ostream& os = *(this->Stream);
vtkIndent nextIndent = indent.GetNextIndent();
// Open the piece's element.
os << nextIndent << "<Piece";
this->WriteInlinePieceAttributes();
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return 0;
}
os << ">\n";
this->WriteInlinePiece(nextIndent.GetNextIndent());
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return 0;
}
// Close the piece's element.
os << nextIndent << "</Piece>\n";
return 1;
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteInlinePieceAttributes()
{
vtkPointSet* input = this->GetInputAsPointSet();
this->WriteScalarAttribute("NumberOfPoints",
input->GetNumberOfPoints());
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteInlinePiece(vtkIndent indent)
{
vtkPointSet* input = this->GetInputAsPointSet();
// Split progress among point data, cell data, and point arrays.
float progressRange[2] = {0,0};
this->GetProgressRange(progressRange);
float fractions[4];
this->CalculateDataFractions(fractions);
// Set the range of progress for the point data arrays.
this->SetProgressRange(progressRange, 0, fractions);
// Write the point data arrays.
this->WritePointDataInline(input->GetPointData(), indent);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
// Set the range of progress for the cell data arrays.
this->SetProgressRange(progressRange, 1, fractions);
// Write the cell data arrays.
this->WriteCellDataInline(input->GetCellData(), indent);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
// Set the range of progress for the point specification array.
this->SetProgressRange(progressRange, 2, fractions);
// Write the point specification array.
this->WritePointsInline(input->GetPoints(), indent);
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteAppendedPieceAttributes(int index)
{
this->NumberOfPointsPositions[index] =
this->ReserveAttributeSpace("NumberOfPoints");
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteAppendedPiece(int index,
vtkIndent indent)
{
vtkPointSet* input = this->GetInputAsPointSet();
this->WritePointDataAppended(input->GetPointData(), indent,
&this->PointDataOM->GetPiece(index));
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
this->WriteCellDataAppended(input->GetCellData(), indent,
&this->CellDataOM->GetPiece(index));
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
this->WritePointsAppended(input->GetPoints(), indent,
&this->PointsOM->GetPiece(index));
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteAppendedPieceData(int index)
{
ostream& os = *(this->Stream);
vtkPointSet* input = this->GetInputAsPointSet();
std::streampos returnPosition = os.tellp();
os.seekp(std::streampos(this->NumberOfPointsPositions[index]));
vtkPoints* points = input->GetPoints();
this->WriteScalarAttribute("NumberOfPoints",
(points?points->GetNumberOfPoints():0));
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
os.seekp(returnPosition);
// Split progress among point data, cell data, and point arrays.
float progressRange[2] = {0,0};
this->GetProgressRange(progressRange);
float fractions[4];
this->CalculateDataFractions(fractions);
// Set the range of progress for the point data arrays.
this->SetProgressRange(progressRange, 0, fractions);
// Write the point data arrays.
this->WritePointDataAppendedData(input->GetPointData(), this->CurrentTimeIndex,
&this->PointDataOM->GetPiece(index));
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
// Set the range of progress for the cell data arrays.
this->SetProgressRange(progressRange, 1, fractions);
// Write the cell data arrays.
this->WriteCellDataAppendedData(input->GetCellData(), this->CurrentTimeIndex,
&this->CellDataOM->GetPiece(index));
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
// Set the range of progress for the point specification array.
this->SetProgressRange(progressRange, 2, fractions);
// Write the point specification array.
// Since we are writing the point let save the Modified Time of vtkPoints:
this->WritePointsAppendedData(input->GetPoints(), this->CurrentTimeIndex,
&this->PointsOM->GetPiece(index));
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteCellsInline(
const char *name, vtkCellIterator *cellIter, vtkIdType numCells,
vtkIdType cellSizeEstimate, vtkIndent indent)
{
this->ConvertCells(cellIter, numCells, cellSizeEstimate);
// Faces are not supported via this method.
this->Faces->SetNumberOfTuples(0);
this->FaceOffsets->SetNumberOfTuples(0);
vtkNew<vtkUnsignedCharArray> types;
types->Allocate(numCells);
for (cellIter->InitTraversal(); !cellIter->IsDoneWithTraversal();
cellIter->GoToNextCell())
{
types->InsertNextValue(static_cast<unsigned char>(cellIter->GetCellType()));
}
this->WriteCellsInlineWorker(name, types.GetPointer(), indent);
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteCellsInline(const char* name,
vtkCellArray* cells,
vtkDataArray* types,
vtkIndent indent)
{
this->WriteCellsInline(name, cells, types, NULL, NULL, indent);
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteCellsInline(const char* name,
vtkCellArray* cells, vtkDataArray* types,
vtkIdTypeArray* faces, vtkIdTypeArray* faceOffsets,
vtkIndent indent)
{
if(cells)
{
this->ConvertCells(cells);
}
this->ConvertFaces(faces, faceOffsets);
this->WriteCellsInlineWorker(name, types, indent);
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteCellsInlineWorker(
const char *name, vtkDataArray *types, vtkIndent indent)
{
ostream& os = *(this->Stream);
os << indent << "<" << name << ">\n";
// Split progress by cell connectivity, offset, and type arrays.
float progressRange[2] = {0,0};
this->GetProgressRange(progressRange);
float fractions[6];
this->CalculateCellFractions(fractions, types?types->GetNumberOfTuples():0);
// Set the range of progress for the connectivity array.
this->SetProgressRange(progressRange, 0, fractions);
// Write the connectivity array.
this->WriteArrayInline(this->CellPoints, indent.GetNextIndent());
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
// Set the range of progress for the offsets array.
this->SetProgressRange(progressRange, 1, fractions);
// Write the offsets array.
this->WriteArrayInline(this->CellOffsets, indent.GetNextIndent());
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
if(types)
{
// Set the range of progress for the types array.
this->SetProgressRange(progressRange, 2, fractions);
// Write the types array.
this->WriteArrayInline(types, indent.GetNextIndent(), "types");
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
}
if (this->Faces->GetNumberOfTuples())
{
// Set the range of progress for the faces array.
this->SetProgressRange(progressRange, 3, fractions);
// Write the connectivity array.
this->WriteArrayInline(this->Faces, indent.GetNextIndent(), "faces");
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
}
if (this->FaceOffsets->GetNumberOfTuples())
{
// Set the range of progress for the face offset array.
this->SetProgressRange(progressRange, 4, fractions);
// Write the face offsets array.
this->WriteArrayInline(this->FaceOffsets, indent.GetNextIndent(), "faceoffsets");
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
}
os << indent << "</" << name << ">\n";
os.flush();
if (os.fail())
{
this->SetErrorCode(vtkErrorCode::OutOfDiskSpaceError);
}
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteCellsAppended(const char* name,
vtkDataArray* types,
vtkIndent indent,
OffsetsManagerGroup *cellsManager)
{
this->WriteCellsAppended(name, types, 0, 0, indent, cellsManager);
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteCellsAppended(const char* name,
vtkDataArray* types,
vtkIdTypeArray* faces,
vtkIdTypeArray* faceOffsets,
vtkIndent indent,
OffsetsManagerGroup *cellsManager)
{
this->ConvertFaces(faces,faceOffsets);
ostream& os = *(this->Stream);
os << indent << "<" << name << ">\n";
// Helper for the 'for' loop
vtkDataArray *allcells[5];
allcells[0] = this->CellPoints;
allcells[1] = this->CellOffsets;
allcells[2] = types;
allcells[3] = this->Faces->GetNumberOfTuples() ? this->Faces : 0;
allcells[4] = this->FaceOffsets->GetNumberOfTuples() ? this->FaceOffsets : 0;
const char *names[] = {NULL, NULL, "types", NULL, NULL};
for(int t=0; t<this->NumberOfTimeSteps; t++)
{
for(int i=0; i<5; i++)
{
if(allcells[i])
{
this->WriteArrayAppended(allcells[i], indent.GetNextIndent(),
cellsManager->GetElement(i), names[i], 0, t);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
}
}
}
os << indent << "</" << name << ">\n";
os.flush();
if (os.fail())
{
this->SetErrorCode(vtkErrorCode::OutOfDiskSpaceError);
return;
}
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteCellsAppended(
const char *name, vtkCellIterator *cellIter, vtkIdType numCells,
vtkIndent indent, OffsetsManagerGroup *cellsManager)
{
vtkNew<vtkUnsignedCharArray> types;
types->Allocate(numCells);
for (cellIter->InitTraversal(); !cellIter->IsDoneWithTraversal();
cellIter->GoToNextCell())
{
types->InsertNextValue(static_cast<unsigned char>(cellIter->GetCellType()));
}
this->WriteCellsAppended(name, types.GetPointer(), 0, 0, indent, cellsManager);
}
//----------------------------------------------------------------------------
void
vtkXMLUnstructuredDataWriter::WriteCellsAppendedData(vtkCellArray* cells,
vtkDataArray* types,
int timestep,
OffsetsManagerGroup *cellsManager)
{
this->WriteCellsAppendedData(cells, types, NULL, NULL, timestep, cellsManager);
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteCellsAppendedData(
vtkCellIterator *cellIter, vtkIdType numCells, vtkIdType cellSizeEstimate,
int timestep, OffsetsManagerGroup *cellsManager)
{
this->ConvertCells(cellIter, numCells, cellSizeEstimate);
// Faces are not supported by this method:
this->Faces->SetNumberOfTuples(0);
this->FaceOffsets->SetNumberOfTuples(0);
vtkNew<vtkUnsignedCharArray> types;
types->Allocate(this->CellOffsets->GetNumberOfTuples() + 1);
for(cellIter->InitTraversal(); !cellIter->IsDoneWithTraversal();
cellIter->GoToNextCell())
{
types->InsertNextValue(static_cast<unsigned char>(cellIter->GetCellType()));
}
this->WriteCellsAppendedDataWorker(types.GetPointer(), timestep,
cellsManager);
}
//----------------------------------------------------------------------------
void
vtkXMLUnstructuredDataWriter::WriteCellsAppendedData(vtkCellArray* cells,
vtkDataArray* types,
vtkIdTypeArray* faces,
vtkIdTypeArray* faceOffsets,
int timestep,
OffsetsManagerGroup *cellsManager)
{
if (cells)
{
this->ConvertCells(cells);
}
this->ConvertFaces(faces, faceOffsets);
this->WriteCellsAppendedDataWorker(types, timestep, cellsManager);
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::WriteCellsAppendedDataWorker(
vtkDataArray *types, int timestep, OffsetsManagerGroup *cellsManager)
{
// Split progress by cell connectivity, offset, and type arrays.
float progressRange[5] = {0,0,0,0,0};
this->GetProgressRange(progressRange);
float fractions[6];
this->CalculateCellFractions(fractions, types?types->GetNumberOfTuples():0);
// Helper for the 'for' loop
vtkDataArray *allcells[5];
allcells[0] = this->CellPoints;
allcells[1] = this->CellOffsets;
allcells[2] = types;
allcells[3] = this->Faces->GetNumberOfTuples() ? this->Faces : 0;
allcells[4] = this->FaceOffsets->GetNumberOfTuples() ? this->FaceOffsets : 0;
for(int i=0; i<5; i++)
{
if(allcells[i])
{
// Set the range of progress for the connectivity array.
this->SetProgressRange(progressRange, i, fractions);
vtkMTimeType mtime = allcells[i]->GetMTime();
vtkMTimeType &cellsMTime = cellsManager->GetElement(i).GetLastMTime();
// Only write cells if MTime has changed
if( cellsMTime != mtime )
{
cellsMTime = mtime;
// Write the connectivity array.
this->WriteArrayAppendedData(allcells[i],
cellsManager->GetElement(i).GetPosition(timestep),
cellsManager->GetElement(i).GetOffsetValue(timestep));
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
}
else
{
// One timestep must have already been written or the
// mtime would have changed and we would not be here.
assert( timestep > 0 );
cellsManager->GetElement(i).GetOffsetValue(timestep) =
cellsManager->GetElement(i).GetOffsetValue(timestep-1);
this->ForwardAppendedDataOffset(cellsManager->GetElement(i).GetPosition(timestep),
cellsManager->GetElement(i).GetOffsetValue(timestep),
"offset" );
}
}
}
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::ConvertCells(
vtkCellIterator *cellIter, vtkIdType numCells, vtkIdType cellSizeEstimate)
{
this->CellPoints->Allocate(numCells * cellSizeEstimate);
this->CellOffsets->Allocate(numCells);
for (cellIter->InitTraversal(); !cellIter->IsDoneWithTraversal();
cellIter->GoToNextCell())
{
vtkIdType *begin = cellIter->GetPointIds()->GetPointer(0);
vtkIdType *end = begin + cellIter->GetNumberOfPoints();
while (begin != end)
{
this->CellPoints->InsertNextValue(*begin++);
}
this->CellOffsets->InsertNextValue(this->CellPoints->GetNumberOfTuples());
}
this->CellPoints->Squeeze();
this->CellOffsets->Squeeze();
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::ConvertCells(vtkCellArray* cells)
{
vtkIdTypeArray* connectivity = cells->GetData();
vtkIdType numberOfCells = cells->GetNumberOfCells();
vtkIdType numberOfTuples = connectivity->GetNumberOfTuples();
this->CellPoints->SetNumberOfTuples(numberOfTuples - numberOfCells);
this->CellOffsets->SetNumberOfTuples(numberOfCells);
vtkIdType* inCell = connectivity->GetPointer(0);
vtkIdType* outCellPointsBase = this->CellPoints->GetPointer(0);
vtkIdType* outCellPoints = outCellPointsBase;
vtkIdType* outCellOffset = this->CellOffsets->GetPointer(0);
vtkIdType i;
for(i=0;i < numberOfCells; ++i)
{
vtkIdType numberOfPoints = *inCell++;
memcpy(outCellPoints, inCell, sizeof(vtkIdType)*numberOfPoints);
outCellPoints += numberOfPoints;
inCell += numberOfPoints;
*outCellOffset++ = outCellPoints - outCellPointsBase;
}
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::ConvertFaces(vtkIdTypeArray* faces,
vtkIdTypeArray* faceOffsets)
{
if (!faces || !faces->GetNumberOfTuples() ||
!faceOffsets || !faceOffsets->GetNumberOfTuples())
{
this->Faces->SetNumberOfTuples(0);
this->FaceOffsets->SetNumberOfTuples(0);
return;
}
// copy faces stream.
this->Faces->SetNumberOfTuples(faces->GetNumberOfTuples());
vtkIdType * fromPtr = faces->GetPointer(0);
vtkIdType * toPtr = this->Faces->GetPointer(0);
for (vtkIdType i = 0; i < faces->GetNumberOfTuples(); i++)
{
*toPtr++ = *fromPtr++;
}
// this->FaceOffsets point to the face arrays of cells. Specifically
// FaceOffsets[i] points to the end of the i-th cell's faces + 1. While
// input faceOffsets[i] points to the beginning of the i-th cell. Note
// that for both arrays, a non-polyhedron cell has an offset of -1.
vtkIdType numberOfCells = faceOffsets->GetNumberOfTuples();
this->FaceOffsets->SetNumberOfTuples(numberOfCells);
vtkIdType* newOffsetPtr = this->FaceOffsets->GetPointer(0);
vtkIdType* oldOffsetPtr = faceOffsets->GetPointer(0);
vtkIdType* facesPtr = this->Faces->GetPointer(0);
bool foundPolyhedronCell = false;
for (vtkIdType i = 0; i < numberOfCells; i++)
{
if (oldOffsetPtr[i] < 0) //non-polyhedron cell
{
newOffsetPtr[i] = -1;
}
else // polyhedron cell
{
foundPolyhedronCell = true;
// read numberOfFaces in a cell
vtkIdType currLoc = oldOffsetPtr[i];
vtkIdType numberOfCellFaces = facesPtr[currLoc];
currLoc += 1;
for (vtkIdType j = 0; j < numberOfCellFaces; j++)
{
// read numberOfPoints in a face
vtkIdType numberOfFacePoints = facesPtr[currLoc];
currLoc += numberOfFacePoints + 1;
}
newOffsetPtr[i] = currLoc;
}
}
if (!foundPolyhedronCell)
{
this->Faces->SetNumberOfTuples(0);
this->FaceOffsets->SetNumberOfTuples(0);
}
return;
}
//----------------------------------------------------------------------------
vtkIdType vtkXMLUnstructuredDataWriter::GetNumberOfInputPoints()
{
vtkPointSet* input = this->GetInputAsPointSet();
vtkPoints* points = input->GetPoints();
return points?points->GetNumberOfPoints():0;
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::CalculateDataFractions(float* fractions)
{
// Calculate the fraction of point/cell data and point
// specifications contributed by each component.
vtkPointSet* input = this->GetInputAsPointSet();
int pdArrays = input->GetPointData()->GetNumberOfArrays();
int cdArrays = input->GetCellData()->GetNumberOfArrays();
vtkIdType pdSize = pdArrays*this->GetNumberOfInputPoints();
vtkIdType cdSize = cdArrays*this->GetNumberOfInputCells();
int total = (pdSize+cdSize+this->GetNumberOfInputPoints());
if(total == 0)
{
total = 1;
}
fractions[0] = 0;
fractions[1] = float(pdSize)/total;
fractions[2] = float(pdSize+cdSize)/total;
fractions[3] = 1;
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::CalculateCellFractions(float* fractions,
vtkIdType typesSize)
{
// Calculate the fraction of cell specification data contributed by
// each of the connectivity, offset, and type arrays.
vtkIdType connectSize = this->CellPoints->GetNumberOfTuples();
vtkIdType offsetSize = this->CellOffsets->GetNumberOfTuples();
vtkIdType faceSize = this->Faces ? this->Faces->GetNumberOfTuples() : 0;
vtkIdType faceoffsetSize = this->FaceOffsets ?
this->FaceOffsets->GetNumberOfTuples() : 0;
vtkIdType total = connectSize+offsetSize+faceSize+faceoffsetSize+typesSize;
if(total == 0)
{
total = 1;
}
fractions[0] = 0;
fractions[1] = float(connectSize)/total;
fractions[2] = float(connectSize+offsetSize)/total;
fractions[3] = float(connectSize+offsetSize+faceSize)/total;
fractions[4] = float(connectSize+offsetSize+faceSize+faceoffsetSize)/total;
fractions[5] = 1;
}
//----------------------------------------------------------------------------
void vtkXMLUnstructuredDataWriter::SetInputUpdateExtent(
int piece, int numPieces, int ghostLevel)
{
vtkInformation* inInfo =
this->GetExecutive()->GetInputInformation(0, 0);
inInfo->Set(
vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(), numPieces);
inInfo->Set(
vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(), piece);
inInfo->Set(
vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(), ghostLevel);
}