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.
 
 
 
 
 
 

270 lines
6.9 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkExtractEdges.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 "vtkExtractEdges.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkDataSet.h"
#include "vtkEdgeTable.h"
#include "vtkGenericCell.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMergePoints.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
vtkCxxRevisionMacro(vtkExtractEdges, "$Revision: 1.53 $");
vtkStandardNewMacro(vtkExtractEdges);
// Construct object.
vtkExtractEdges::vtkExtractEdges()
{
this->Locator = NULL;
}
vtkExtractEdges::~vtkExtractEdges()
{
if ( this->Locator )
{
this->Locator->UnRegister(this);
this->Locator = NULL;
}
}
// Generate feature edges for mesh
int vtkExtractEdges::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
vtkDataSet *input = vtkDataSet::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkPolyData *output = vtkPolyData::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkPoints *newPts;
vtkCellArray *newLines;
vtkIdType numCells, cellNum, numPts, newId;
int edgeNum, numEdgePts, numCellEdges;
int i, abort = 0;
vtkIdType pts[2];
vtkIdType pt1 = 0, pt2;
double x[3];
vtkEdgeTable *edgeTable;
vtkGenericCell *cell;
vtkCell *edge;
vtkPointData *pd, *outPD;
vtkCellData *cd, *outCD;
vtkDebugMacro(<<"Executing edge extractor");
// Check input
//
numPts=input->GetNumberOfPoints();
if ( (numCells=input->GetNumberOfCells()) < 1 || numPts < 1 )
{
return 1;
}
// Set up processing
//
edgeTable = vtkEdgeTable::New();
edgeTable->InitEdgeInsertion(numPts);
newPts = vtkPoints::New();
newPts->Allocate(numPts);
newLines = vtkCellArray::New();
newLines->EstimateSize(numPts*4,2);
pd = input->GetPointData();
outPD = output->GetPointData();
outPD->CopyAllocate(pd,numPts);
cd = input->GetCellData();
outCD = output->GetCellData();
outCD->CopyAllocate(cd,numCells);
cell = vtkGenericCell::New();
vtkIdList *edgeIds, *HEedgeIds=vtkIdList::New();
vtkPoints *edgePts, *HEedgePts=vtkPoints::New();
// Get our locator for merging points
//
if ( this->Locator == NULL )
{
this->CreateDefaultLocator();
}
this->Locator->InitPointInsertion (newPts, input->GetBounds());
// Loop over all cells, extracting non-visited edges.
//
int tenth = numCells/10 + 1;
for (cellNum=0; cellNum < numCells && !abort; cellNum++ )
{
if ( ! (cellNum % tenth) ) //manage progress reports / early abort
{
this->UpdateProgress ((double)cellNum / numCells);
abort = this->GetAbortExecute();
}
input->GetCell(cellNum,cell);
numCellEdges = cell->GetNumberOfEdges();
for (edgeNum=0; edgeNum < numCellEdges; edgeNum++ )
{
edge = cell->GetEdge(edgeNum);
numEdgePts = edge->GetNumberOfPoints();
// Tessellate higher-order edges
if ( ! edge->IsLinear() )
{
edge->Triangulate(0, HEedgeIds, HEedgePts);
edgeIds = HEedgeIds;
edgePts = HEedgePts;
for ( i=0; i < (edgeIds->GetNumberOfIds()/2); i++ )
{
pt1 = edgeIds->GetId(2*i);
pt2 = edgeIds->GetId(2*i+1);
edgePts->GetPoint(2*i, x);
if ( this->Locator->InsertUniquePoint(x, pts[0]) )
{
outPD->CopyData (pd,pt1,pts[0]);
}
edgePts->GetPoint(2*i+1, x);
if ( this->Locator->InsertUniquePoint(x, pts[1]) )
{
outPD->CopyData (pd,pt2,pts[1]);
}
if ( edgeTable->IsEdge(pt1,pt2) == -1 )
{
edgeTable->InsertEdge(pt1, pt2);
newId = newLines->InsertNextCell(2,pts);
outCD->CopyData(cd, cellNum, newId);
}
}
} //if non-linear edge
else // linear edges
{
edgeIds = edge->PointIds;
edgePts = edge->Points;
for ( i=0; i < numEdgePts; i++, pt1=pt2, pts[0]=pts[1] )
{
pt2 = edgeIds->GetId(i);
edgePts->GetPoint(i, x);
if ( this->Locator->InsertUniquePoint(x, pts[1]) )
{
outPD->CopyData (pd,pt2,pts[1]);
}
if ( i > 0 && edgeTable->IsEdge(pt1,pt2) == -1 )
{
edgeTable->InsertEdge(pt1, pt2);
newId = newLines->InsertNextCell(2,pts);
outCD->CopyData(cd, cellNum, newId);
}
}//if linear edge
}
}//for all edges of cell
}//for all cells
vtkDebugMacro(<<"Created " << newLines->GetNumberOfCells() << " edges");
// Update ourselves.
//
HEedgeIds->Delete();
HEedgePts->Delete();
edgeTable->Delete();
cell->Delete();
output->SetPoints(newPts);
newPts->Delete();
output->SetLines(newLines);
newLines->Delete();
output->Squeeze();
return 1;
}
// Specify a spatial locator for merging points. By
// default an instance of vtkMergePoints is used.
void vtkExtractEdges::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 vtkExtractEdges::CreateDefaultLocator()
{
if ( this->Locator == NULL )
{
vtkMergePoints *locator = vtkMergePoints::New();
this->SetLocator(locator);
locator->Delete();
}
}
int vtkExtractEdges::FillInputPortInformation(int, vtkInformation *info)
{
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
return 1;
}
void vtkExtractEdges::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
if ( this->Locator )
{
os << indent << "Locator: " << this->Locator << "\n";
}
else
{
os << indent << "Locator: (none)\n";
}
}
unsigned long int vtkExtractEdges::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;
}