Here is a simple example which use vtkMarchingCubes to take iossurface from volume.
We use vtkVoxelModeller to create an image data which has scalar data to mark where is inside and outside.
#include <vtkVersion.h>
#include <vtkImageData.h>
#include <vtkImageMapper3D.h>
#include <vtkImageStencil.h>
#include <vtkImageStencilData.h>
#include <vtkImageToImageStencil.h>
#include <vtkJPEGReader.h>
#include <vtkPointData.h>
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkPolyDataToImageStencil.h>
#include <vtkPolyData.h>
#include <vtkSTLReader.h>
#include <vtkProperty.h>
#include <vtkImageProperty.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkImageDataGeometryFilter.h>
#include <vtkImageMarchingCubes.h>
#include <vtkPolyDataNormals.h>
#include <vtkFillHolesFilter.h>
#include <vtkCleanPolyData.h>
#include <vtkTriangleFilter.h>
#include <vtkAppendPolyData.h>
#include <vtkImageMarchingCubes.h>
#include <vtkImageWeightedSum.h>
#include <vtkConeSource.h>
#include <vtkStripper.h>
#include <vtkPolyDataConnectivityFilter.h>
#include <vtkMarchingCubes.h>
#include <vtkVoxelModeller.h>
#include "point.hpp"
#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();
unsigned char inval = 255;
unsigned char outval = 0;
double spacingVal = 0.5;
int main(int, char *[])
{
setbuf( stdout, nullptr );
vtkSPtrNew( source, vtkSphereSource );
source->SetRadius( 2 );
source->Update();
//--------------------- take sphere from image -----------------------
double bounds[6];
source->GetOutput()->GetBounds(bounds);
int dim[3];
for (int i = 0; i < 3; i++)
{
dim[i] = bounds[2 * i + 1] - bounds[2 * i];
bounds[2 * i] = bounds[2 * i] - 0.1 * dim[i];
bounds[2 * i + 1] = bounds[2 * i + 1] + 0.1 * dim[i];
}
int sDim = 50;
vtkSPtrNew( voxel_modeller, vtkVoxelModeller );
voxel_modeller->SetSampleDimensions(sDim, sDim, sDim);
voxel_modeller->SetModelBounds(bounds);
voxel_modeller->SetScalarTypeToInt();
voxel_modeller->SetMaximumDistance(0.01);
voxel_modeller->SetInputData(source->GetOutput());
voxel_modeller->Update();
vtkSPtrNew(imageData, vtkImageData);
imageData->DeepCopy( voxel_modeller->GetOutput() );
int oneCount = 0;
for( int i = 0; i < sDim; i++ )
{
for( int j = 0; j < sDim; ++j )
{
for( int k = 0; k < sDim; ++k )
{
int *value = (int *)( imageData->GetScalarPointer( i, j, k ) );
//cout << *value << endl; // 0 or 1
if( *value > 0 ) oneCount++;
}
}
}
cout << "oneCount: " << oneCount << endl; // 6400
vtkSPtrNew( marchingCubes, vtkMarchingCubes );
marchingCubes->SetInputData( imageData );
marchingCubes->SetValue( 0, 0.5);
marchingCubes->ComputeScalarsOff();
marchingCubes->Update();
cout << marchingCubes->GetOutput()->GetNumberOfCells() << endl;
vtkSPtrNew( plyNormals, vtkPolyDataNormals );
plyNormals->SetInputData(marchingCubes->GetOutput());
plyNormals->SetFeatureAngle(60.0);
plyNormals->Update();
vtkSPtrNew( stripper, vtkStripper );
stripper->SetInputData(plyNormals->GetOutput());
stripper->Update();
vtkSPtr<vtkPolyData> spherePd = stripper->GetOutput();
//--------------------- finish: take sphere from image -----------------------
vtkSPtrNew( sphereMapper, vtkPolyDataMapper );
sphereMapper->SetInputData( spherePd );
sphereMapper->Update();
vtkSPtrNew( sphereActor, vtkActor );
sphereActor->SetMapper( sphereMapper );
sphereActor->GetProperty()->SetColor( 0, 1, 0 );
// Setup renderers
vtkSPtrNew( renderer, vtkRenderer );
renderer->AddActor( sphereActor );
renderer->SetBackground(.6, .5, .4);
renderer->ResetCamera();
// Setup render window
vtkSPtrNew( renderWindow, vtkRenderWindow );
renderWindow->AddRenderer( renderer );
// Setup render window interactor
vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
// Render and start interaction
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
Output: