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.
 
 
 
 
 
 

523 lines
12 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkMergeFilter.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 "vtkMergeFilter.h"
#include "vtkCellData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkRectilinearGrid.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkStructuredGrid.h"
#include "vtkStructuredPoints.h"
#include "vtkUnstructuredGrid.h"
vtkCxxRevisionMacro(vtkMergeFilter, "$Revision: 1.69 $");
vtkStandardNewMacro(vtkMergeFilter);
class vtkFieldNode
{
public:
vtkFieldNode(const char* name, vtkDataSet* ptr=0)
{
int length = static_cast<int>(strlen(name));
if (length > 0)
{
this->Name = new char[length+1];
strcpy(this->Name, name);
}
else
{
this->Name = 0;
}
this->Ptr = ptr;
this->Next = 0;
}
~vtkFieldNode()
{
delete[] this->Name;
}
const char* GetName()
{
return Name;
}
vtkDataSet* Ptr;
vtkFieldNode* Next;
private:
vtkFieldNode(const vtkFieldNode&) {}
void operator=(const vtkFieldNode&) {}
char* Name;
};
class vtkFieldList
{
public:
vtkFieldList()
{
this->First = 0;
this->Last = 0;
}
~vtkFieldList()
{
vtkFieldNode* node = this->First;
vtkFieldNode* next;
while(node)
{
next = node->Next;
delete node;
node = next;
}
}
void Add(const char* name, vtkDataSet* ptr)
{
vtkFieldNode* newNode = new vtkFieldNode(name, ptr);
if (!this->First)
{
this->First = newNode;
this->Last = newNode;
}
else
{
this->Last->Next = newNode;
this->Last = newNode;
}
}
friend class vtkFieldListIterator;
private:
vtkFieldNode* First;
vtkFieldNode* Last;
};
class vtkFieldListIterator
{
public:
vtkFieldListIterator(vtkFieldList* list)
{
this->List = list;
this->Position = 0;
}
void Begin()
{
this->Position = this->List->First;
}
void Next()
{
if (this->Position)
{
this->Position = this->Position->Next;
}
}
int End()
{
return this->Position ? 0 : 1;
}
vtkFieldNode* Get()
{
return this->Position;
}
private:
vtkFieldNode* Position;
vtkFieldList* List;
};
//------------------------------------------------------------------------------
// Create object with no input or output.
vtkMergeFilter::vtkMergeFilter()
{
this->FieldList = new vtkFieldList;
this->SetNumberOfInputPorts(6);
}
vtkMergeFilter::~vtkMergeFilter()
{
delete this->FieldList;
}
vtkDataSet* vtkMergeFilter::GetGeometry()
{
if (this->GetNumberOfInputConnections(0) < 1)
{
return NULL;
}
return vtkDataSet::SafeDownCast(
this->GetExecutive()->GetInputData(0, 0));
}
void vtkMergeFilter::SetScalars(vtkDataSet *input)
{
this->SetInput(1, input);
}
vtkDataSet *vtkMergeFilter::GetScalars()
{
if (this->GetNumberOfInputConnections(1) < 1)
{
return NULL;
}
return vtkDataSet::SafeDownCast(
this->GetExecutive()->GetInputData(1, 0));
}
void vtkMergeFilter::SetVectors(vtkDataSet *input)
{
this->SetInput(2, input);
}
vtkDataSet *vtkMergeFilter::GetVectors()
{
if (this->GetNumberOfInputConnections(2) < 1)
{
return NULL;
}
return vtkDataSet::SafeDownCast(
this->GetExecutive()->GetInputData(2, 0));
}
void vtkMergeFilter::SetNormals(vtkDataSet *input)
{
this->SetInput(3, input);
}
vtkDataSet *vtkMergeFilter::GetNormals()
{
if (this->GetNumberOfInputConnections(3) < 1)
{
return NULL;
}
return vtkDataSet::SafeDownCast(
this->GetExecutive()->GetInputData(3, 0));
}
void vtkMergeFilter::SetTCoords(vtkDataSet *input)
{
this->SetInput(4, input);
}
vtkDataSet *vtkMergeFilter::GetTCoords()
{
if (this->GetNumberOfInputConnections(4) < 1)
{
return NULL;
}
return vtkDataSet::SafeDownCast(
this->GetExecutive()->GetInputData(4, 0));
}
void vtkMergeFilter::SetTensors(vtkDataSet *input)
{
this->SetInput(5, input);
}
vtkDataSet *vtkMergeFilter::GetTensors()
{
if (this->GetNumberOfInputConnections(5) < 1)
{
return NULL;
}
return vtkDataSet::SafeDownCast(
this->GetExecutive()->GetInputData(5, 0));
}
void vtkMergeFilter::AddField(const char* name, vtkDataSet* input)
{
this->FieldList->Add(name, input);
}
int vtkMergeFilter::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
// get the info objects
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
vtkInformation *outInfo = outputVector->GetInformationObject(0);
vtkInformation *scalarsInfo = inputVector[1]->GetInformationObject(0);
vtkInformation *vectorsInfo = inputVector[2]->GetInformationObject(0);
vtkInformation *normalsInfo = inputVector[3]->GetInformationObject(0);
vtkInformation *tCoordsInfo = inputVector[4]->GetInformationObject(0);
vtkInformation *tensorsInfo = inputVector[5]->GetInformationObject(0);
// get the input and ouptut
vtkDataSet *input = vtkDataSet::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkDataSet *output = vtkDataSet::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkDataSet *scalarsData = 0;
vtkDataSet *vectorsData = 0;
vtkDataSet *normalsData = 0;
vtkDataSet *tCoordsData = 0;
vtkDataSet *tensorsData = 0;
if (scalarsInfo)
{
scalarsData = vtkDataSet::SafeDownCast(
scalarsInfo->Get(vtkDataObject::DATA_OBJECT()));
}
if (vectorsInfo)
{
vectorsData = vtkDataSet::SafeDownCast(
vectorsInfo->Get(vtkDataObject::DATA_OBJECT()));
}
if (normalsInfo)
{
normalsData = vtkDataSet::SafeDownCast(
normalsInfo->Get(vtkDataObject::DATA_OBJECT()));
}
if (tCoordsInfo)
{
tCoordsData = vtkDataSet::SafeDownCast(
tCoordsInfo->Get(vtkDataObject::DATA_OBJECT()));
}
if (tensorsInfo)
{
tensorsData = vtkDataSet::SafeDownCast(
tensorsInfo->Get(vtkDataObject::DATA_OBJECT()));
}
vtkIdType numPts, numScalars=0, numVectors=0, numNormals=0, numTCoords=0;
vtkIdType numTensors=0;
vtkIdType numCells, numCellScalars=0, numCellVectors=0, numCellNormals=0;
vtkIdType numCellTCoords=0, numCellTensors=0;
vtkPointData *pd;
vtkDataArray *scalars = NULL;
vtkDataArray *vectors = NULL;
vtkDataArray *normals = NULL;
vtkDataArray *tcoords = NULL;
vtkDataArray *tensors = NULL;
vtkCellData *cd;
vtkDataArray *cellScalars = NULL;
vtkDataArray *cellVectors = NULL;
vtkDataArray *cellNormals = NULL;
vtkDataArray *cellTCoords = NULL;
vtkDataArray *cellTensors = NULL;
vtkPointData *outputPD = output->GetPointData();
vtkCellData *outputCD = output->GetCellData();
vtkDebugMacro(<<"Merging data!");
// geometry needs to be copied
output->CopyStructure(input);
if ( (numPts = input->GetNumberOfPoints()) < 1 )
{
vtkWarningMacro(<<"Nothing to merge!");
}
numCells = input->GetNumberOfCells();
if ( scalarsData )
{
pd = scalarsData->GetPointData();
scalars = pd->GetScalars();
if ( scalars != NULL )
{
numScalars = scalars->GetNumberOfTuples();
}
cd = scalarsData->GetCellData();
cellScalars = cd->GetScalars();
if ( cellScalars != NULL )
{
numCellScalars = cellScalars->GetNumberOfTuples();
}
}
if ( vectorsData )
{
pd = vectorsData->GetPointData();
vectors = pd->GetVectors();
if ( vectors != NULL )
{
numVectors= vectors->GetNumberOfTuples();
}
cd = vectorsData->GetCellData();
cellVectors = cd->GetVectors();
if ( cellVectors != NULL )
{
numCellVectors = cellVectors->GetNumberOfTuples();
}
}
if ( normalsData )
{
pd = normalsData->GetPointData();
normals = pd->GetNormals();
if ( normals != NULL )
{
numNormals= normals->GetNumberOfTuples();
}
cd = normalsData->GetCellData();
cellNormals = cd->GetNormals();
if ( cellNormals != NULL )
{
numCellNormals = cellNormals->GetNumberOfTuples();
}
}
if ( tCoordsData )
{
pd = tCoordsData->GetPointData();
tcoords = pd->GetTCoords();
if ( tcoords != NULL )
{
numTCoords= tcoords->GetNumberOfTuples();
}
cd = tCoordsData->GetCellData();
cellTCoords = cd->GetTCoords();
if ( cellTCoords != NULL )
{
numCellTCoords = cellTCoords->GetNumberOfTuples();
}
}
if ( tensorsData )
{
pd = tensorsData->GetPointData();
tensors = pd->GetTensors();
if ( tensors != NULL )
{
numTensors = tensors->GetNumberOfTuples();
}
cd = tensorsData->GetCellData();
cellTensors = cd->GetTensors();
if ( cellTensors != NULL )
{
numCellTensors = cellTensors->GetNumberOfTuples();
}
}
// merge data only if it is consistent
if ( numPts == numScalars )
{
outputPD->SetScalars(scalars);
}
if ( numCells == numCellScalars )
{
outputCD->SetScalars(cellScalars);
}
if ( numPts == numVectors )
{
outputPD->SetVectors(vectors);
}
if ( numCells == numCellVectors )
{
outputCD->SetVectors(cellVectors);
}
if ( numPts == numNormals )
{
outputPD->SetNormals(normals);
}
if ( numCells == numCellNormals )
{
outputCD->SetNormals(cellNormals);
}
if ( numPts == numTCoords )
{
outputPD->SetTCoords(tcoords);
}
if ( numCells == numCellTCoords )
{
outputCD->SetTCoords(cellTCoords);
}
if ( numPts == numTensors )
{
outputPD->SetTensors(tensors);
}
if ( numCells == numCellTensors )
{
outputCD->SetTensors(cellTensors);
}
vtkFieldListIterator it(this->FieldList);
vtkDataArray* da;
const char* name;
vtkIdType num;
for(it.Begin(); !it.End() ; it.Next())
{
pd = it.Get()->Ptr->GetPointData();
cd = it.Get()->Ptr->GetCellData();
name = it.Get()->GetName();
if ( (da=pd->GetArray(name)) )
{
num = da->GetNumberOfTuples();
if (num == numPts)
{
outputPD->AddArray(da);
}
}
if ( (da=cd->GetArray(name)) )
{
num = da->GetNumberOfTuples();
if (num == numPts)
{
outputCD->AddArray(da);
}
}
}
return 1;
}
//----------------------------------------------------------------------------
// Trick: Abstract data types that may or may not be the same type
// (structured/unstructured), but the points/cells match up.
// Output/Geometry may be structured while ScalarInput may be
// unstructured (but really have same triagulation/topology as geometry).
// Just request all the input. Always generate all of the output (todo).
int vtkMergeFilter::RequestUpdateExtent(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *vtkNotUsed(outputVector))
{
vtkInformation *inputInfo;
int idx;
for (idx = 0; idx < 6; ++idx)
{
inputInfo = inputVector[idx]->GetInformationObject(0);
if (inputInfo)
{
inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
0);
inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
1);
inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
0);
inputInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
}
}
return 1;
}
int vtkMergeFilter::FillInputPortInformation(int port, vtkInformation *info)
{
int retval = this->Superclass::FillInputPortInformation(port, info);
if (port > 0)
{
info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
}
return retval;
}
void vtkMergeFilter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
}