They are many different cells in VTK, they can be divided into two kinds, linear cells, and non-linear cells.
The following images are from VTKUsersGuide.
Linear Cells
Non-Linear Cells
Although vtkUnstructuredGrid and vtkPolyData are similar, there are substantial differences. vtkPolyData can only represent cells of topological dimension 2 or less (i.e., triangle strips, polygons, lines, vertices) while vtkUnstructuredGrid can represent cells of dimension 3 and less.
Also, vtkUnstructuredGrid maintains an internal instance of vtkCellTypes to allow random access to its cells, while vtkPolyData instantiates vtkCellTypes only when random access is required. Finally, vtkUnstructuredGrid maintains a single internal instance of vtkCellArray to represent cell connectivity; vtkPolyData maintains four arrays corresponding to triangle strips, polygons, lines, and vertices.
We can judge whether the vtkImageData object has an unstructured grid (the cell has dimension 3) by the number of faces of a single cell.
vtkSmartPointer<vtkImageData> imageData =
vtkSmartPointer<vtkImageData>::New();
imageData->SetDimensions(3, 3, 2);
imageData->SetSpacing(1.0, 1.0, 1.0);
imageData->SetOrigin(0.0, 0.0, 0.0);
//...
for(vtkIdType cellId = 0; cellId < imageData->GetNumberOfCells(); ++cellId)
{
vtkCell *cell = imageData->GetCell( cellId );
cout << cell->GetNumberOfFaces() << endl;
/*
6
6
6
6
*/
I design a project which allows user press number [5,8] to show cells that ids are in the range [0, 3].
#include <vtkSmartPointer.h>
#include <vtkCell.h>
#include <vtkImageData.h>
#include <vtkImageMapper3D.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkImageDataGeometryFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkImageMarchingCubes.h>
#include <vtkPointData.h>
#include <vtkPointSource.h>
#include <vtkSphereSource.h>
#include <vtkProperty.h>
#include <vector>
#include <vtkDataSetMapper.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <QString>
#include "tool.h"
using namespace std;
vtkSmartPointer<vtkActor> boundsActor;
vtkSmartPointer<vtkImageData> imageData;
vtkSmartPointer<vtkRenderer> renderer;
vtkSmartPointer<vtkRenderWindow> renderWindow;
// Define interaction style
class KeyPressInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
static KeyPressInteractorStyle* New();
vtkTypeMacro(KeyPressInteractorStyle, vtkInteractorStyleTrackballCamera);
void ShowCell( int cellId );
virtual void OnKeyPress()
{
vtkRenderWindowInteractor *rwi = this->Interactor;
QString key = rwi->GetKeySym();
int value = key.toInt();
if( value >= 5 & value <= 8 ) // avoid "3" which show RGB
{
ShowCell( value - 5 );
renderWindow->Render();
}
else
{
// Forward events
vtkInteractorStyleTrackballCamera::OnKeyPress();
}
}
};
vtkStandardNewMacro(KeyPressInteractorStyle);
void KeyPressInteractorStyle::ShowCell( int cellId )
{
vtkCell *imageCell = imageData->GetCell( cellId );
double bounds[ 6 ];
imageCell->GetBounds( bounds );
vector<PointStruct> pts;
for( int i = 0; i < 2; ++i )
{
for( int j = 2; j < 4; ++j )
{
for( int k = 4; k < 6; ++k )
{
pts.push_back( PointStruct( bounds[i], bounds[j], bounds[k] ) );
}
}
}
vtkSmartPointer<vtkPolyData> boundsPolydata =
vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPoints> boundsPoints =
vtkSmartPointer<vtkPoints>::New();
for( int i = 0 ; i < 8; ++i )
{
boundsPoints->InsertNextPoint( pts[i].point );
}
boundsPolydata->SetPoints( boundsPoints );
vtkSmartPointer<vtkCellArray> cells =
vtkSmartPointer<vtkCellArray>::New();
vtkIdType cell[2] = { 0, 1 };
cells->InsertNextCell( 2, cell );
cell[0] = 0; cell[1] = 2;
cells->InsertNextCell( 2, cell );
cell[0] = 3; cell[1] = 2;
cells->InsertNextCell( 2, cell );
cell[0] = 3; cell[1] = 1;
cells->InsertNextCell( 2, cell );
cell[0] = 4; cell[1] = 5;
cells->InsertNextCell( 2, cell );
cell[0] = 4; cell[1] = 6;
cells->InsertNextCell( 2, cell );
cell[0] = 7; cell[1] = 5;
cells->InsertNextCell( 2, cell );
cell[0] = 7; cell[1] = 6;
cells->InsertNextCell( 2, cell );
cell[0] = 1; cell[1] = 5;
cells->InsertNextCell( 2, cell );
cell[0] = 0; cell[1] = 4;
cells->InsertNextCell( 2, cell );
cell[0] = 2; cell[1] = 6;
cells->InsertNextCell( 2, cell );
cell[0] = 3; cell[1] = 7;
cells->InsertNextCell( 2, cell );
boundsPolydata->SetLines( cells );
vtkSmartPointer<vtkPolyDataMapper> boundsMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
boundsMapper->SetInputData( boundsPolydata );
boundsActor->SetMapper( boundsMapper );
boundsActor->GetProperty()->SetColor( 1, 0, 0 );
}
int main(int, char *[])
{
imageData = vtkSmartPointer<vtkImageData>::New();
imageData->SetDimensions(3,3,2); // This will cause 18 points and 4 cells
imageData->SetSpacing(1.0, 1.0, 1.0);
imageData->SetOrigin(0.0, 0.0, 0.0);
vtkSmartPointer<vtkDataSetMapper> mapper =
vtkSmartPointer<vtkDataSetMapper>::New();
mapper->SetInputData( imageData );
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper( mapper );
renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor( actor );
renderer->SetBackground( 0, 0, 0 );
renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer( renderer );
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow( renderWindow );
boundsActor = vtkSmartPointer<vtkActor>::New();
renderer->AddActor( boundsActor );
vtkSmartPointer<KeyPressInteractorStyle> style =
vtkSmartPointer<KeyPressInteractorStyle>::New();
renderWindowInteractor->SetInteractorStyle( style );
style->SetCurrentRenderer( renderer );
renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
How to interact with the program?
Press s
to get surface, w
to get wireframe performance.
Press number key [5, 8] to display different cells, for example, our program will show the first cell as red cube when I press 5
.