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
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";
|
|
}
|
|
|