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/vtkXMLCompositeDataReader.cxx

422 lines
12 KiB
C++

/*=========================================================================
Program: ParaView
Module: vtkXMLCompositeDataReader.cxx
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 "vtkXMLCompositeDataReader.h"
#include "vtkCompositeDataPipeline.h"
#include "vtkCompositeDataSet.h"
#include "vtkDataArraySelection.h"
#include "vtkDataSet.h"
#include "vtkEventForwarderCommand.h"
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkInformation.h"
#include "vtkInformationIntegerKey.h"
#include "vtkInformationIntegerVectorKey.h"
#include "vtkInformationVector.h"
#include "vtkInstantiator.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkSmartPointer.h"
#include "vtkUniformGrid.h"
#include "vtkXMLDataElement.h"
#include "vtkXMLImageDataReader.h"
#include "vtkXMLPolyDataReader.h"
#include "vtkXMLRectilinearGridReader.h"
#include "vtkXMLStructuredGridReader.h"
#include "vtkXMLUnstructuredGridReader.h"
#include <map>
#include <set>
#include <string>
#include <vector>
#include <vtksys/SystemTools.hxx>
struct vtkXMLCompositeDataReaderEntry
{
const char* extension;
const char* name;
};
struct vtkXMLCompositeDataReaderInternals
{
vtkSmartPointer<vtkXMLDataElement> Root;
typedef std::map<std::string, vtkSmartPointer<vtkXMLReader> > ReadersType;
ReadersType Readers;
static const vtkXMLCompositeDataReaderEntry ReaderList[];
unsigned int MinDataset;
unsigned int MaxDataset;
vtkXMLCompositeDataReaderInternals()
{
this->MinDataset = 0;
this->MaxDataset = 0;
}
std::set<int> UpdateIndices;
bool HasUpdateRestriction;
};
//----------------------------------------------------------------------------
vtkXMLCompositeDataReader::vtkXMLCompositeDataReader()
{
this->Internal = new vtkXMLCompositeDataReaderInternals;
}
//----------------------------------------------------------------------------
vtkXMLCompositeDataReader::~vtkXMLCompositeDataReader()
{
delete this->Internal;
}
//----------------------------------------------------------------------------
void vtkXMLCompositeDataReader::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
//----------------------------------------------------------------------------
const char* vtkXMLCompositeDataReader::GetDataSetName()
{
return "vtkCompositeDataSet";
}
//----------------------------------------------------------------------------
void vtkXMLCompositeDataReader::SetupEmptyOutput()
{
this->GetCurrentOutput()->Initialize();
}
//----------------------------------------------------------------------------
int vtkXMLCompositeDataReader::FillOutputPortInformation(
int vtkNotUsed(port), vtkInformation* info)
{
info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkCompositeDataSet");
return 1;
}
//----------------------------------------------------------------------------
vtkExecutive* vtkXMLCompositeDataReader::CreateDefaultExecutive()
{
return vtkCompositeDataPipeline::New();
}
//----------------------------------------------------------------------------
vtkCompositeDataSet* vtkXMLCompositeDataReader::GetOutput()
{
return this->GetOutput(0);
}
//----------------------------------------------------------------------------
vtkCompositeDataSet* vtkXMLCompositeDataReader::GetOutput(int port)
{
vtkDataObject* output =
vtkCompositeDataPipeline::SafeDownCast(this->GetExecutive())->
GetCompositeOutputData(port);
return vtkCompositeDataSet::SafeDownCast(output);
}
//----------------------------------------------------------------------------
int vtkXMLCompositeDataReader::ReadPrimaryElement(vtkXMLDataElement* ePrimary)
{
if (!this->Superclass::ReadPrimaryElement(ePrimary))
{
return 0;
}
// Simply save the XML tree. We'll iterate over it later.
this->Internal->Root = ePrimary;
return 1;
}
//----------------------------------------------------------------------------
vtkXMLDataElement* vtkXMLCompositeDataReader::GetPrimaryElement()
{
return this->Internal->Root;
}
//----------------------------------------------------------------------------
vtkXMLReader* vtkXMLCompositeDataReader::GetReaderOfType(const char* type)
{
if (!type)
{
return 0;
}
vtkXMLCompositeDataReaderInternals::ReadersType::iterator iter =
this->Internal->Readers.find(type);
if (iter != this->Internal->Readers.end())
{
return iter->second.GetPointer();
}
vtkXMLReader* reader = 0;
if (strcmp(type, "vtkXMLImageDataReader") == 0)
{
reader = vtkXMLImageDataReader::New();
}
else if (strcmp(type,"vtkXMLUnstructuredGridReader") == 0)
{
reader = vtkXMLUnstructuredGridReader::New();
}
else if (strcmp(type,"vtkXMLPolyDataReader") == 0)
{
reader = vtkXMLPolyDataReader::New();
}
else if (strcmp(type,"vtkXMLRectilinearGridReader") == 0)
{
reader = vtkXMLRectilinearGridReader::New();
}
else if (strcmp(type,"vtkXMLStructuredGridReader") == 0)
{
reader = vtkXMLStructuredGridReader::New();
}
if (!reader)
{
// If all fails, Use the instantiator to create the reader.
reader = vtkXMLReader::SafeDownCast(vtkInstantiator::CreateInstance(type));
}
if (reader)
{
if (this->GetParserErrorObserver())
{
reader->SetParserErrorObserver(this->GetParserErrorObserver());
}
if (this->HasObserver("ErrorEvent"))
{
vtkNew<vtkEventForwarderCommand> fwd;
fwd->SetTarget(this);
reader->AddObserver("ErrorEvent", fwd.GetPointer());
}
this->Internal->Readers[type] = reader;
reader->Delete();
}
return reader;
}
//----------------------------------------------------------------------------
unsigned int vtkXMLCompositeDataReader::CountLeaves(vtkXMLDataElement* elem)
{
unsigned int count = 0;
if (elem)
{
unsigned int max = elem->GetNumberOfNestedElements();
for (unsigned int cc=0; cc < max; ++cc)
{
vtkXMLDataElement* child = elem->GetNestedElement(cc);
if (child && child->GetName())
{
if (strcmp(child->GetName(), "DataSet")==0)
{
count++;
}
else
{
count += this->CountLeaves(child);
}
}
}
}
return count;
}
//----------------------------------------------------------------------------
void vtkXMLCompositeDataReader::ReadXMLData()
{
vtkInformation* info = this->GetCurrentOutputInformation();
unsigned int updatePiece = static_cast<unsigned int>(
info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
unsigned int updateNumPieces = static_cast<unsigned int>(
info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
vtkDataObject* doOutput =
info->Get(vtkDataObject::DATA_OBJECT());
vtkCompositeDataSet* composite =
vtkCompositeDataSet::SafeDownCast(doOutput);
if (!composite)
{
return;
}
// Find the path to this file in case the internal files are
// specified as relative paths.
std::string filePath = this->FileName;
std::string::size_type pos = filePath.find_last_of("/\\");
if (pos != filePath.npos)
{
filePath = filePath.substr(0, pos);
}
else
{
filePath = "";
}
// In earlier implementation only dataset with a group were distributed among
// the processes. In this implementation, we distribute all leaf datasets
// among the processes.
// Determine the leaves that this process is going to read.
unsigned int numDatasets = this->CountLeaves(this->GetPrimaryElement());
unsigned int numDatasetsPerPiece = 1;
unsigned int remaining_blocks = 0;
if (updateNumPieces < numDatasets)
{
numDatasetsPerPiece = numDatasets / updateNumPieces;
remaining_blocks = numDatasets % updateNumPieces;
}
if (updatePiece < remaining_blocks)
{
this->Internal->MinDataset = (numDatasetsPerPiece+1)*updatePiece;
this->Internal->MaxDataset = this->Internal->MinDataset + numDatasetsPerPiece + 1;
}
else
{
this->Internal->MinDataset = (numDatasetsPerPiece +1)* remaining_blocks +
numDatasetsPerPiece * (updatePiece-remaining_blocks);
this->Internal->MaxDataset = this->Internal->MinDataset + numDatasetsPerPiece;
}
vtkInformation* outInfo = this->GetCurrentOutputInformation();
if (outInfo->Has(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES()))
{
this->Internal->HasUpdateRestriction = true;
this->Internal->UpdateIndices = std::set<int>();
int length = outInfo->Length(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES());
if (length > 0)
{
int* idx = outInfo->Get(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES());
this->Internal->UpdateIndices = std::set<int>(idx, idx+length);
}
}
else
{
this->Internal->HasUpdateRestriction = false;
}
// All process create the entire tree structure however, only each one only
// reads the datasets assigned to it.
unsigned int dataSetIndex=0;
this->ReadComposite(this->GetPrimaryElement(), composite, filePath.c_str(), dataSetIndex);
}
//----------------------------------------------------------------------------
int vtkXMLCompositeDataReader::ShouldReadDataSet(unsigned int dataSetIndex)
{
bool shouldRead =
(dataSetIndex >= this->Internal->MinDataset &&
dataSetIndex < this->Internal->MaxDataset);
if (shouldRead && this->Internal->HasUpdateRestriction)
{
if (this->Internal->UpdateIndices.find(dataSetIndex) ==
this->Internal->UpdateIndices.end())
{
shouldRead = false;
}
}
return shouldRead;
}
//----------------------------------------------------------------------------
vtkDataSet* vtkXMLCompositeDataReader::ReadDataset(vtkXMLDataElement* xmlElem,
const char* filePath)
{
// Construct the name of the internal file.
const char* file = xmlElem->GetAttribute("file");
if (!file)
{
return 0;
}
std::string fileName;
if (!(file[0] == '/' || file[1] == ':'))
{
fileName = filePath;
if (fileName.length())
{
fileName += "/";
}
}
fileName += file;
// Get the file extension.
std::string ext = vtksys::SystemTools::GetFilenameLastExtension(fileName);
if (ext.size() > 0)
{
// remote "." from the extension.
ext = &(ext.c_str()[1]);
}
// Search for the reader matching this extension.
const char* rname = 0;
for(const vtkXMLCompositeDataReaderEntry* readerEntry =
this->Internal->ReaderList;
!rname && readerEntry->extension; ++readerEntry)
{
if (ext == readerEntry->extension)
{
rname = readerEntry->name;
}
}
vtkXMLReader* reader = this->GetReaderOfType(rname);
if (!reader)
{
vtkErrorMacro("Could not create reader for " << rname);
return 0;
}
reader->SetFileName(fileName.c_str());
// initialize array selection so we don't have any residual array selections
// from previous use of the reader.
reader->GetPointDataArraySelection()->RemoveAllArrays();
reader->GetCellDataArraySelection()->RemoveAllArrays();
reader->Update();
vtkDataSet* output = reader->GetOutputAsDataSet();
if (!output)
{
return 0;
}
vtkDataSet* outputCopy = output->NewInstance();
outputCopy->ShallowCopy(output);
return outputCopy;
}
//----------------------------------------------------------------------------
int vtkXMLCompositeDataReader::RequestInformation(
vtkInformation *request,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
this->Superclass::RequestInformation(request, inputVector, outputVector);
vtkInformation* info = outputVector->GetInformationObject(0);
info->Set(
CAN_HANDLE_PIECE_REQUEST(), 1);
return 1;
}
//----------------------------------------------------------------------------
const vtkXMLCompositeDataReaderEntry
vtkXMLCompositeDataReaderInternals::ReaderList[] =
{
{"vtp", "vtkXMLPolyDataReader"},
{"vtu", "vtkXMLUnstructuredGridReader"},
{"vti", "vtkXMLImageDataReader"},
{"vtr", "vtkXMLRectilinearGridReader"},
{"vts", "vtkXMLStructuredGridReader"},
{0, 0}
};