|
|
#include "FITKShellFeatureEdges.h"
|
|
|
|
|
|
// #include "Common/DebugLogger.h"
|
|
|
|
|
|
#include "vtkCellArray.h"
|
|
|
#include "vtkCellData.h"
|
|
|
#include "vtkFloatArray.h"
|
|
|
#include "vtkIncrementalPointLocator.h"
|
|
|
#include "vtkInformation.h"
|
|
|
#include "vtkInformationVector.h"
|
|
|
#include "vtkMath.h"
|
|
|
#include "vtkMergePoints.h"
|
|
|
#include "vtkObjectFactory.h"
|
|
|
#include "vtkPointData.h"
|
|
|
#include "vtkPolyData.h"
|
|
|
#include "vtkPolygon.h"
|
|
|
#include "vtkStreamingDemandDrivenPipeline.h"
|
|
|
#include "vtkTriangleStrip.h"
|
|
|
#include "vtkUnsignedCharArray.h"
|
|
|
|
|
|
#include "vtkIdTypeArray.h"
|
|
|
|
|
|
#include "vtkVersionMacros.h"
|
|
|
|
|
|
vtkStandardNewMacro(FITKShellFeatureEdges);
|
|
|
|
|
|
// Construct object with feature angle = 30; all types of edges, except
|
|
|
// manifold edges, are extracted and colored.
|
|
|
FITKShellFeatureEdges::FITKShellFeatureEdges( )
|
|
|
{
|
|
|
this->FeatureAngle = 5.0;
|
|
|
this->BoundaryEdges = 0;
|
|
|
this->FeatureEdges = 1;
|
|
|
this->NonManifoldEdges = 0;
|
|
|
this->ManifoldEdges = 0;
|
|
|
this->Coloring = 1;
|
|
|
this->Locator = nullptr;
|
|
|
this->OutputPointsPrecision = vtkAlgorithm::DEFAULT_PRECISION;
|
|
|
this->PassThroughIds = 1;
|
|
|
}
|
|
|
|
|
|
FITKShellFeatureEdges::~FITKShellFeatureEdges( )
|
|
|
{
|
|
|
if ( this->Locator )
|
|
|
{
|
|
|
this->Locator->UnRegister( this );
|
|
|
this->Locator = nullptr;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Generate feature edges for mesh
|
|
|
int FITKShellFeatureEdges::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 output
|
|
|
vtkPolyData* input = vtkPolyData::SafeDownCast(
|
|
|
inInfo->Get( vtkDataObject::DATA_OBJECT( ) ) );
|
|
|
vtkPolyData* output = vtkPolyData::SafeDownCast(
|
|
|
outInfo->Get( vtkDataObject::DATA_OBJECT( ) ) );
|
|
|
|
|
|
vtkPoints* inPts;
|
|
|
vtkPoints* newPts;
|
|
|
vtkFloatArray* newScalars = nullptr;
|
|
|
vtkIdTypeArray* newIDArr = nullptr;
|
|
|
vtkCellArray* newLines;
|
|
|
vtkPolyData* Mesh;
|
|
|
int i;
|
|
|
vtkIdType j, numNei, cellId;
|
|
|
vtkIdType numBEdges, numNonManifoldEdges, numFedges, numManifoldEdges;
|
|
|
double scalar, n[ 3 ], x1[ 3 ], x2[ 3 ];
|
|
|
double cosAngle = 0;
|
|
|
vtkIdType lineIds[ 2 ];
|
|
|
vtkIdType npts = 0;
|
|
|
|
|
|
// Added by CHT
|
|
|
#if VTK_MAJOR_VERSION >=9
|
|
|
const vtkIdType* pts = nullptr;
|
|
|
#else
|
|
|
vtkIdType* pts = nullptr;
|
|
|
#endif
|
|
|
|
|
|
vtkCellArray * inPolys, *inStrips, *newPolys;
|
|
|
vtkFloatArray* polyNormals = nullptr;
|
|
|
vtkIdType numPts, numCells, numPolys, numStrips, nei;
|
|
|
vtkIdList* neighbors;
|
|
|
vtkIdType p1, p2, newId;
|
|
|
vtkPointData * pd = input->GetPointData( ), *outPD = output->GetPointData( );
|
|
|
vtkCellData * cd = input->GetCellData( ), *outCD = output->GetCellData( );
|
|
|
|
|
|
unsigned char* ghosts = nullptr;
|
|
|
vtkDebugMacro( << "Executing feature edges" );
|
|
|
|
|
|
vtkDataArray* temp = nullptr;
|
|
|
if ( cd )
|
|
|
{
|
|
|
temp = cd->GetArray( vtkDataSetAttributes::GhostArrayName( ) );
|
|
|
}
|
|
|
if ( ( !temp ) || ( temp->GetDataType( ) != VTK_UNSIGNED_CHAR ) || ( temp->GetNumberOfComponents( ) != 1 ) )
|
|
|
{
|
|
|
vtkDebugMacro( "No appropriate ghost levels field available." );
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ghosts = static_cast< vtkUnsignedCharArray* >( temp )->GetPointer( 0 );
|
|
|
}
|
|
|
|
|
|
// Check input
|
|
|
//
|
|
|
inPts = input->GetPoints( );
|
|
|
numCells = input->GetNumberOfCells( );
|
|
|
numPolys = input->GetNumberOfPolys( );
|
|
|
numStrips = input->GetNumberOfStrips( );
|
|
|
if ( ( numPts = input->GetNumberOfPoints( ) ) < 1 || !inPts ||
|
|
|
( numPolys < 1 && numStrips < 1 ) )
|
|
|
{
|
|
|
vtkDebugMacro( << "No input data!" );
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
if ( !this->BoundaryEdges && !this->NonManifoldEdges &&
|
|
|
!this->FeatureEdges && !this->ManifoldEdges )
|
|
|
{
|
|
|
vtkDebugMacro( << "All edge types turned off!" );
|
|
|
}
|
|
|
|
|
|
// Build cell structure. Might have to triangulate the strips.
|
|
|
Mesh = vtkPolyData::New( );
|
|
|
Mesh->SetPoints( inPts );
|
|
|
inPolys = input->GetPolys( );
|
|
|
// 原有的节点id存储在此处
|
|
|
vtkIdTypeArray* inPolyData = inPolys->GetData( );
|
|
|
Q_UNUSED(inPolyData);
|
|
|
if ( numStrips > 0 )
|
|
|
{
|
|
|
newPolys = vtkCellArray::New( );
|
|
|
if ( numPolys > 0 )
|
|
|
{
|
|
|
newPolys->DeepCopy( inPolys );
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
newPolys->Allocate( newPolys->EstimateSize( numStrips, 5 ) );
|
|
|
}
|
|
|
|
|
|
inStrips = input->GetStrips( );
|
|
|
for ( inStrips->InitTraversal( ); inStrips->GetNextCell( npts, pts ); )
|
|
|
{
|
|
|
vtkTriangleStrip::DecomposeStrip( npts, pts, newPolys );
|
|
|
}
|
|
|
|
|
|
Mesh->SetPolys( newPolys );
|
|
|
newPolys->Delete( );
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
newPolys = inPolys;
|
|
|
Mesh->SetPolys( newPolys );
|
|
|
}
|
|
|
Mesh->BuildLinks( );
|
|
|
|
|
|
// Allocate storage for lines/points (arbitrary allocation sizes)
|
|
|
//
|
|
|
newPts = vtkPoints::New( );
|
|
|
|
|
|
// Set the desired precision for the points in the output.
|
|
|
if ( this->OutputPointsPrecision == vtkAlgorithm::DEFAULT_PRECISION )
|
|
|
{
|
|
|
newPts->SetDataType( inPts->GetDataType( ) );
|
|
|
}
|
|
|
else if ( this->OutputPointsPrecision == vtkAlgorithm::SINGLE_PRECISION )
|
|
|
{
|
|
|
newPts->SetDataType( VTK_FLOAT );
|
|
|
}
|
|
|
else if ( this->OutputPointsPrecision == vtkAlgorithm::DOUBLE_PRECISION )
|
|
|
{
|
|
|
newPts->SetDataType( VTK_DOUBLE );
|
|
|
}
|
|
|
|
|
|
newPts->Allocate( numPts / 10, numPts );
|
|
|
newLines = vtkCellArray::New( );
|
|
|
newLines->Allocate( numPts / 10 );
|
|
|
|
|
|
if ( this->Coloring )
|
|
|
{
|
|
|
newScalars = vtkFloatArray::New( );
|
|
|
newScalars->SetName( "Edge Types" );
|
|
|
newScalars->Allocate( numCells / 10, numCells );
|
|
|
}
|
|
|
vtkCellData* cellData = input->GetCellData( );
|
|
|
vtkPointData* pointData = input->GetPointData( );
|
|
|
//input与grid的单元号对应关系
|
|
|
vtkDataArray* cellDataArr = cellData->GetArray( 0 );
|
|
|
//input与grid的节点号对应关系
|
|
|
vtkDataArray* pointDataArr = pointData->GetArray( 0 );
|
|
|
if ( this->PassThroughIds )
|
|
|
{
|
|
|
// 若需要输出原始点号,放开此语句
|
|
|
//// 若input中无所需数据,则不输出原id
|
|
|
if ( cellDataArr == nullptr || pointDataArr == nullptr )
|
|
|
{
|
|
|
// DebugWarn( "ShellFeatureEdges::PassThroughIdsOff,because of no oriId data" );
|
|
|
PassThroughIdsOff( );
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
newIDArr = vtkIdTypeArray::New( );
|
|
|
newIDArr->SetName( "OriIDArray" );
|
|
|
newIDArr->SetNumberOfComponents( 4 );
|
|
|
}
|
|
|
}
|
|
|
outPD->CopyAllocate( pd, numPts );
|
|
|
outCD->CopyAllocate( cd, numCells );
|
|
|
|
|
|
// Get our locator for merging points
|
|
|
//
|
|
|
if ( this->Locator == nullptr )
|
|
|
{
|
|
|
this->CreateDefaultLocator( );
|
|
|
}
|
|
|
this->Locator->InitPointInsertion( newPts, input->GetBounds( ) );
|
|
|
|
|
|
// Loop over all polygons generating boundary, non-manifold,
|
|
|
// and feature edges
|
|
|
//
|
|
|
if ( this->FeatureEdges )
|
|
|
{
|
|
|
polyNormals = vtkFloatArray::New( );
|
|
|
polyNormals->SetNumberOfComponents( 3 );
|
|
|
polyNormals->Allocate( 3 * newPolys->GetNumberOfCells( ) );
|
|
|
|
|
|
for ( cellId = 0, newPolys->InitTraversal( ); newPolys->GetNextCell( npts, pts );
|
|
|
cellId++ )
|
|
|
{
|
|
|
vtkPolygon::ComputeNormal( inPts, npts, pts, n );
|
|
|
polyNormals->InsertTuple( cellId, n );
|
|
|
}
|
|
|
|
|
|
cosAngle = cos( vtkMath::RadiansFromDegrees( this->FeatureAngle ) );
|
|
|
}
|
|
|
|
|
|
neighbors = vtkIdList::New( );
|
|
|
neighbors->Allocate( VTK_CELL_SIZE );
|
|
|
|
|
|
int abort = 0;
|
|
|
vtkIdType progressInterval = numCells / 20 + 1;
|
|
|
|
|
|
numBEdges = numNonManifoldEdges = numFedges = numManifoldEdges = 0;
|
|
|
|
|
|
int lineId = 0;
|
|
|
for ( cellId = 0, newPolys->InitTraversal( );
|
|
|
newPolys->GetNextCell( npts, pts ) && !abort; cellId++ )
|
|
|
{
|
|
|
_surEdegeIDMap[ cellId ];
|
|
|
if ( !( cellId % progressInterval ) ) //manage progress / early abort
|
|
|
{
|
|
|
this->UpdateProgress( static_cast< double >( cellId ) / numCells );
|
|
|
abort = this->GetAbortExecute( );
|
|
|
}
|
|
|
|
|
|
for ( i = 0; i < npts; i++ )
|
|
|
{
|
|
|
p1 = pts[ i ];
|
|
|
p2 = pts[ ( i + 1 ) % npts ];
|
|
|
|
|
|
// Added by ChengHaotian Remove duplicated edge.
|
|
|
//@{
|
|
|
//int numCellCurrent = newLines->GetNumberOfCells();
|
|
|
//for (int j = 0; j < numCellCurrent; j++)
|
|
|
//{
|
|
|
// vtkSmartPointer<vtkIdList> pointPair = vtkSmartPointer<vtkIdList>::New();
|
|
|
// newLines->GetCellAtId(j, pointPair);
|
|
|
|
|
|
// // We just need to check if the p2-p1 edge exist, because the each edge will only be added once.
|
|
|
// if (/*(pointPair->GetId(0) == p1 && pointPair->GetId(1) == p2)
|
|
|
// || */(pointPair->GetId(1) == p1 && pointPair->GetId(0) == p2))
|
|
|
// {
|
|
|
// continue;
|
|
|
// }
|
|
|
//}
|
|
|
//@}
|
|
|
|
|
|
Mesh->GetCellEdgeNeighbors( cellId, p1, p2, neighbors );
|
|
|
numNei = neighbors->GetNumberOfIds( );
|
|
|
int numNei2 = numNei;
|
|
|
//无临近单元的单元为边界单元
|
|
|
if ( this->BoundaryEdges && numNei < 1 )
|
|
|
{
|
|
|
if ( ghosts &&
|
|
|
ghosts[ cellId ] & vtkDataSetAttributes::DUPLICATECELL )
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
numBEdges++;
|
|
|
scalar = 0.0;
|
|
|
}
|
|
|
}
|
|
|
// 有1个以上相邻单元,是非流形面
|
|
|
else if ( this->NonManifoldEdges && numNei > 1 )
|
|
|
{
|
|
|
// check to make sure that this edge hasn't been created before
|
|
|
for ( j = 0; j < numNei; j++ )
|
|
|
{
|
|
|
if ( neighbors->GetId( j ) < cellId )
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if ( j >= numNei )
|
|
|
{
|
|
|
if ( ghosts &&
|
|
|
ghosts[ cellId ] & vtkDataSetAttributes::DUPLICATECELL )
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
numNonManifoldEdges++;
|
|
|
scalar = 0.222222;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
// numNei == 1可能是特征边,判断nei>cellId是为了防止重复
|
|
|
else if ( this->FeatureEdges &&
|
|
|
numNei == 1 && ( nei = neighbors->GetId( 0 ) ) > cellId )
|
|
|
{
|
|
|
Mesh->GetCellEdgeNeighbors(cellId, p1, p2, neighbors);
|
|
|
|
|
|
// neighbors->Reset();
|
|
|
vtkSmartPointer<vtkIdList> neiForBd = vtkSmartPointer<vtkIdList>::New();
|
|
|
vtkSmartPointer<vtkIdList> pointCells1 = vtkSmartPointer<vtkIdList>::New();
|
|
|
Mesh->GetPointCells(p1, pointCells1);
|
|
|
|
|
|
int neiNumTemp = 0;
|
|
|
for (int index1 = 0; index1 < pointCells1->GetNumberOfIds(); index1++)
|
|
|
{
|
|
|
int cellIdNei1 = pointCells1->GetId(index1);
|
|
|
vtkCell* ptCell1 = Mesh->GetCell(cellIdNei1);
|
|
|
vtkIdList* cPtIds1 = ptCell1->GetPointIds();
|
|
|
if (cPtIds1->IsId(p2) != -1)
|
|
|
{
|
|
|
neiForBd->InsertNextId(cellIdNei1);
|
|
|
neiNumTemp++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Added by ChengHaotian
|
|
|
//@{
|
|
|
if (neiNumTemp == 2)
|
|
|
{
|
|
|
// Get the angle between two cells.
|
|
|
int id1 = neiForBd->GetId(0);
|
|
|
int id2 = neiForBd->GetId(1);
|
|
|
|
|
|
double normal1[3]{ 0., 0., 0. };
|
|
|
double normal2[3]{ 0., 0., 0. };
|
|
|
|
|
|
vtkCell* neiCell1 = Mesh->GetCell(id1);
|
|
|
vtkPolygon::ComputeNormal(neiCell1->GetPoints(), normal1);
|
|
|
|
|
|
vtkCell* neiCell2 = Mesh->GetCell(id2);
|
|
|
vtkPolygon::ComputeNormal(neiCell2->GetPoints(), normal2);
|
|
|
|
|
|
double rad = vtkMath::AngleBetweenVectors(normal1, normal2);
|
|
|
double angle = vtkMath::DegreesFromRadians(rad);
|
|
|
|
|
|
double factor = 30.;
|
|
|
if (angle > 180 - factor || angle < factor)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
else if (neiNumTemp == 1)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
//@}
|
|
|
|
|
|
double neiTuple[ 3 ];
|
|
|
double cellTuple[ 3 ];
|
|
|
polyNormals->GetTuple( nei, neiTuple );
|
|
|
polyNormals->GetTuple( cellId, cellTuple );
|
|
|
double cos1 = vtkMath::Dot( neiTuple, cellTuple );
|
|
|
// 角度大于等于特征角度,则为特征边
|
|
|
if ( cos1 <= cosAngle )
|
|
|
{
|
|
|
if ( ghosts &&
|
|
|
ghosts[ cellId ] & vtkDataSetAttributes::DUPLICATECELL )
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
numFedges++;
|
|
|
scalar = 0.444444;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
else if ( this->ManifoldEdges &&
|
|
|
numNei == 1 && neighbors->GetId( 0 ) > cellId )
|
|
|
{
|
|
|
if ( ghosts &&
|
|
|
ghosts[ cellId ] & vtkDataSetAttributes::DUPLICATECELL )
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
numManifoldEdges++;
|
|
|
scalar = 0.666667;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
// Add edge to output
|
|
|
Mesh->GetPoint( p1, x1 );
|
|
|
Mesh->GetPoint( p2, x2 );
|
|
|
|
|
|
if ( this->Locator->InsertUniquePoint( x1, lineIds[ 0 ] ) )
|
|
|
{
|
|
|
outPD->CopyData( pd, p1, lineIds[ 0 ] );
|
|
|
}
|
|
|
|
|
|
if ( this->Locator->InsertUniquePoint( x2, lineIds[ 1 ] ) )
|
|
|
{
|
|
|
outPD->CopyData( pd, p2, lineIds[ 1 ] );
|
|
|
}
|
|
|
|
|
|
/// 添加特征网格与表面网格间节点映射
|
|
|
int ptNum = input->GetNumberOfPoints( );
|
|
|
Q_UNUSED(ptNum);
|
|
|
if (_edgeSurfacePointIDMap.contains(lineIds[0]))
|
|
|
{
|
|
|
int oldValue = _edgeSurfacePointIDMap.value( lineIds[ 0 ] );
|
|
|
if ( p1 != oldValue )
|
|
|
{
|
|
|
int a = 0;
|
|
|
Q_UNUSED(a);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_edgeSurfacePointIDMap.insert( lineIds[ 0 ], p1 );
|
|
|
_edgeSurfacePointIDMap.insert( lineIds[ 1 ], p2 );
|
|
|
}
|
|
|
|
|
|
newId = newLines->InsertNextCell( 2, lineIds );
|
|
|
_edgeSurCell[ newId ];
|
|
|
_edgeSurCell[ newId ].push_back( cellId );
|
|
|
_surEdegeIDMap[ cellId ].push_back( newId );
|
|
|
for ( int i = 0; i < numNei2; ++i )
|
|
|
{
|
|
|
vtkIdType neiID = neighbors->GetId( i );
|
|
|
_edgeSurCell[ newId ].push_back(neiID);
|
|
|
_surEdegeIDMap[ neiID ].push_back( newId );
|
|
|
|
|
|
}
|
|
|
|
|
|
// m_edgeSurfaceHash.insert(newId, QPair<int, int>(cellId, ));
|
|
|
|
|
|
outCD->CopyData( cd, cellId, newId );
|
|
|
if ( this->Coloring )
|
|
|
{
|
|
|
newScalars->InsertTuple( newId, &scalar );
|
|
|
}
|
|
|
|
|
|
_ptLines[ p1 ];
|
|
|
_ptLines[ p2 ];
|
|
|
_ptLines[ p1 ].push_back( newId );
|
|
|
_ptLines[ p2 ].push_back( newId );
|
|
|
|
|
|
if ( this->PassThroughIds )
|
|
|
{
|
|
|
double ids[ 4 ] = {0};
|
|
|
ids[ 0 ] = cellId;
|
|
|
ids[ 1 ] = p1;
|
|
|
ids[ 2 ] = p2;
|
|
|
|
|
|
// 若需要获取原点号时放开
|
|
|
// ids[ 0 ] = cellDataArr->GetComponent( cellId, 0 );
|
|
|
// ids[ 1 ] = pointDataArr->GetComponent( p1, 0 );
|
|
|
// ids[ 2 ] = pointDataArr->GetComponent( p2, 0 );
|
|
|
ids[ 3 ] = pointDataArr->GetComponent( lineId, 0 );
|
|
|
newIDArr->InsertTuple( newId, ids );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
vtkDebugMacro( << "Created " << numBEdges << " boundary edges, "
|
|
|
<< numNonManifoldEdges << " non-manifold edges, "
|
|
|
<< numFedges << " feature edges, "
|
|
|
<< numManifoldEdges << " manifold edges" );
|
|
|
|
|
|
// Update ourselves.
|
|
|
//
|
|
|
if ( this->FeatureEdges )
|
|
|
{
|
|
|
polyNormals->Delete( );
|
|
|
}
|
|
|
|
|
|
Mesh->Delete( );
|
|
|
|
|
|
output->SetPoints( newPts );
|
|
|
newPts->Delete( );
|
|
|
neighbors->Delete( );
|
|
|
|
|
|
output->SetLines( newLines );
|
|
|
newLines->Delete( );
|
|
|
this->Locator->Initialize( ); //release any extra memory
|
|
|
if ( this->Coloring )
|
|
|
{
|
|
|
int idx = outCD->AddArray( newScalars );
|
|
|
outCD->SetActiveAttribute( idx, vtkDataSetAttributes::SCALARS );
|
|
|
newScalars->Delete( );
|
|
|
}
|
|
|
if ( PassThroughIds )
|
|
|
{
|
|
|
newIDArr->SetName( "OriIds" );
|
|
|
outCD->AddArray( newIDArr );
|
|
|
newIDArr->Delete( );
|
|
|
}
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
void FITKShellFeatureEdges::CreateDefaultLocator( )
|
|
|
{
|
|
|
if ( this->Locator == nullptr )
|
|
|
{
|
|
|
this->Locator = vtkMergePoints::New( );
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Specify a spatial locator for merging points. By
|
|
|
// default an instance of vtkMergePoints is used.
|
|
|
void FITKShellFeatureEdges::SetLocator( vtkIncrementalPointLocator* locator )
|
|
|
{
|
|
|
if ( this->Locator == locator )
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
if ( this->Locator )
|
|
|
{
|
|
|
this->Locator->UnRegister( this );
|
|
|
this->Locator = nullptr;
|
|
|
}
|
|
|
if ( locator )
|
|
|
{
|
|
|
locator->Register( this );
|
|
|
}
|
|
|
this->Locator = locator;
|
|
|
this->Modified( );
|
|
|
}
|
|
|
|
|
|
vtkMTimeType FITKShellFeatureEdges::GetMTime( )
|
|
|
{
|
|
|
vtkMTimeType mTime = this->Superclass::GetMTime( );
|
|
|
vtkMTimeType time;
|
|
|
|
|
|
if ( this->Locator != nullptr )
|
|
|
{
|
|
|
time = this->Locator->GetMTime( );
|
|
|
mTime = ( time > mTime ? time : mTime );
|
|
|
}
|
|
|
return mTime;
|
|
|
}
|
|
|
|
|
|
const std::vector< int >& FITKShellFeatureEdges::getLinesByPt( int ptID ) const
|
|
|
{
|
|
|
if ( _ptLines.find(ptID)!=_ptLines.end() )
|
|
|
{
|
|
|
return _ptLines.at( ptID );
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return _nullVec;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
const std::vector< int >& FITKShellFeatureEdges::getEdgeCells( int iEdgeCellID,bool* b ) const
|
|
|
{
|
|
|
if ( _edgeSurCell.find( iEdgeCellID ) == _edgeSurCell.end( ) )
|
|
|
{
|
|
|
if ( b != nullptr ) *b = false;
|
|
|
std::vector< int > rtV;
|
|
|
return rtV;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if ( b != nullptr ) *b = true;
|
|
|
return _edgeSurCell.at(iEdgeCellID);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const QVector< int >& FITKShellFeatureEdges::getSurCellEdge( int iCell ,bool* b ) const
|
|
|
{
|
|
|
if ( _surEdegeIDMap.find( iCell ) != _surEdegeIDMap.end( ) )
|
|
|
{
|
|
|
if ( b != nullptr ) *b = true;
|
|
|
return _surEdegeIDMap.value( iCell );
|
|
|
}
|
|
|
QVector< int > rt;
|
|
|
if ( b != nullptr ) *b = false;
|
|
|
return rt;
|
|
|
}
|
|
|
|
|
|
int FITKShellFeatureEdges::getSurfacePointIDByEdgePointID( int edgePointID )
|
|
|
{
|
|
|
if (_edgeSurfacePointIDMap.contains(edgePointID))
|
|
|
{
|
|
|
return _edgeSurfacePointIDMap[ edgePointID ];
|
|
|
}
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
//int FITKShellFeatureEdges::getEdgeIndex(int edgeCellId, int& surfaceCellId)
|
|
|
//{
|
|
|
// edgeCellId = -1;
|
|
|
// surfaceCellId = -1;
|
|
|
//
|
|
|
// if (!m_edgeSurfaceHash.contains(edgeCellId))
|
|
|
// {
|
|
|
// return -1;
|
|
|
// }
|
|
|
//
|
|
|
// QPair<int, int> & pair = m_edgeSurfaceHash[edgeCellId];
|
|
|
// surfaceCellId = pair.first;
|
|
|
// return pair.second;
|
|
|
//}
|
|
|
|
|
|
int FITKShellFeatureEdges::RequestUpdateExtent(
|
|
|
vtkInformation* vtkNotUsed( request ),
|
|
|
vtkInformationVector** inputVector,
|
|
|
vtkInformationVector* outputVector )
|
|
|
{
|
|
|
// get the info objects
|
|
|
vtkInformation* inInfo = inputVector[ 0 ]->GetInformationObject( 0 );
|
|
|
vtkInformation* outInfo = outputVector->GetInformationObject( 0 );
|
|
|
|
|
|
int numPieces, ghostLevel;
|
|
|
|
|
|
numPieces =
|
|
|
outInfo->Get( vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES( ) );
|
|
|
ghostLevel =
|
|
|
outInfo->Get( vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS( ) );
|
|
|
|
|
|
if ( numPieces > 1 )
|
|
|
{
|
|
|
inInfo->Set( vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS( ),
|
|
|
ghostLevel + 1 );
|
|
|
}
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
void FITKShellFeatureEdges::PrintSelf( ostream& os, vtkIndent indent )
|
|
|
{
|
|
|
this->Superclass::PrintSelf( os, indent );
|
|
|
|
|
|
os << indent << "Feature Angle: " << this->FeatureAngle << "\n";
|
|
|
os << indent << "Boundary Edges: " << ( this->BoundaryEdges ? "On\n" : "Off\n" );
|
|
|
os << indent << "Feature Edges: " << ( this->FeatureEdges ? "On\n" : "Off\n" );
|
|
|
os << indent << "Non-Manifold Edges: " << ( this->NonManifoldEdges ? "On\n" : "Off\n" );
|
|
|
os << indent << "Manifold Edges: " << ( this->ManifoldEdges ? "On\n" : "Off\n" );
|
|
|
os << indent << "Coloring: " << ( this->Coloring ? "On\n" : "Off\n" );
|
|
|
|
|
|
if ( this->Locator )
|
|
|
{
|
|
|
os << indent << "Locator: " << this->Locator << "\n";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
os << indent << "Locator: (none)\n";
|
|
|
}
|
|
|
|
|
|
os << indent << "Output Points Precision: " << this->OutputPointsPrecision << "\n";
|
|
|
}
|