ExtractLargestIsosurface
Repository source: ExtractLargestIsosurface
Description¶
- Contributed by: Jinyoung Hwang
This example reads a structured points dataset stored in a .vtk file and constructs a 3D model using vtkFlyingEdges3D or vtkMarchingCubes, vtkPolyDataConnectivityFilter is used to extract the largest isosurface.
Data is available at:
-
test.vtk: http://web.kaist.ac.kr/~hjy/test.vtk
-
brainweb.img: http://web.kaist.ac.kr/~hjy/brainweb.img
-
brainweb.hdr: http://web.kaist.ac.kr/~hjy/brainweb.hdr
Second and third datasets can be downloaded from BrainWeb, which is free of charge in use for a research. "test.vtk" was converted from "brainweb.img" using a program by Erik Vidholm (http://www.cb.uu.se/~erik/vtk/rawToVTK.cpp).
The examples expects 2 or 3 argments:
ExtractLargestIsosurface InputFilename Threshold (ExtractLargest)
if ExtractLargest is omitted or 1, the largest isosurface is extracted
if ExtractLargest is 0 (or -a in Python), all of the isosurfaces are extracted
Try
ExtractLargestIsosurface test.vtk 50
and compare the results to
ExtractLargestIsosurface test.vtk 50 0
Other languages
See (Python), (PythonicAPI), (CSharp)
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
ExtractLargestIsosurface.cxx
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkMarchingCubes.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataConnectivityFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkStructuredPointsReader.h>
#include <vtkVersion.h>
// vtkFlyingEdges3D was introduced in VTK >= 8.2
#if VTK_MAJOR_VERSION >= 9 || (VTK_MAJOR_VERSION >= 8 && VTK_MINOR_VERSION >= 2)
#define USE_FLYING_EDGES
#else
#undef USE_FLYING_EDGES
#endif
#ifdef USE_FLYING_EDGES
#include <vtkFlyingEdges3D.h>
#else
#include <vtkMarchingCubes.h>
#endif
#include <array>
int main(int argc, char* argv[])
{
if (argc < 3)
{
std::cerr << "Usage: " << argv[0]
<< " InputFile(.vtk) Threshold e.g. brain.vtk 50 1" << std::endl;
return EXIT_FAILURE;
}
const char* fileName = argv[1];
float threshold = atof(argv[2]);
auto extractLargest = true;
if (argc == 4)
{
extractLargest = atoi(argv[3]) == 1;
}
vtkNew<vtkNamedColors> colors;
std::array<unsigned char, 4> skinColor{{240, 184, 160, 255}};
colors->SetColor("SkinColor", skinColor.data());
std::array<unsigned char, 4> backColor{{255, 229, 200, 255}};
colors->SetColor("BackfaceColor", backColor.data());
// std::array<unsigned char, 4> bkg{{51, 77, 102, 255}};
// Load data
vtkNew<vtkStructuredPointsReader> reader;
reader->SetFileName(fileName);
// Create a 3D model using flying edges or marching cubes.
#ifdef USE_FLYING_EDGES
vtkNew<vtkFlyingEdges3D> mc;
#else
vtkNew<vtkMarchingCubes> mc;
#endif
mc->SetInputConnection(reader->GetOutputPort());
mc->ComputeNormalsOn();
mc->ComputeGradientsOn();
mc->SetValue(0, threshold); // Second value acts as threshold.
// To remain largest region.
vtkNew<vtkPolyDataConnectivityFilter> confilter;
confilter->SetInputConnection(mc->GetOutputPort());
confilter->SetExtractionModeToLargestRegion();
// Create a mapper.
vtkNew<vtkPolyDataMapper> mapper;
if (extractLargest)
{
mapper->SetInputConnection(confilter->GetOutputPort());
}
else
{
mapper->SetInputConnection(mc->GetOutputPort());
}
mapper->ScalarVisibilityOff();
// Visualize
vtkNew<vtkActor> actor;
actor->GetProperty()->SetColor(colors->GetColor3d("SkinColor").GetData());
vtkNew<vtkProperty> backProp;
backProp->SetDiffuseColor(colors->GetColor3d("BackfaceColor").GetData());
actor->SetBackfaceProperty(backProp);
actor->SetMapper(mapper);
vtkNew<vtkRenderer> renderer;
renderer->AddActor(actor);
renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());
renderer->GetActiveCamera()->SetViewUp(0.0, 0.0, 1.0);
renderer->GetActiveCamera()->SetPosition(0.0, 1.0, 0.0);
renderer->GetActiveCamera()->SetFocalPoint(0.0, 0.0, 0.0);
renderer->ResetCamera();
renderer->GetActiveCamera()->Azimuth(30.0);
renderer->GetActiveCamera()->Elevation(30.0);
vtkNew<vtkRenderWindow> renwin;
renwin->AddRenderer(renderer);
renwin->SetSize(640, 480);
renwin->SetWindowName("ExtractLargestIsosurface");
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renwin);
renwin->Render();
iren->Initialize();
iren->Start();
return EXIT_SUCCESS;
}
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(ExtractLargestIsosurface)
find_package(VTK COMPONENTS
CommonColor
CommonCore
FiltersCore
IOLegacy
InteractionStyle
RenderingContextOpenGL2
RenderingCore
RenderingFreeType
RenderingGL2PSOpenGL2
RenderingOpenGL2
)
if (NOT VTK_FOUND)
message(FATAL_ERROR "ExtractLargestIsosurface: Unable to find the VTK build folder.")
endif()
# Prevent a "command line is too long" failure in Windows.
set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.")
add_executable(ExtractLargestIsosurface MACOSX_BUNDLE ExtractLargestIsosurface.cxx )
target_link_libraries(ExtractLargestIsosurface PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS ExtractLargestIsosurface
MODULES ${VTK_LIBRARIES}
)
Download and Build ExtractLargestIsosurface¶
Click here to download ExtractLargestIsosurface and its CMakeLists.txt file. Once the tarball ExtractLargestIsosurface.tar has been downloaded and extracted,
cd ExtractLargestIsosurface/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./ExtractLargestIsosurface
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.