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.
724 lines
21 KiB
724 lines
21 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkCleanPolyData.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 "vtkCleanPolyData.h"
|
|
|
|
#include "vtkCellArray.h"
|
|
#include "vtkCellData.h"
|
|
#include "vtkMergePoints.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkPolyData.h"
|
|
#include "vtkStreamingDemandDrivenPipeline.h"
|
|
|
|
vtkCxxRevisionMacro(vtkCleanPolyData, "$Revision: 1.77 $");
|
|
vtkStandardNewMacro(vtkCleanPolyData);
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Construct object with initial Tolerance of 0.0
|
|
vtkCleanPolyData::vtkCleanPolyData()
|
|
{
|
|
this->PointMerging = 1;
|
|
this->ToleranceIsAbsolute = 0;
|
|
this->Tolerance = 0.0;
|
|
this->AbsoluteTolerance = 1.0;
|
|
this->ConvertPolysToLines = 1;
|
|
this->ConvertLinesToPoints = 1;
|
|
this->ConvertStripsToPolys = 1;
|
|
this->Locator = NULL;
|
|
this->PieceInvariant = 1;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
vtkCleanPolyData::~vtkCleanPolyData()
|
|
{
|
|
this->ReleaseLocator();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void vtkCleanPolyData::OperateOnPoint(double in[3], double out[3])
|
|
{
|
|
out[0] = in[0];
|
|
out[1] = in[1];
|
|
out[2] = in[2];
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void vtkCleanPolyData::OperateOnBounds(double in[6], double out[6])
|
|
{
|
|
out[0] = in[0];
|
|
out[1] = in[1];
|
|
out[2] = in[2];
|
|
out[3] = in[3];
|
|
out[4] = in[4];
|
|
out[5] = in[5];
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
int vtkCleanPolyData::RequestInformation(
|
|
vtkInformation *vtkNotUsed(request),
|
|
vtkInformationVector **vtkNotUsed(inputVector),
|
|
vtkInformationVector *outputVector)
|
|
{
|
|
// get the info object
|
|
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
|
|
|
if (this->PieceInvariant)
|
|
{
|
|
outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
|
|
1);
|
|
}
|
|
else
|
|
{
|
|
outInfo->Set(vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(),
|
|
-1);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
int vtkCleanPolyData::RequestUpdateExtent(
|
|
vtkInformation *vtkNotUsed(request),
|
|
vtkInformationVector **inputVector,
|
|
vtkInformationVector *outputVector)
|
|
{
|
|
// get the info objects
|
|
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
|
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
|
|
|
if (this->PieceInvariant)
|
|
{
|
|
// Although piece > 1 is handled by superclass, we should be thorough.
|
|
if (outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) == 0)
|
|
{
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(), 0);
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
|
|
1);
|
|
}
|
|
else
|
|
{
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(), -1);
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
|
|
0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()));
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
|
|
outInfo->Get(
|
|
vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()));
|
|
inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
|
|
outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS()));
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
int vtkCleanPolyData::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 ouptut
|
|
vtkPolyData *input = vtkPolyData::SafeDownCast(
|
|
inInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
vtkPolyData *output = vtkPolyData::SafeDownCast(
|
|
outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
|
|
vtkPoints *inPts = input->GetPoints();
|
|
vtkIdType numPts = input->GetNumberOfPoints();
|
|
|
|
vtkDebugMacro(<<"Beginning PolyData clean");
|
|
if ( (numPts<1) || (inPts == NULL ) )
|
|
{
|
|
vtkDebugMacro(<<"No data to Operate On!");
|
|
return 1;
|
|
}
|
|
vtkIdType *updatedPts = new vtkIdType[input->GetMaxCellSize()];
|
|
|
|
vtkIdType numNewPts;
|
|
vtkIdType numUsedPts=0;
|
|
vtkPoints *newPts = vtkPoints::New();
|
|
newPts->Allocate(numPts);
|
|
|
|
// we'll be needing these
|
|
vtkIdType inCellID, newId;
|
|
int i;
|
|
vtkIdType ptId;
|
|
vtkIdType npts = 0;
|
|
vtkIdType *pts = 0;
|
|
double x[3];
|
|
double newx[3];
|
|
vtkIdType *pointMap=0; //used if no merging
|
|
|
|
vtkCellArray *inVerts = input->GetVerts(), *newVerts = NULL;
|
|
vtkCellArray *inLines = input->GetLines(), *newLines = NULL;
|
|
vtkCellArray *inPolys = input->GetPolys(), *newPolys = NULL;
|
|
vtkCellArray *inStrips = input->GetStrips(), *newStrips = NULL;
|
|
|
|
vtkPointData *inputPD = input->GetPointData();
|
|
vtkCellData *inputCD = input->GetCellData();
|
|
|
|
// We must be careful to 'operate' on the bounds of the locator so
|
|
// that all inserted points lie inside it
|
|
if ( this->PointMerging )
|
|
{
|
|
this->CreateDefaultLocator(input);
|
|
if (this->ToleranceIsAbsolute)
|
|
{
|
|
this->Locator->SetTolerance(this->AbsoluteTolerance);
|
|
}
|
|
else
|
|
{
|
|
this->Locator->SetTolerance(this->Tolerance*input->GetLength());
|
|
}
|
|
double originalbounds[6], mappedbounds[6];
|
|
input->GetBounds(originalbounds);
|
|
this->OperateOnBounds(originalbounds,mappedbounds);
|
|
this->Locator->InitPointInsertion(newPts, mappedbounds);
|
|
}
|
|
else
|
|
{
|
|
pointMap = new vtkIdType [numPts];
|
|
for (i=0; i < numPts; i++)
|
|
{
|
|
pointMap[i] = -1; //initialize unused
|
|
}
|
|
}
|
|
|
|
vtkPointData *outputPD = output->GetPointData();
|
|
vtkCellData *outputCD = output->GetCellData();
|
|
outputPD->CopyAllocate(inputPD);
|
|
outputCD->CopyAllocate(inputCD);
|
|
|
|
// Celldata needs to be copied correctly. If a poly is converted to
|
|
// a line, or a line to a point, then using a CellCounter will not
|
|
// do, as the cells should be ordered verts, lines, polys,
|
|
// strips. We need to maintain seperate cell data lists so we can
|
|
// copy them all correctly. Tedious but easy to implement. We can
|
|
// use outputCD for vertex cell data, then add the rest at the end.
|
|
vtkCellData *outLineData = NULL;
|
|
vtkCellData *outPolyData = NULL;
|
|
vtkCellData *outStrpData = NULL;
|
|
vtkIdType vertIDcounter = 0, lineIDcounter = 0;
|
|
vtkIdType polyIDcounter = 0, strpIDcounter = 0;
|
|
|
|
// Begin to adjust topology.
|
|
//
|
|
// Vertices are renumbered and we remove duplicates
|
|
inCellID = 0;
|
|
if ( !this->GetAbortExecute() && inVerts->GetNumberOfCells() > 0 )
|
|
{
|
|
newVerts = vtkCellArray::New();
|
|
newVerts->Allocate(inVerts->GetSize());
|
|
|
|
vtkDebugMacro(<<"Starting Verts "<<inCellID);
|
|
for (inVerts->InitTraversal(); inVerts->GetNextCell(npts,pts);
|
|
inCellID++)
|
|
{
|
|
for ( numNewPts=0, i=0; i < npts; i++ )
|
|
{
|
|
inPts->GetPoint(pts[i],x);
|
|
this->OperateOnPoint(x, newx);
|
|
if ( ! this->PointMerging )
|
|
{
|
|
if ( (ptId=pointMap[pts[i]]) == -1 )
|
|
{
|
|
pointMap[pts[i]] = ptId = numUsedPts++;
|
|
newPts->SetPoint(ptId,newx);
|
|
outputPD->CopyData(inputPD,pts[i],ptId);
|
|
}
|
|
}
|
|
else if ( this->Locator->InsertUniquePoint(newx, ptId) )
|
|
{
|
|
outputPD->CopyData(inputPD,pts[i],ptId);
|
|
}
|
|
updatedPts[numNewPts++] = ptId;
|
|
}//for all points of vertex cell
|
|
|
|
if ( numNewPts > 0 )
|
|
{
|
|
newId = newVerts->InsertNextCell(numNewPts,updatedPts);
|
|
outputCD->CopyData(inputCD, inCellID, newId);
|
|
if ( vertIDcounter != newId)
|
|
{
|
|
vtkErrorMacro(<<"Vertex ID fault in vertex test");
|
|
}
|
|
vertIDcounter++;
|
|
}
|
|
}
|
|
}
|
|
this->UpdateProgress(0.25);
|
|
|
|
// lines reduced to one point are eliminated or made into verts
|
|
if ( !this->GetAbortExecute() && inLines->GetNumberOfCells() > 0 )
|
|
{
|
|
newLines = vtkCellArray::New();
|
|
newLines->Allocate(inLines->GetSize());
|
|
outLineData = vtkCellData::New();
|
|
outLineData->CopyAllocate(inputCD);
|
|
//
|
|
vtkDebugMacro(<<"Starting Lines "<<inCellID);
|
|
for (inLines->InitTraversal(); inLines->GetNextCell(npts,pts); inCellID++)
|
|
{
|
|
for ( numNewPts=0, i=0; i<npts; i++ )
|
|
{
|
|
inPts->GetPoint(pts[i],x);
|
|
this->OperateOnPoint(x, newx);
|
|
if ( ! this->PointMerging )
|
|
{
|
|
if ( (ptId=pointMap[pts[i]]) == -1 )
|
|
{
|
|
pointMap[pts[i]] = ptId = numUsedPts++;
|
|
newPts->SetPoint(ptId,newx);
|
|
outputPD->CopyData(inputPD,pts[i],ptId);
|
|
}
|
|
}
|
|
else if ( this->Locator->InsertUniquePoint(newx, ptId) )
|
|
{
|
|
outputPD->CopyData(inputPD,pts[i],ptId);
|
|
}
|
|
if ( i == 0 || ptId != updatedPts[numNewPts-1] )
|
|
{
|
|
updatedPts[numNewPts++] = ptId;
|
|
}
|
|
}//for all cell points
|
|
if ( (numNewPts>1) || !this->ConvertLinesToPoints )
|
|
{
|
|
newId = newLines->InsertNextCell(numNewPts,updatedPts);
|
|
outLineData->CopyData(inputCD, inCellID, newId);
|
|
if (lineIDcounter!=newId)
|
|
{
|
|
vtkErrorMacro(<<"Line ID fault in line test");
|
|
}
|
|
lineIDcounter++;
|
|
}
|
|
else if ( numNewPts==1 )
|
|
{
|
|
if (!newVerts)
|
|
{
|
|
newVerts = vtkCellArray::New();
|
|
newVerts->Allocate(5);
|
|
}
|
|
newId = newVerts->InsertNextCell(numNewPts,updatedPts);
|
|
outputCD->CopyData(inputCD, inCellID, newId);
|
|
if (vertIDcounter!=newId)
|
|
{
|
|
vtkErrorMacro(<<"Vertex ID fault in line test");
|
|
}
|
|
vertIDcounter++;
|
|
}
|
|
}
|
|
vtkDebugMacro(<<"Removed "
|
|
<< inLines->GetNumberOfCells() - newLines->GetNumberOfCells()
|
|
<< " lines");
|
|
}
|
|
this->UpdateProgress(0.50);
|
|
|
|
// polygons reduced to two points or less are either eliminated
|
|
// or converted to lines or points if enabled
|
|
if ( !this->GetAbortExecute() && inPolys->GetNumberOfCells() > 0 )
|
|
{
|
|
newPolys = vtkCellArray::New();
|
|
newPolys->Allocate(inPolys->GetSize());
|
|
outPolyData = vtkCellData::New();
|
|
outPolyData->CopyAllocate(inputCD);
|
|
|
|
vtkDebugMacro(<<"Starting Polys "<<inCellID);
|
|
for (inPolys->InitTraversal(); inPolys->GetNextCell(npts,pts); inCellID++)
|
|
{
|
|
for ( numNewPts=0, i=0; i<npts; i++ )
|
|
{
|
|
inPts->GetPoint(pts[i],x);
|
|
this->OperateOnPoint(x, newx);
|
|
if ( ! this->PointMerging )
|
|
{
|
|
if ( (ptId=pointMap[pts[i]]) == -1 )
|
|
{
|
|
pointMap[pts[i]] = ptId = numUsedPts++;
|
|
newPts->SetPoint(ptId,newx);
|
|
outputPD->CopyData(inputPD,pts[i],ptId);
|
|
}
|
|
}
|
|
else if ( this->Locator->InsertUniquePoint(newx, ptId) )
|
|
{
|
|
outputPD->CopyData(inputPD,pts[i],ptId);
|
|
}
|
|
if ( i == 0 || ptId != updatedPts[numNewPts-1] )
|
|
{
|
|
updatedPts[numNewPts++] = ptId;
|
|
}
|
|
} //for points in cell
|
|
if ( numNewPts>2 && updatedPts[0] == updatedPts[numNewPts-1] )
|
|
{
|
|
numNewPts--;
|
|
}
|
|
if ( (numNewPts > 2) || !this->ConvertPolysToLines )
|
|
{
|
|
newId = newPolys->InsertNextCell(numNewPts,updatedPts);
|
|
outPolyData->CopyData(inputCD, inCellID, newId);
|
|
if (polyIDcounter!=newId)
|
|
{
|
|
vtkErrorMacro(<<"Poly ID fault in poly test");
|
|
}
|
|
polyIDcounter++;
|
|
}
|
|
else if ( (numNewPts==2) || !this->ConvertLinesToPoints )
|
|
{
|
|
if (!newLines)
|
|
{
|
|
newLines = vtkCellArray::New();
|
|
newLines->Allocate(5);
|
|
outLineData = vtkCellData::New();
|
|
outLineData->CopyAllocate(inputCD);
|
|
}
|
|
newId = newLines->InsertNextCell(numNewPts,updatedPts);
|
|
outLineData->CopyData(inputCD, inCellID, newId);
|
|
if (lineIDcounter!=newId)
|
|
{
|
|
vtkErrorMacro(<<"Line ID fault in poly test");
|
|
}
|
|
lineIDcounter++;
|
|
}
|
|
else if ( numNewPts==1 )
|
|
{
|
|
if (!newVerts)
|
|
{
|
|
newVerts = vtkCellArray::New();
|
|
newVerts->Allocate(5);
|
|
}
|
|
newId = newVerts->InsertNextCell(numNewPts,updatedPts);
|
|
outputCD->CopyData(inputCD, inCellID, newId);
|
|
if (vertIDcounter!=newId)
|
|
{
|
|
vtkErrorMacro(<<"Vertex ID fault in poly test");
|
|
}
|
|
vertIDcounter++;
|
|
}
|
|
}
|
|
vtkDebugMacro(<<"Removed "
|
|
<< inPolys->GetNumberOfCells() - newPolys->GetNumberOfCells()
|
|
<< " polys");
|
|
}
|
|
this->UpdateProgress(0.75);
|
|
|
|
// triangle strips can reduced to polys/lines/points etc
|
|
if ( !this->GetAbortExecute() && inStrips->GetNumberOfCells() > 0 )
|
|
{
|
|
newStrips = vtkCellArray::New();
|
|
newStrips->Allocate(inStrips->GetSize());
|
|
outStrpData = vtkCellData::New();
|
|
outStrpData->CopyAllocate(inputCD);
|
|
|
|
for (inStrips->InitTraversal(); inStrips->GetNextCell(npts,pts);
|
|
inCellID++)
|
|
{
|
|
for ( numNewPts=0, i=0; i < npts; i++ )
|
|
{
|
|
inPts->GetPoint(pts[i],x);
|
|
this->OperateOnPoint(x, newx);
|
|
if ( ! this->PointMerging )
|
|
{
|
|
if ( (ptId=pointMap[pts[i]]) == -1 )
|
|
{
|
|
pointMap[pts[i]] = ptId = numUsedPts++;
|
|
newPts->SetPoint(ptId,newx);
|
|
outputPD->CopyData(inputPD,pts[i],ptId);
|
|
}
|
|
}
|
|
else if ( this->Locator->InsertUniquePoint(newx, ptId) )
|
|
{
|
|
outputPD->CopyData(inputPD,pts[i],ptId);
|
|
}
|
|
if ( i == 0 || ptId != updatedPts[numNewPts-1] )
|
|
{
|
|
updatedPts[numNewPts++] = ptId;
|
|
}
|
|
}
|
|
if ( (numNewPts > 3) || !this->ConvertStripsToPolys )
|
|
{
|
|
newId = newStrips->InsertNextCell(numNewPts,updatedPts);
|
|
outStrpData->CopyData(inputCD, inCellID, newId);
|
|
if (strpIDcounter!=newId)
|
|
{
|
|
vtkErrorMacro(<<"Strip ID fault in strip test");
|
|
}
|
|
strpIDcounter++;
|
|
}
|
|
else if ( (numNewPts==3) || !this->ConvertPolysToLines )
|
|
{
|
|
if (!newPolys)
|
|
{
|
|
newPolys = vtkCellArray::New();
|
|
newPolys->Allocate(5);
|
|
outPolyData = vtkCellData::New();
|
|
outPolyData->CopyAllocate(inputCD);
|
|
}
|
|
newId = newPolys->InsertNextCell(numNewPts,updatedPts);
|
|
outPolyData->CopyData(inputCD, inCellID, newId);
|
|
if (polyIDcounter!=newId)
|
|
{
|
|
vtkErrorMacro(<<"Poly ID fault in strip test");
|
|
}
|
|
polyIDcounter++;
|
|
}
|
|
else if ( (numNewPts==2) || !this->ConvertLinesToPoints )
|
|
{
|
|
if (!newLines)
|
|
{
|
|
newLines = vtkCellArray::New();
|
|
newLines->Allocate(5);
|
|
outLineData = vtkCellData::New();
|
|
outLineData->CopyAllocate(inputCD);
|
|
}
|
|
newId = newLines->InsertNextCell(numNewPts,updatedPts);
|
|
outLineData->CopyData(inputCD, inCellID, newId);
|
|
if (lineIDcounter!=newId)
|
|
{
|
|
vtkErrorMacro(<<"Line ID fault in strip test");
|
|
}
|
|
lineIDcounter++;
|
|
}
|
|
else if ( numNewPts==1 )
|
|
{
|
|
if (!newVerts)
|
|
{
|
|
newVerts = vtkCellArray::New();
|
|
newVerts->Allocate(5);
|
|
}
|
|
newId = newVerts->InsertNextCell(numNewPts,updatedPts);
|
|
outputCD->CopyData(inputCD, inCellID, newId);
|
|
if (vertIDcounter!=newId)
|
|
{
|
|
vtkErrorMacro(<<"Vertex ID fault in strip test");
|
|
}
|
|
vertIDcounter++;
|
|
}
|
|
}
|
|
vtkDebugMacro(<<"Removed "
|
|
<< inStrips->GetNumberOfCells() - newStrips->GetNumberOfCells()
|
|
<< " strips");
|
|
}
|
|
|
|
vtkDebugMacro(<<"Removed "
|
|
<< numPts - newPts->GetNumberOfPoints() << " points");
|
|
|
|
// Update ourselves and release memory
|
|
//
|
|
delete [] updatedPts;
|
|
if ( this->PointMerging )
|
|
{
|
|
this->Locator->Initialize(); //release memory.
|
|
}
|
|
else
|
|
{
|
|
newPts->SetNumberOfPoints(numUsedPts);
|
|
delete [] pointMap;
|
|
}
|
|
|
|
// Now transfer all CellData from Lines/Polys/Strips into final
|
|
// Cell data output
|
|
int CombinedCellID = vertIDcounter;
|
|
if (newLines)
|
|
{
|
|
for (i=0; i<lineIDcounter; i++, CombinedCellID++)
|
|
{
|
|
outputCD->CopyData(outLineData, i, CombinedCellID);
|
|
}
|
|
outLineData->Delete();
|
|
}
|
|
if (newPolys)
|
|
{
|
|
for (i=0; i<polyIDcounter; i++, CombinedCellID++)
|
|
{
|
|
outputCD->CopyData(outPolyData, i, CombinedCellID);
|
|
}
|
|
outPolyData->Delete();
|
|
}
|
|
if (newStrips)
|
|
{
|
|
for (i=0; i<strpIDcounter; i++, CombinedCellID++)
|
|
{
|
|
outputCD->CopyData(outStrpData, i, CombinedCellID);
|
|
}
|
|
outStrpData->Delete();
|
|
}
|
|
|
|
output->SetPoints(newPts);
|
|
newPts->Squeeze();
|
|
newPts->Delete();
|
|
if (newVerts)
|
|
{
|
|
newVerts->Squeeze();
|
|
output->SetVerts(newVerts);
|
|
newVerts->Delete();
|
|
}
|
|
if (newLines)
|
|
{
|
|
newLines->Squeeze();
|
|
output->SetLines(newLines);
|
|
newLines->Delete();
|
|
}
|
|
if (newPolys)
|
|
{
|
|
newPolys->Squeeze();
|
|
output->SetPolys(newPolys);
|
|
newPolys->Delete();
|
|
}
|
|
if (newStrips)
|
|
{
|
|
newStrips->Squeeze();
|
|
output->SetStrips(newStrips);
|
|
newStrips->Delete();
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Specify a spatial locator for speeding the search process. By
|
|
// default an instance of vtkLocator is used.
|
|
void vtkCleanPolyData::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();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Method manages creation of locators. It takes into account the potential
|
|
// change of tolerance (zero to non-zero).
|
|
void vtkCleanPolyData::CreateDefaultLocator(vtkPolyData *input)
|
|
{
|
|
double tol;
|
|
if (this->ToleranceIsAbsolute)
|
|
{
|
|
tol = this->AbsoluteTolerance;
|
|
}
|
|
else
|
|
{
|
|
if (input)
|
|
{
|
|
tol = this->Tolerance*input->GetLength();
|
|
}
|
|
else
|
|
{
|
|
tol = this->Tolerance;
|
|
}
|
|
}
|
|
|
|
if ( this->Locator == NULL)
|
|
{
|
|
if (tol==0.0)
|
|
{
|
|
this->Locator = vtkMergePoints::New();
|
|
this->Locator->Register(this);
|
|
this->Locator->Delete();
|
|
}
|
|
else
|
|
{
|
|
this->Locator = vtkPointLocator::New();
|
|
this->Locator->Register(this);
|
|
this->Locator->Delete();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// check that the tolerance wasn't changed from zero to non-zero
|
|
if ((tol>0.0) && (this->GetLocator()->GetTolerance()==0.0))
|
|
{
|
|
this->ReleaseLocator();
|
|
this->Locator = vtkPointLocator::New();
|
|
this->Locator->Register(this);
|
|
this->Locator->Delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void vtkCleanPolyData::ReleaseLocator(void)
|
|
{
|
|
if ( this->Locator )
|
|
{
|
|
this->Locator->UnRegister(this);
|
|
this->Locator = NULL;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void vtkCleanPolyData::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "Point Merging: "
|
|
<< (this->PointMerging ? "On\n" : "Off\n");
|
|
os << indent << "ToleranceIsAbsolute: "
|
|
<< (this->ToleranceIsAbsolute ? "On\n" : "Off\n");
|
|
os << indent << "Tolerance: "
|
|
<< (this->Tolerance ? "On\n" : "Off\n");
|
|
os << indent << "AbsoluteTolerance: "
|
|
<< (this->AbsoluteTolerance ? "On\n" : "Off\n");
|
|
os << indent << "ConvertPolysToLines: "
|
|
<< (this->ConvertPolysToLines ? "On\n" : "Off\n");
|
|
os << indent << "ConvertLinesToPoints: "
|
|
<< (this->ConvertLinesToPoints ? "On\n" : "Off\n");
|
|
os << indent << "ConvertStripsToPolys: "
|
|
<< (this->ConvertStripsToPolys ? "On\n" : "Off\n");
|
|
if ( this->Locator )
|
|
{
|
|
os << indent << "Locator: " << this->Locator << "\n";
|
|
}
|
|
else
|
|
{
|
|
os << indent << "Locator: (none)\n";
|
|
}
|
|
os << indent << "PieceInvariant: "
|
|
<< (this->PieceInvariant ? "On\n" : "Off\n");
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
unsigned long int vtkCleanPolyData::GetMTime()
|
|
{
|
|
unsigned long mTime=this->vtkObject::GetMTime();
|
|
unsigned long time;
|
|
if ( this->Locator != NULL )
|
|
{
|
|
time = this->Locator->GetMTime();
|
|
mTime = ( time > mTime ? time : mTime );
|
|
}
|
|
return mTime;
|
|
}
|
|
|