Question 1, Given a triangle, what are the three adjacent triangles?
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkSphereSource.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkLineSource.h>
#include <vtkCellData.h>
#include <vtkColorTransferFunction.h>
#include <vtkTextSource.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkCoordinate.h>
#include <vtkPolyDataMapper2D.h>
#include <vtkActor2D.h>
#include <string>
#include <vtkTransform.h>
#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();
using namespace std;
void MarkPoint(int index, vtkPolyData *pd, vtkRenderer *render)
{
cout << "index: " << index << endl;
vtkSmartPointer<vtkTextSource> text2D =
vtkSmartPointer<vtkTextSource>::New();
text2D->SetText( std::to_string( index ).c_str() );
vtkSmartPointer<vtkTransform> text2DTransform =
vtkSmartPointer<vtkTransform>::New();
double *center = pd->GetPoint( index );
text2DTransform->Translate( center[0], center[1], center[2] );
text2DTransform->Scale( 0.005, 0.005, 0.005 );
vtkSmartPointer<vtkTransformPolyDataFilter> text2DDataFilter =
vtkSmartPointer<vtkTransformPolyDataFilter>::New();
text2DDataFilter->SetTransform( text2DTransform );
text2DDataFilter->SetInputConnection( text2D->GetOutputPort() );
vtkSmartPointer<vtkCoordinate> coords =
vtkSmartPointer<vtkCoordinate>::New();
coords->SetCoordinateSystemToWorld();
vtkSmartPointer<vtkPolyDataMapper2D> text2DMapper =
vtkSmartPointer<vtkPolyDataMapper2D>::New();
text2DMapper->SetInputConnection( text2DDataFilter->GetOutputPort() );
text2DMapper->SetTransformCoordinate( coords );
vtkSmartPointer<vtkActor2D> text2DActor =
vtkSmartPointer<vtkActor2D>::New();
text2DActor->SetMapper( text2DMapper );
render->AddActor( text2DActor );
}
int main()
{
vtkSPtrNew( renderer, vtkRenderer );
vtkSPtrNew( sphere, vtkSphereSource );
sphere->SetCenter( 0, 0, 0 );
sphere->SetRadius( 1 );
sphere->Update();
vtkPolyData *data = sphere->GetOutput();
data->BuildCells();
data->BuildLinks();
vtkSPtrNew( cellScalars, vtkIntArray );
cellScalars->SetNumberOfTuples( data->GetNumberOfCells() );
for( int i = 0; i < data->GetNumberOfCells(); ++i )
{
cellScalars->SetTuple1( i, 0 );
}
data->GetCellData()->SetScalars( cellScalars );
// ----------------------- Given a triangle, what are the three adjacent triangles? ---------------------------------
// GetCellNeighbors: return the shared cell(except parameter cell) by the first point and the other point.
int seedCellId = 0;
vtkSPtrNew( ptIds, vtkIdList );
data->GetCellPoints( seedCellId, ptIds );
vtkSPtrNew( neiCellIds, vtkIdList );
for( int i = 0; i < ptIds->GetNumberOfIds(); ++i )
{
vtkSPtrNew( ids, vtkIdList );
ids->InsertNextId( ptIds->GetId( i ) );
ids->InsertNextId( ptIds->GetId( (i+1)%ptIds->GetNumberOfIds() ) );
vtkSPtrNew( cellIds, vtkIdList );
data->GetCellNeighbors( seedCellId, ids, cellIds );
for( int j = 0; j < cellIds->GetNumberOfIds(); ++j )
{
auto cellId = cellIds->GetId( j );
neiCellIds->InsertUniqueId( cellId );
}
}
// -------------------------------- Finish --------------------------------------
MarkPoint( ptIds->GetId( 0 ), data, renderer );
MarkPoint( ptIds->GetId( 1 ), data, renderer );
MarkPoint( ptIds->GetId( 2 ), data, renderer );
cellScalars->SetTuple1( 0, 1 );
for( int i = 0; i < neiCellIds->GetNumberOfIds(); ++i )
{
auto cellId = neiCellIds->GetId( i );
cellScalars->SetTuple1( cellId, 2 );
}
vtkSPtrNew( lut, vtkColorTransferFunction );
lut->SetClamping( 0 );
double colors[4][3] = { {199, 21, 133}, { 139, 0, 0 }, {85, 107, 47}, { 123, 104, 238 } };
for( int i = 0; i < 4; ++i )
{
lut->AddRGBPoint( i, colors[i][0]/255.0, colors[i][1]/255.0, colors[i][2]/255.0 );
}
vtkSPtrNew( mapper, vtkPolyDataMapper );
mapper->SetInputData( data );
mapper->SetScalarModeToUseCellData();
mapper->SetLookupTable( lut );
mapper->SetScalarRange( 0, 3 );
vtkSPtrNew( sphereActor, vtkActor );
sphereActor->SetMapper( mapper );
renderer->AddActor( sphereActor );
renderer->SetBackground( 0, 0, 0 );
vtkSPtrNew( renderWindow, vtkRenderWindow );
renderWindow->AddRenderer( renderer );
vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
renderWindowInteractor->SetRenderWindow( renderWindow );
renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
Question 2, Given an edge, which two triangles share it?
// ---------------------- Given an edge, which two triangles share it? ----------------------
int seedCellId = 0;
vtkSPtrNew( ptIds, vtkIdList );
data->GetCellPoints( seedCellId, ptIds );
vtkSPtrNew( neiCellIds, vtkIdList );;
auto pId0 = ptIds->GetId( 0 );
auto pId1 = ptIds->GetId( 1 );
data->GetCellEdgeNeighbors( seedCellId, pId0, pId1, neiCellIds );
// -------------------------------- Finish --------------------------------------
MarkPoint( ptIds->GetId( 0 ), data, renderer );
MarkPoint( ptIds->GetId( 1 ), data, renderer );
cellScalars->SetTuple1( seedCellId, 1 );
for( int i = 0; i < neiCellIds->GetNumberOfIds(); ++i )
{
auto cellId = neiCellIds->GetId( i );
cellScalars->SetTuple1( cellId, 2 );
}
Question 3, Given a vertex, which faces share it?
// ---------------------------- Given a vertex, which faces share it? ---------------------------------
int seedPtId = 0;
vtkIdType ncells;
vtkIdType* neiCellIds;
data->GetPointCells( seedPtId, ncells, neiCellIds );
// ------------------------------------- Finish ------------------------------------
cout << "neiCellIds count: " << ncells << endl;
MarkPoint( seedPtId, data, renderer );
for( int i = 0; i < ncells; ++i )
{
cellScalars->SetTuple1( neiCellIds[i], i+1 );
}
vtkSPtrNew( lut, vtkColorTransferFunction );
lut->SetClamping( 0 );
double colors[9][3] = { {199, 21, 133}, { 139, 0, 0 }, {85, 107, 47}, { 123, 104, 238 },
{0, 228, 225},{ 47, 79, 79}, { 72, 209, 204}, { 255, 255, 0 },
{ 255, 255, 255 }};
for( int i = 0; i < 9; ++i )
{
lut->AddRGBPoint( i, colors[i][0]/255.0, colors[i][1]/255.0, colors[i][2]/255.0 );
}
Question 4, Given a vertex, which edges share it?
// ------------------------------- Given a vertex, which edges share it? --------------------------------------------
int seedPtId = 0;
vtkIdType ncells;
vtkIdType* neiCellIds;
data->GetPointCells( seedPtId, ncells, neiCellIds );
std::vector<vtkSmartPointer<vtkIdList>> edgePtIds;
for( int i = 0; i < ncells; ++i )
{
vtkCell *cell = data->GetCell( neiCellIds[i] );
for( int j = 0; j < cell->GetNumberOfEdges(); ++j )
{
vtkCell *edge = cell->GetEdge( j );
cout << edge->GetPointId( 0 ) << ", " << edge->GetPointId( 1 ) << endl;
if( edge->GetPointId( 0 ) == seedPtId || edge->GetPointId( 1 ) == seedPtId )
{
vtkSmartPointer<vtkIdList> linePtIds = vtkSmartPointer<vtkIdList>::New();
linePtIds->InsertNextId( edge->GetPointId( 0 ) );
linePtIds->InsertNextId( edge->GetPointId( 1 ) );
bool hasSameEdge = false;
for( int k = 0; k < edgePtIds.size(); ++k )
{
auto edgePtId0 = edgePtIds[k]->GetId( 0 );
auto edgePtId1 = edgePtIds[k]->GetId( 1 );
if( (edgePtId0 == edge->GetPointId( 0 ) && edgePtId1 == edge->GetPointId( 1 )) ||
(edgePtId0 == edge->GetPointId( 1 ) && edgePtId1 == edge->GetPointId( 0 )) )
{
hasSameEdge = true;
}
}
if( !hasSameEdge )
{
edgePtIds.push_back( linePtIds );
}
}
}
}
// ------------------------------- Finish --------------------------------------------
MarkPoint( seedPtId, data, renderer );
vtkSPtrNew(points, vtkPoints);
vtkSPtrNew(cells, vtkCellArray);
double bds[6];
data->GetBounds(bds);
vtkSPtrNew(pointsLocator, vtkPointLocator);
pointsLocator->InitPointInsertion(points, bds);
cout << "edges count : " << edgePtIds.size() << endl;
for( int i = 0; i < edgePtIds.size(); ++i )
{
vtkIdType newcell[2];
double tmp[3];
for( int j = 0; j < 2; ++j )
{
auto id = edgePtIds[i]->GetId( j );
data->GetPoint( id, tmp );
pointsLocator->InsertUniquePoint(tmp, newcell[j]);
}
cells->InsertNextCell( 2, newcell );
}
vtkSPtrNew(linesPd, vtkPolyData);
linesPd->SetPoints(points);
linesPd->SetLines(cells);
linesPd->Modified();
vtkSPtrNew( lineMapper, vtkPolyDataMapper );
lineMapper->SetInputData( linesPd );
vtkSPtrNew( lineActor, vtkActor );
lineActor->SetMapper( lineMapper );
lineActor->GetProperty()->SetColor( 1, 0, 0 );
lineActor->GetProperty()->SetLineWidth( 2 );
A video about the post:
Bilibili