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.
 
 
 
 
 
 

316 lines
8.9 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkGenericDataSetTessellator.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 "vtkGenericDataSetTessellator.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkUnstructuredGrid.h"
#include "vtkPointData.h"
#include "vtkTetra.h"
#include "vtkCellArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkIdTypeArray.h"
#include "vtkDoubleArray.h"
#include "vtkMergePoints.h"
#include "vtkGenericDataSet.h"
#include "vtkGenericCellIterator.h"
#include "vtkGenericAdaptorCell.h"
#include "vtkGenericAttributeCollection.h"
#include "vtkGenericAttribute.h"
#include "vtkCellData.h"
#include "vtkGenericCellTessellator.h"
vtkCxxRevisionMacro(vtkGenericDataSetTessellator, "$Revision: 1.13 $");
vtkStandardNewMacro(vtkGenericDataSetTessellator);
//----------------------------------------------------------------------------
//
vtkGenericDataSetTessellator::vtkGenericDataSetTessellator()
{
this->internalPD=vtkPointData::New();
this->KeepCellIds = 1;
this->Merging = 1;
this->Locator = NULL;
}
//----------------------------------------------------------------------------
vtkGenericDataSetTessellator::~vtkGenericDataSetTessellator()
{
if ( this->Locator )
{
this->Locator->UnRegister(this);
this->Locator = NULL;
}
this->internalPD->Delete();
}
//----------------------------------------------------------------------------
//
int vtkGenericDataSetTessellator::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
// get the info objects
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
vtkInformation *outInfo = outputVector->GetInformationObject(0);
// get the input and output
vtkGenericDataSet *input = vtkGenericDataSet::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkDebugMacro(<< "Executing vtkGenericDataSetTessellator...");
// vtkGenericDataSet *input = this->GetInput();
// vtkUnstructuredGrid *output = this->GetOutput();
vtkIdType numPts = input->GetNumberOfPoints();
vtkIdType numCells = input->GetNumberOfCells();
vtkPointData *outputPD = output->GetPointData();
vtkCellData *outputCD = output->GetCellData();
vtkGenericAdaptorCell *cell;
vtkIdType numInserted=0, numNew, i;
vtkIdType npts, *pts;
int abortExecute=0;
// Copy original points and point data
vtkPoints *newPts = vtkPoints::New();
newPts->Allocate(2*numPts,numPts);
// loop over region
vtkUnsignedCharArray *types = vtkUnsignedCharArray::New();
types->Allocate(numCells);
vtkIdTypeArray *locs = vtkIdTypeArray::New();
locs->Allocate(numCells);
vtkCellArray *conn = vtkCellArray::New();
conn->Allocate(numCells);
// prepare the output attributes
vtkGenericAttributeCollection *attributes=input->GetAttributes();
vtkGenericAttribute *attribute;
vtkDataArray *attributeArray;
int c=attributes->GetNumberOfAttributes();
vtkDataSetAttributes *dsAttributes;
int attributeType;
i=0;
while(i<c)
{
attribute=attributes->GetAttribute(i);
attributeType=attribute->GetType();
if(attribute->GetCentering()==vtkPointCentered)
{
dsAttributes=outputPD;
attributeArray=vtkDataArray::CreateDataArray(attribute->GetComponentType());
attributeArray->SetNumberOfComponents(attribute->GetNumberOfComponents());
attributeArray->SetName(attribute->GetName());
this->internalPD->AddArray(attributeArray);
attributeArray->Delete();
if(this->internalPD->GetAttribute(attributeType)==0)
{
this->internalPD->SetActiveAttribute(this->internalPD->GetNumberOfArrays()-1,attributeType);
}
}
else // vtkCellCentered
{
dsAttributes=outputCD;
}
attributeArray=vtkDataArray::CreateDataArray(attribute->GetComponentType());
attributeArray->SetNumberOfComponents(attribute->GetNumberOfComponents());
attributeArray->SetName(attribute->GetName());
dsAttributes->AddArray(attributeArray);
attributeArray->Delete();
if(dsAttributes->GetAttribute(attributeType)==0)
{
dsAttributes->SetActiveAttribute(dsAttributes->GetNumberOfArrays()-1,attributeType);
}
++i;
}
vtkIdTypeArray *cellIdArray=0;
if(this->KeepCellIds)
{
cellIdArray=vtkIdTypeArray::New();
cellIdArray->SetName("OriginalIds");
}
vtkGenericCellIterator *cellIt = input->NewCellIterator();
vtkIdType updateCount = numCells/20 + 1; // update roughly every 5%
vtkIdType count = 0;
input->GetTessellator()->InitErrorMetrics(input);
vtkPointLocator *locator=0;
if ( this->Merging )
{
if ( this->Locator == NULL )
{
this->CreateDefaultLocator();
}
this->Locator->InitPointInsertion (newPts, input->GetBounds());
locator=this->Locator;
}
for(cellIt->Begin(); !cellIt->IsAtEnd() && !abortExecute; cellIt->Next(), count++)
{
if ( !(count % updateCount) )
{
this->UpdateProgress((double)count / numCells);
abortExecute = this->GetAbortExecute();
}
cell = cellIt->GetCell();
cell->Tessellate(input->GetAttributes(), input->GetTessellator(),
newPts, locator, conn, this->internalPD,outputPD,
outputCD,types);
numNew = conn->GetNumberOfCells() - numInserted;
numInserted = conn->GetNumberOfCells();
vtkIdType cellId=cell->GetId();
if(this->KeepCellIds)
{
for(i=0;i<numNew;i++)
{
cellIdArray->InsertNextValue(cellId);
}
}
for (i=0; i < numNew; i++)
{
locs->InsertNextValue(conn->GetTraversalLocation());
conn->GetNextCell(npts,pts); //side effect updates traversal location
} //insert each new cell
} //for all cells
cellIt->Delete();
// Send to the output
if(this->KeepCellIds)
{
outputCD->AddArray(cellIdArray);
cellIdArray->Delete();
}
output->SetPoints(newPts);
output->SetCells(types, locs, conn);
if (!this->Merging && this->Locator)
{
this->Locator->Initialize();
}
vtkDebugMacro(<<"Subdivided " << numCells << " cells to produce "
<< conn->GetNumberOfCells() << "new cells");
newPts->Delete();
types->Delete();
locs->Delete();
conn->Delete();
output->Squeeze();
return 1;
}
//----------------------------------------------------------------------------
int vtkGenericDataSetTessellator::FillInputPortInformation(
int port,
vtkInformation* info)
{
if(!this->Superclass::FillInputPortInformation(port, info))
{
return 0;
}
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkGenericDataSet");
return 1;
}
//----------------------------------------------------------------------------
// Specify a spatial locator for merging points. By
// default an instance of vtkMergePoints is used.
void vtkGenericDataSetTessellator::SetLocator(vtkPointLocator *locator)
{
if ( this->Locator == locator )
{
return;
}
if ( this->Locator )
{
this->Locator->UnRegister(this);
this->Locator = NULL;
}
if ( locator )
{
locator->Register(this);
}
this->Locator = locator;
this->Modified();
}
//----------------------------------------------------------------------------
void vtkGenericDataSetTessellator::CreateDefaultLocator()
{
if ( this->Locator == NULL )
{
this->Locator = vtkMergePoints::New();
}
}
//----------------------------------------------------------------------------
void vtkGenericDataSetTessellator::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "keep cells ids=";
if(this->KeepCellIds)
{
os << "true" << endl;
}
else
{
os << "false" << endl;
}
os << indent << "Merging: " << (this->Merging ? "On\n" : "Off\n");
if ( this->Locator )
{
os << indent << "Locator: " << this->Locator << "\n";
}
else
{
os << indent << "Locator: (none)\n";
}
}
//----------------------------------------------------------------------------
unsigned long int vtkGenericDataSetTessellator::GetMTime()
{
unsigned long mTime=this->Superclass::GetMTime();
unsigned long time;
if ( this->Locator != NULL )
{
time = this->Locator->GetMTime();
mTime = ( time > mTime ? time : mTime );
}
return mTime;
}