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.
171 lines
5.4 KiB
171 lines
5.4 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkShrinkFilter.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 "vtkShrinkFilter.h"
|
|
|
|
#include "vtkCell.h"
|
|
#include "vtkCellData.h"
|
|
#include "vtkIdList.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkSmartPointer.h"
|
|
#include "vtkUnstructuredGrid.h"
|
|
|
|
vtkCxxRevisionMacro(vtkShrinkFilter, "$Revision: 1.64.12.2 $");
|
|
vtkStandardNewMacro(vtkShrinkFilter);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkShrinkFilter::vtkShrinkFilter()
|
|
{
|
|
this->ShrinkFactor = 0.5;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkShrinkFilter::~vtkShrinkFilter()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkShrinkFilter::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
os << indent << "Shrink Factor: " << this->ShrinkFactor << "\n";
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkShrinkFilter::FillInputPortInformation(int, vtkInformation* info)
|
|
{
|
|
// This filter uses the vtkDataSet cell traversal methods so it
|
|
// suppors any data set type as input.
|
|
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkShrinkFilter::RequestData(vtkInformation*,
|
|
vtkInformationVector** inputVector,
|
|
vtkInformationVector* outputVector)
|
|
{
|
|
// Get input and output data.
|
|
vtkDataSet* input = vtkDataSet::GetData(inputVector[0]);
|
|
vtkUnstructuredGrid* output = vtkUnstructuredGrid::GetData(outputVector);
|
|
|
|
// We are now executing this filter.
|
|
vtkDebugMacro("Shrinking cells");
|
|
|
|
// Skip execution if there is no input geometry.
|
|
vtkIdType numCells = input->GetNumberOfCells();
|
|
vtkIdType numPts = input->GetNumberOfPoints();
|
|
if(numCells < 1 || numPts < 1)
|
|
{
|
|
vtkDebugMacro("No data to shrink!");
|
|
return 1;
|
|
}
|
|
|
|
// Allocate working space for new and old cell point lists.
|
|
vtkSmartPointer<vtkIdList> ptIds = vtkSmartPointer<vtkIdList>::New();
|
|
vtkSmartPointer<vtkIdList> newPtIds = vtkSmartPointer<vtkIdList>::New();
|
|
ptIds->Allocate(VTK_CELL_SIZE);
|
|
newPtIds->Allocate(VTK_CELL_SIZE);
|
|
|
|
// Allocate approximately the space needed for the output cells.
|
|
output->Allocate(numCells);
|
|
|
|
// Allocate space for a new set of points.
|
|
vtkSmartPointer<vtkPoints> newPts = vtkSmartPointer<vtkPoints>::New();
|
|
newPts->Allocate(numPts*8, numPts);
|
|
|
|
// Allocate space for data associated with the new set of points.
|
|
vtkPointData* inPD = input->GetPointData();
|
|
vtkPointData* outPD = output->GetPointData();
|
|
outPD->CopyAllocate(inPD, numPts*8, numPts);
|
|
|
|
// Support progress and abort.
|
|
vtkIdType tenth = (numCells >= 10? numCells/10 : 1);
|
|
double numCellsInv = 1.0/numCells;
|
|
int abort = 0;
|
|
|
|
// Traverse all cells, obtaining node coordinates. Compute "center"
|
|
// of cell, then create new vertices shrunk towards center.
|
|
for(vtkIdType cellId = 0; cellId < numCells && !abort; ++cellId)
|
|
{
|
|
// Get the list of points for this cell.
|
|
input->GetCellPoints(cellId, ptIds);
|
|
vtkIdType numIds = ptIds->GetNumberOfIds();
|
|
|
|
// Periodically update progress and check for an abort request.
|
|
if(cellId % tenth == 0)
|
|
{
|
|
this->UpdateProgress((cellId+1)*numCellsInv);
|
|
abort = this->GetAbortExecute();
|
|
}
|
|
|
|
// Compute the center of mass of the cell points.
|
|
double center[3] = {0,0,0};
|
|
for(vtkIdType i=0; i < numIds; ++i)
|
|
{
|
|
double p[3];
|
|
input->GetPoint(ptIds->GetId(i), p);
|
|
for(int j=0; j < 3; ++j)
|
|
{
|
|
center[j] += p[j];
|
|
}
|
|
}
|
|
for(int j=0; j < 3; ++j)
|
|
{
|
|
center[j] /= numIds;
|
|
}
|
|
|
|
// Create new points for this cell.
|
|
newPtIds->Reset();
|
|
for(vtkIdType i=0; i < numIds; ++i)
|
|
{
|
|
// Get the old point location.
|
|
double p[3];
|
|
input->GetPoint(ptIds->GetId(i), p);
|
|
|
|
// Compute the new point location.
|
|
double newPt[3];
|
|
for(int j=0; j < 3; ++j)
|
|
{
|
|
newPt[j] = center[j] + this->ShrinkFactor*(p[j] - center[j]);
|
|
}
|
|
|
|
// Create the new point for this cell.
|
|
vtkIdType newId = newPts->InsertNextPoint(newPt);
|
|
newPtIds->InsertId(i, newId);
|
|
|
|
// Copy point data from the old point.
|
|
vtkIdType oldId = ptIds->GetId(i);
|
|
outPD->CopyData(inPD, oldId, newId);
|
|
}
|
|
|
|
// Store the new cell in the output.
|
|
output->InsertNextCell(input->GetCellType(cellId), newPtIds);
|
|
}
|
|
|
|
// Store the new set of points in the output.
|
|
output->SetPoints(newPts);
|
|
|
|
// Just pass cell data through because we still have the same number
|
|
// and type of cells.
|
|
output->GetCellData()->PassData(input->GetCellData());
|
|
|
|
// Avoid keeping extra memory around.
|
|
output->Squeeze();
|
|
|
|
return 1;
|
|
}
|
|
|