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.2 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkShrinkPolyData.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 "vtkShrinkPolyData.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
vtkCxxRevisionMacro(vtkShrinkPolyData, "$Revision: 1.69 $");
vtkStandardNewMacro(vtkShrinkPolyData);
vtkShrinkPolyData::vtkShrinkPolyData(double sf)
{
sf = ( sf < 0.0 ? 0.0 : (sf > 1.0 ? 1.0 : sf));
this->ShrinkFactor = sf;
}
template <class T>
void vtkShrinkPolyDataExecute(vtkShrinkPolyData *self, T *inPts,
double shrinkFactor,
vtkInformation *inInfo, vtkInformation *outInfo)
{
int j, k;
T center[3];
int abortExecute=0;
vtkCellArray *newVerts, *newLines, *newPolys;
vtkPointData *pd;
vtkCellArray *inVerts,*inLines,*inPolys,*inStrips;
vtkIdType numNewPts, numNewLines, numNewPolys, polyAllocSize;
vtkIdType npts = 0;
vtkIdType *pts = 0;
vtkIdType newIds[3];
vtkPoints *newPoints;
T *p1, *p2, *p3;
vtkPolyData *input = vtkPolyData::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkPolyData *output= vtkPolyData::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkPointData *pointData = output->GetPointData();
pd = input->GetPointData();
inVerts = input->GetVerts();
inLines = input->GetLines();
inPolys = input->GetPolys();
inStrips = input->GetStrips();
// Count the number of new points and other primitives that
// need to be created.
//
numNewPts = input->GetNumberOfVerts();
numNewLines = 0;
numNewPolys = 0;
polyAllocSize = 0;
for (inLines->InitTraversal(); inLines->GetNextCell(npts,pts); )
{
numNewPts += (npts-1) * 2;
numNewLines += npts - 1;
}
for (inPolys->InitTraversal(); inPolys->GetNextCell(npts,pts); )
{
numNewPts += npts;
numNewPolys++;
polyAllocSize += npts + 1;
}
for (inStrips->InitTraversal(); inStrips->GetNextCell(npts,pts); )
{
numNewPts += (npts-2) * 3;
polyAllocSize += (npts - 2) * 4;
}
// Allocate
//
newVerts = vtkCellArray::New();
newVerts->Allocate(input->GetNumberOfVerts());
newLines = vtkCellArray::New();
newLines->Allocate(numNewLines*3);
newPolys = vtkCellArray::New();
newPolys->Allocate(polyAllocSize);
pointData->CopyAllocate(pd);
newPoints = input->GetPoints()->NewInstance();
newPoints->SetDataType(input->GetPoints()->GetDataType());
newPoints->Allocate(numNewPts);
newPoints->SetNumberOfPoints(numNewPts);
T *outPts = (T *)newPoints->GetVoidPointer(0);
vtkIdType outCount = 0;
// Copy vertices (no shrinking necessary)
//
for (inVerts->InitTraversal();
inVerts->GetNextCell(npts,pts) && !abortExecute; )
{
newVerts->InsertNextCell(npts);
for (j=0; j<npts; j++)
{
outPts[0] = inPts[pts[j]*3];
outPts[1] = inPts[pts[j]*3+1];
outPts[2] = inPts[pts[j]*3+2];
outPts += 3;
newVerts->InsertCellPoint(outCount);
pointData->CopyData(pd,pts[j],outCount);
outCount++;
}
abortExecute = self->GetAbortExecute();
}
self->UpdateProgress (0.10);
// Lines need to be shrunk, and if polyline, split into separate pieces
//
for (inLines->InitTraversal();
inLines->GetNextCell(npts,pts) && !abortExecute; )
{
for (j=0; j<(npts-1); j++)
{
p1 = inPts + pts[j]*3;
p2 = inPts + pts[j+1]*3;
for (k=0; k<3; k++)
{
center[k] = (p1[k] + p2[k]) / 2;
}
for (k=0; k<3; k++)
{
outPts[k] = (T)(center[k] + shrinkFactor*(p1[k] - center[k]));
}
outPts += 3;
pointData->CopyData(pd,pts[j],outCount);
outCount++;
for (k=0; k<3; k++)
{
outPts[k] = (T)(center[k] + shrinkFactor*(p2[k] - center[k]));
}
outPts += 3;
pointData->CopyData(pd,pts[j+1],outCount);
newIds[0] = outCount - 1;
newIds[1] = outCount;
newLines->InsertNextCell(2,newIds);
outCount++;
}
abortExecute = self->GetAbortExecute();
}
self->UpdateProgress (0.25);
// Polygons need to be shrunk
//
for (inPolys->InitTraversal();
inPolys->GetNextCell(npts,pts) && !abortExecute; )
{
for (center[0]=center[1]=center[2]=0, j=0; j<npts; j++)
{
p1 = inPts + pts[j]*3;
for (k=0; k<3; k++)
{
center[k] += p1[k];
}
}
for (k=0; k<3; k++)
{
center[k] /= npts;
}
newPolys->InsertNextCell(npts);
for (j=0; j<npts; j++)
{
p1 = inPts + pts[j]*3;
for (k=0; k<3; k++)
{
outPts[k] = (T)(center[k] + shrinkFactor*(p1[k] - center[k]));
}
outPts += 3;
newPolys->InsertCellPoint(outCount);
pointData->CopyData(pd,pts[j],outCount);
outCount++;
}
abortExecute = self->GetAbortExecute();
}
self->UpdateProgress (0.75);
// Triangle strips need to be shrunk and split into separate pieces.
//
vtkIdType tmp;
for (inStrips->InitTraversal();
inStrips->GetNextCell(npts,pts) && !abortExecute; )
{
for (j=0; j<(npts-2); j++)
{
p1 = inPts + pts[j]*3;
p2 = inPts + pts[j+1]*3;
p3 = inPts + pts[j+2]*3;
for (k=0; k<3; k++)
{
center[k] = (p1[k] + p2[k] + p3[k]) / 3;
}
for (k=0; k<3; k++)
{
outPts[k] = (T)(center[k] + shrinkFactor*(p1[k] - center[k]));
}
outPts += 3;
pointData->CopyData(pd,pts[j],outCount);
newIds[0] = outCount;
outCount++;
for (k=0; k<3; k++)
{
outPts[k] = (T)(center[k] + shrinkFactor*(p2[k] - center[k]));
}
outPts += 3;
pointData->CopyData(pd,pts[j+1],outCount);
newIds[1] = outCount;
outCount++;
for (k=0; k<3; k++)
{
outPts[k] = (T)(center[k] + shrinkFactor*(p3[k] - center[k]));
}
outPts += 3;
pointData->CopyData(pd,pts[j+2],outCount);
newIds[1] = outCount;
outCount++;
// must reverse order for every other triangle
if (j%2)
{
tmp = newIds[0];
newIds[0] = newIds[2];
newIds[2] = tmp;
}
newPolys->InsertNextCell(3,newIds);
}
abortExecute = self->GetAbortExecute();
}
// Update self and release memory
//
output->SetPoints(newPoints);
newPoints->Delete();
output->SetVerts(newVerts);
newVerts->Delete();
output->SetLines(newLines);
newLines->Delete();
output->SetPolys(newPolys);
newPolys->Delete();
output->GetCellData()->PassData(input->GetCellData());
}
int vtkShrinkPolyData::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
vtkPolyData *input = vtkPolyData::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
// Initialize
vtkDebugMacro(<<"Shrinking polygonal data");
if (input == NULL || input->GetPoints() == NULL)
{
return 1;
}
// get the input pointer for templating
void *inPtr = input->GetPoints()->GetVoidPointer(0);
// call templated function
switch (input->GetPoints()->GetDataType())
{
vtkTemplateMacro(
vtkShrinkPolyDataExecute(this,
(VTK_TT *)(inPtr), this->ShrinkFactor,
inInfo, outInfo));
default:
break;
}
return 1;
}
void vtkShrinkPolyData::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Shrink Factor: " << this->ShrinkFactor << "\n";
}