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.
 
 
 
 
 
 

365 lines
11 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkXMLPDataWriter.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 "vtkXMLPDataWriter.h"
#include "vtkCallbackCommand.h"
#include "vtkDataSet.h"
#include "vtkErrorCode.h"
vtkCxxRevisionMacro(vtkXMLPDataWriter, "$Revision: 1.15 $");
//----------------------------------------------------------------------------
vtkXMLPDataWriter::vtkXMLPDataWriter()
{
this->StartPiece = 0;
this->EndPiece = 0;
this->NumberOfPieces = 1;
this->GhostLevel = 0;
this->WriteSummaryFileInitialized = 0;
this->WriteSummaryFile = 0;
this->PathName = 0;
this->FileNameBase = 0;
this->FileNameExtension = 0;
this->PieceFileNameExtension = 0;
// Setup a callback for the internal writer to report progress.
this->ProgressObserver = vtkCallbackCommand::New();
this->ProgressObserver->SetCallback(&vtkXMLPDataWriter::ProgressCallbackFunction);
this->ProgressObserver->SetClientData(this);
}
//----------------------------------------------------------------------------
vtkXMLPDataWriter::~vtkXMLPDataWriter()
{
if(this->PathName) { delete [] this->PathName; }
if(this->FileNameBase) { delete [] this->FileNameBase; }
if(this->FileNameExtension) { delete [] this->FileNameExtension; }
if(this->PieceFileNameExtension) { delete [] this->PieceFileNameExtension; }
this->ProgressObserver->Delete();
}
//----------------------------------------------------------------------------
void vtkXMLPDataWriter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "NumberOfPieces: " << this->NumberOfPieces << "\n";
os << indent << "StartPiece: " << this->StartPiece << "\n";
os << indent << "EndPiece: " << this->EndPiece << "\n";
os << indent << "GhostLevel: " << this->GhostLevel << "\n";
os << indent << "WriteSummaryFile: " << this->WriteSummaryFile << "\n";
}
//----------------------------------------------------------------------------
void vtkXMLPDataWriter::SetWriteSummaryFile(int flag)
{
this->WriteSummaryFileInitialized = 1;
vtkDebugMacro(<< this->GetClassName() << " ("
<< this << "): setting WriteSummaryFile to " << flag);
if(this->WriteSummaryFile != flag)
{
this->WriteSummaryFile = flag;
this->Modified();
}
}
//----------------------------------------------------------------------------
int vtkXMLPDataWriter::WriteInternal()
{
// Prepare the file name.
this->SplitFileName();
// Write the pieces now so the data are up to date.
int result = this->WritePieces();
if (!result)
{
return result;
}
// Decide whether to write the summary file.
int writeSummary = 0;
if(this->WriteSummaryFileInitialized)
{
writeSummary = this->WriteSummaryFile;
}
else if(this->StartPiece == 0)
{
writeSummary = 1;
}
// Write the summary file if requested.
if(result && writeSummary)
{
if(!this->Superclass::WriteInternal())
{
int i;
vtkErrorMacro("Ran out of disk space; deleting file(s) already written");
for (i = this->StartPiece; i < this->EndPiece; i++)
{
char* fileName = this->CreatePieceFileName(i, this->PathName);
this->DeleteAFile(fileName);
delete [] fileName;
}
return 0;
}
}
return result;
}
//----------------------------------------------------------------------------
void vtkXMLPDataWriter::WritePrimaryElementAttributes(ostream &, vtkIndent)
{
this->WriteScalarAttribute("GhostLevel", this->GhostLevel);
}
//----------------------------------------------------------------------------
int vtkXMLPDataWriter::WriteData()
{
// Write the summary file.
ostream& os = *(this->Stream);
vtkIndent indent = vtkIndent().GetNextIndent();
vtkIndent nextIndent = indent.GetNextIndent();
this->StartFile();
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return 0;
}
os << indent << "<" << this->GetDataSetName();
this->WritePrimaryElementAttributes(os, indent);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return 0;
}
os << ">\n";
// Write the information needed for a reader to produce the output's
// information during UpdateInformation without reading a piece.
this->WritePData(indent.GetNextIndent());
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return 0;
}
// Write the elements referencing each piece and its file.
int i;
for(i=0;i < this->NumberOfPieces; ++i)
{
os << nextIndent << "<Piece";
this->WritePPieceAttributes(i);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return 0;
}
os << "/>\n";
}
os << indent << "</" << this->GetDataSetName() << ">\n";
this->EndFile();
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return 0;
}
return 1;
}
//----------------------------------------------------------------------------
void vtkXMLPDataWriter::WritePData(vtkIndent indent)
{
vtkDataSet* input = this->GetInputAsDataSet();
this->WritePPointData(input->GetPointData(), indent);
if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
{
return;
}
this->WritePCellData(input->GetCellData(), indent);
}
//----------------------------------------------------------------------------
void vtkXMLPDataWriter::WritePPieceAttributes(int index)
{
char* fileName = this->CreatePieceFileName(index);
this->WriteStringAttribute("Source", fileName);
delete [] fileName;
}
//----------------------------------------------------------------------------
void vtkXMLPDataWriter::SplitFileName()
{
// Split the FileName into its PathName, FileNameBase, and
// FileNameExtension components.
size_t length = strlen(this->FileName);
char* fileName = new char[length+1];
strcpy(fileName, this->FileName);
char* begin = fileName;
char* end = fileName + length;
char* s;
#if defined(_WIN32)
// Convert to UNIX-style slashes.
for(s=begin;s != end;++s) { if(*s == '\\') { *s = '/'; } }
#endif
// Extract the path name up to the last '/'.
if(this->PathName) { delete [] this->PathName; this->PathName = 0; }
char* rbegin = end-1;
char* rend = begin-1;
for(s=rbegin;s != rend;--s) { if(*s == '/') { break; } }
if(s >= begin)
{
length = (s-begin)+1;
this->PathName = new char[length+1];
strncpy(this->PathName, this->FileName, length);
this->PathName[length] = '\0';
begin = s+1;
}
// "begin" now points at the beginning of the file name.
// Look for the first "." to pull off the longest extension.
if(this->FileNameExtension)
{ delete [] this->FileNameExtension; this->FileNameExtension = 0; }
for(s=begin; s != end; ++s) { if(*s == '.') { break; } }
if(s < end)
{
length = end-s;
this->FileNameExtension = new char[length+1];
strncpy(this->FileNameExtension, s, length);
this->FileNameExtension[length] = '\0';
end = s;
}
// "end" now points to end of the file name.
if(this->FileNameBase) { delete [] this->FileNameBase; }
length = end-begin;
this->FileNameBase = new char[length+1];
strncpy(this->FileNameBase, begin, length);
this->FileNameBase[length] = '\0';
// Cleanup temporary name.
delete [] fileName;
}
//----------------------------------------------------------------------------
char* vtkXMLPDataWriter::CreatePieceFileName(int index, const char* path)
{
ostrstream fn_with_warning_C4701;
if(path) { fn_with_warning_C4701 << path; }
fn_with_warning_C4701 << this->FileNameBase << "_" << index;
if(this->PieceFileNameExtension)
{ fn_with_warning_C4701 << this->PieceFileNameExtension; }
//if(this->FileNameExtension)
//{ fn_with_warning_C4701 << this->FileNameExtension; }
fn_with_warning_C4701 << ends;
return fn_with_warning_C4701.str();
}
//----------------------------------------------------------------------------
int vtkXMLPDataWriter::WritePieces()
{
// Split progress range by piece. Just assume all pieces are the
// same size.
float progressRange[2] = {0,0};
this->GetProgressRange(progressRange);
// Write each piece from StartPiece to EndPiece.
int i;
for(i=this->StartPiece; i <= this->EndPiece; ++i)
{
this->SetProgressRange(progressRange, i-this->StartPiece,
this->EndPiece-this->StartPiece+1);
if(!this->WritePiece(i))
{
// Writing a piece failed. Delete files for previous pieces and
// abort.
vtkErrorMacro("Ran out of disk space; deleting file(s) already written");
for(int j=this->StartPiece; j < i; ++j)
{
char* fileName = this->CreatePieceFileName(j, this->PathName);
this->DeleteAFile(fileName);
delete [] fileName;
}
return 0;
}
}
return 1;
}
//----------------------------------------------------------------------------
int vtkXMLPDataWriter::WritePiece(int index)
{
// Create the writer for the piece. Its configuration should match
// our own writer.
vtkXMLWriter* pWriter = this->CreatePieceWriter(index);
pWriter->AddObserver(vtkCommand::ProgressEvent, this->ProgressObserver);
// Set the file name.
if(!this->PieceFileNameExtension)
{
const char* ext = pWriter->GetDefaultFileExtension();
this->PieceFileNameExtension = new char[strlen(ext)+2];
this->PieceFileNameExtension[0] = '.';
strcpy(this->PieceFileNameExtension+1, ext);
}
char* fileName = this->CreatePieceFileName(index, this->PathName);
pWriter->SetFileName(fileName);
delete [] fileName;
// Copy the writer settings.
pWriter->SetCompressor(this->Compressor);
pWriter->SetDataMode(this->DataMode);
pWriter->SetByteOrder(this->ByteOrder);
pWriter->SetEncodeAppendedData(this->EncodeAppendedData);
// Write the piece.
int result = pWriter->Write();
this->SetErrorCode(pWriter->GetErrorCode());
// Cleanup.
pWriter->RemoveObserver(this->ProgressObserver);
pWriter->Delete();
return result;
}
//----------------------------------------------------------------------------
void vtkXMLPDataWriter::ProgressCallbackFunction(vtkObject* caller,
unsigned long,
void* clientdata, void*)
{
vtkAlgorithm* w = vtkAlgorithm::SafeDownCast(caller);
if(w)
{
reinterpret_cast<vtkXMLPDataWriter*>(clientdata)->ProgressCallback(w);
}
}
//----------------------------------------------------------------------------
void vtkXMLPDataWriter::ProgressCallback(vtkAlgorithm* w)
{
float width = this->ProgressRange[1]-this->ProgressRange[0];
float internalProgress = w->GetProgress();
float progress = this->ProgressRange[0] + internalProgress*width;
this->UpdateProgressDiscrete(progress);
if(this->AbortExecute)
{
w->SetAbortExecute(1);
}
}