Repository files navigation

ExplodedVolumes

English | 中文 | Nederlands

Introduction

ExplodedVolumes is a C++17/OpenGL application for interactive visualization of volumetric data. It loads NIfTI volume data, extracts an iso-surface with Marching Cubes, computes or selects an explosion axis, constructs cutting planes, separates the resulting components, and renders the result in both normal and exploded-view modes.

The project is designed as a source-only archive and as a course project of TU Eindhoven. Third-party headers and platform-specific binary libraries are intentionally not bundled. Before compiling, each user must reconstruct the local dependency folder using libraries that match their operating system, CPU architecture, and compiler toolchain.


Table of Contents


1. Project Context

Many volumetric data sets contain internal structures that cannot be adequately understood from the exterior iso-surface alone. An exploded view addresses this limitation by cutting a surface into a sequence of components and translating those components along a chosen direction. The resulting visualization exposes hidden geometry while preserving the spatial relationship between the separated pieces.

In this implementation, the input is a scientific or medical volume stored in NIfTI format. The program extracts a triangulated iso-surface, estimates candidate explosion directions, creates cutting planes, separates the mesh into components, and renders the output in an interactive OpenGL viewer. The rendering style is intentionally edge-enhanced to improve surface readability.


2. Results

Main Interface

Main Interface

Main window with Marching Cubes control panel, explosion axis settings, and explosion view controls

Exploded View

Normal ViewExploded View
Iguana NormalIguana Exploded
chris_t1 Normalchris_t1 Exploded
CT_Abdo NormalCT_Abdo Exploded
CT_Philips NormalCT_Philips Exploded

Comparison between normal rendering (left) and exploded view (right) for multiple datasets

3. Functional Overview

The current implementation provides the following functionality:

  • loading .nii NIfTI volume files through a native file dialog;
  • extracting triangulated iso-surfaces with Marching Cubes;
  • rendering normal and exploded views in an OpenGL 3.3 Core profile context;
  • estimating or selecting explosion axes using PCA-, symmetry-, and combined-strategy code paths;
  • constructing cutting planes and separating the mesh into exploded components;
  • interactively adjusting the iso-level and explosion distance;
  • visualizing the explosion axis;
  • rotating and zooming the camera;
  • applying a framebuffer-based post-processing pass for edge-enhanced rendering;
  • exposing runtime controls through Dear ImGui.

4. Methodological Pipeline

The implementation can be read as the following data-flow pipeline:

NIfTI volume
↓
VolumeData representation
↓
Marching Cubes iso-surface extraction
↓
Explosion-axis estimation or selection
↓
Cutting-plane generation and selection
↓
Surface segmentation
↓
Normal or exploded-view rendering
↓
Post-processing and ImGui overlay

The active rendering loop is located in main.cpp. Rendering and user-interface construction are implemented mainly in visual.cpp, while post-processing is handled by post_processor.cpp. Cutting-plane and exploded-view logic is implemented under planes/, and explosion-axis estimation is implemented under explosionaxis/.


5. Source Tree

A source-only copy of the project has the following approximate structure:

.
├── main.cpp # Program entry point and active render loop
├── data.cpp # NIfTI loading and volume utilities
├── marching_cubes.cpp # Marching Cubes iso-surface extraction
├── visual.cpp # GLFW/OpenGL/ImGui rendering and UI
├── post_processor.cpp # FBO-based post-processing pass
├── glad.c # GLAD OpenGL loader implementation
├── nifti1_io.c # NIfTI reader implementation
├── znzlib.c # NIfTI low-level file I/O helper
├── file_dialog.h # Wrapper around portable-file-dialogs
├── headers/
│ ├── data.h
│ ├── marching_cubes.h
│ ├── visual.h
│ ├── post_processor.h
│ ├── explosionaxis/ # Explosion-axis strategy headers
│ └── planes/ # Cutting-plane and exploded-view headers
├── explosionaxis/ # Explosion-axis strategy implementations
├── planes/ # Cutting-plane, selection, and exploded-view code
├── imgui/ # Dear ImGui implementation files used by the project
└── dependencies/ # Local dependency folder; reconstructed by the user

The dependencies/ directory is normally not committed. It should be created locally according to the platform-specific build instructions below.


6. Dependency Model

6.1 Source-Only Distribution Policy

This project is distributed as source code without third-party binary dependencies. This avoids shipping platform-specific libraries that may be incompatible with a different compiler, operating system, or CPU architecture.

In practice, this indicates:

  • do not expect a pre-filled dependency folder in a clean source archive;
  • reconstruct the dependency folder locally;
  • use Windows libraries only for Windows builds;
  • use macOS libraries only for macOS builds;
  • do not mix binary artifacts from different operating systems, CPU architectures, or compiler toolchains.

6.2 Shared Dependency Layout

The build commands in this README assume the following local layout. Equivalent paths can be used, but the include and library flags must then be adjusted accordingly.

dependencies/
├── include/
│ ├── GLFW/ # GLFW headers
│ ├── glad/ # glad.h
│ ├── KHR/ # khrplatform.h
│ ├── glm/ # GLM headers
│ ├── Eigen/ # Eigen headers, or use an external Eigen include path
│ ├── imgui.h
│ ├── imconfig.h
│ ├── imgui_internal.h
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ ├── imstb_truetype.h
│ ├── imgui_impl_glfw.h
│ ├── imgui_impl_opengl3.h
│ ├── nifti1.h
│ ├── nifti1_io.h
│ ├── nifti1_io_version.h
│ ├── znzlib.h
│ ├── znzlib_version.h
│ └── portable-file-dialogs.h
└── library/
└── platform-specific libraries, such as GLFW and OpenMP runtimes

The following components are used by the application:

DependencyRoleTypical handling
C++17 compilerCompiles the applicationClang, MinGW-w64, or MSVC
OpenGL 3.3Rendering backendProvided by platform and graphics driver
GLFWWindow, OpenGL context, inputHeader + platform-specific library
GLADOpenGL function loaderCompile glad.c; provide matching glad/ and KHR/ headers
Dear ImGuiRuntime GUICompile the bundled ImGui .cpp files; provide matching headers
GLMGraphics mathematicsHeader-only
EigenLinear algebra for axis estimationHeader-only
NIfTI C filesVolume loadingCompile nifti1_io.c and znzlib.c; provide matching headers
portable-file-dialogsNative file dialogSingle header
OpenMPParallel CPU loopsCompiler flag and runtime library
zlibOptional compressed NIfTI supportLink when HAVE_ZLIB is enabled or required by the local NIfTI configuration
PCL / VTK / BoostGeometry and rendering support used by the current MakefileInstall with Homebrew on macOS

6.3 Platform-Specific Binary Rule

Compiled libraries must match the target platform and compiler ABI.

File typeTypical context
.aWindows MinGW-w64 or compatible GCC-style toolchain
.libWindows MSVC
.dllWindows runtime library
.dylibmacOS dynamic library
.frameworkmacOS system or framework dependency

For example, MSVC should not link against MinGW .a files, and macOS .dylib files cannot be used in a Windows build. Apple Silicon builds require arm64-compatible dependencies; Intel macOS builds require x86_64-compatible dependencies.


7. Windows Build

Windows builds should use Windows-compatible headers and libraries only. Do not reuse macOS .dylib files, Homebrew paths, or macOS framework flags.

Create the local dependency directories:

mkdir dependencies
mkdir dependencies\include
mkdir dependencies\library

Populate dependencies\include with the headers listed in Section 6.2, and place the matching Windows GLFW/OpenMP runtime libraries under dependencies\library.

MinGW-w64

Run from the project root in PowerShell:

$Sources=@(
"glad.c","znzlib.c","nifti1_io.c","imgui\imgui.cpp","imgui\imgui_draw.cpp","imgui\imgui_impl_glfw.cpp","imgui\imgui_impl_opengl3.cpp","imgui\imgui_tables.cpp","imgui\imgui_widgets.cpp","explosionaxis\eigen_reflective_symmetry_detector.cpp","explosionaxis\eigen_rotational_symmetry_detector.cpp","explosionaxis\explosion_axis_strategy.cpp","explosionaxis\mitra_reflective_symmetry_detector.cpp","explosionaxis\mitra_rotational_symmetry_detector.cpp","explosionaxis\pca_analyzer.cpp","explosionaxis\pcl_reflective_symmetry_detector.cpp","explosionaxis\pcl_rotational_symmetry_detector.cpp","explosionaxis\vector_ops.cpp","planes\cutting_planes.cpp","planes\exploded_view.cpp","planes\selecting_planes.cpp","data.cpp","main.cpp","marching_cubes.cpp","post_processor.cpp","visual.cpp"
)
g++-std=c++17-O2 -g -fopenmp `-I "dependencies\include"`-I "headers"`-I "headers\explosionaxis"`-I "headers\planes"`$Sources`-L "dependencies\library"`-lglfw3 -lopengl32 -lgdi32 -lole32 -lcomctl32 -loleaut32 -luuid `-o explodedvolumes-mingw.exe

If the GLFW build is dynamic, copy the matching GLFW .dll next to the generated executable.

MSVC

Run from an x64 Native Tools Command Prompt for Visual Studio, or another shell where cl.exe is configured:

setGLFW_LIB=C:\path\to\glfw\lib-vc2022
cl /std:c++17 /EHsc /O2 /openmp ^
/I dependencies\include ^
/I headers ^
/I headers\explosionaxis ^
/I headers\planes ^
glad.c znzlib.c nifti1_io.c ^
imgui\imgui.cpp imgui\imgui_draw.cpp imgui\imgui_impl_glfw.cpp ^
imgui\imgui_impl_opengl3.cpp imgui\imgui_tables.cpp imgui\imgui_widgets.cpp ^
explosionaxis\eigen_reflective_symmetry_detector.cpp ^
explosionaxis\eigen_rotational_symmetry_detector.cpp ^
explosionaxis\explosion_axis_strategy.cpp ^
explosionaxis\mitra_reflective_symmetry_detector.cpp ^
explosionaxis\mitra_rotational_symmetry_detector.cpp ^
explosionaxis\pca_analyzer.cpp ^
explosionaxis\pcl_reflective_symmetry_detector.cpp ^
explosionaxis\pcl_rotational_symmetry_detector.cpp ^
explosionaxis\vector_ops.cpp ^
planes\cutting_planes.cpp planes\exploded_view.cpp planes\selecting_planes.cpp ^
data.cpp main.cpp marching_cubes.cpp post_processor.cpp visual.cpp ^
/Fe:explodedvolumes-msvc.exe ^
/link /LIBPATH:%GLFW_LIB% glfw3.lib opengl32.lib gdi32.lib ole32.lib comctl32.lib oleaut32.lib uuid.lib user32.lib shell32.lib

If the GLFW build is dynamic, copy the matching GLFW .dll next to explodedvolumes-msvc.exe.


8. macOS Build

The current build entry point is the root Makefile.

Install the Homebrew dependency set:

brew install glfw glm eigen boost pcl vtk libomp nlohmann-json

Prepare the local dependency layout expected by the Makefile:

mkdir -p dependencies/include dependencies/library
ln -sf "$(brew --prefix glfw)/lib/libglfw.3.dylib" dependencies/library/libglfw.3.4.dylib
ln -sfn "$(brew --prefix vtk)" dependencies/VTK
ln -sfn "$(brew --prefix glm)/include/glm" dependencies/include/glm
ln -sfn "$(brew --prefix eigen)/include/eigen3/Eigen" dependencies/include/Eigen
ln -sfn "$(brew --prefix boost)/include/boost" dependencies/include/boost

The project-local headers listed in Section 6.2 must also be available under dependencies/include.

Build:

make

If your PCL version differs from the Makefile default:

make PCL_VERSION=1.15.1

For Intel macOS or a custom Homebrew prefix:

make BREW_PREFIX=/usr/local

Clean build outputs:

make clean

9. Running the Application

macOS:

make run

Windows MinGW:

.\explodedvolumes-mingw.exe

Windows MSVC:

explodedvolumes-msvc.exe

The application opens a file dialog. Select a .nii volume file for which you have permission to use and, if applicable, redistribute. Public releases should not include private or identifiable medical data.


10. Interaction Guide

ActionControl
Rotate cameraLeft mouse drag
ZoomMouse wheel
Adjust camera distance+ / -
Close applicationEsc
Change iso-levelImGui Marching Cubes control panel
Toggle exploded viewImGui Explosion View control panel
Adjust explosion distanceImGui Explosion View control panel
Show or hide explosion axisImGui Explosion Axis Settings panel

11. VS Code Configuration Notes

For macOS, create a VS Code build task named Build OpenGL that runs:

make

A launch configuration can use:

{
"program": "${workspaceFolder}/app",
"cwd": "${workspaceFolder}",
"preLaunchTask": "Build OpenGL"
}

Use ${workspaceFolder} rather than ${fileDirname}. The latter changes depending on which file is currently focused in the editor and can lead to inconsistent build or runtime paths.


12. Known Limitations

  • The repository does not yet provide a cross-platform CMake configuration.
  • The source-only distribution requires users to reconstruct third-party headers and platform-specific libraries locally.
  • The current Makefile is macOS-oriented and version-sensitive when PCL or VTK paths change.
  • The current file dialog focuses on .nii input. Additional work may be needed for convenient .nii.gz handling.
  • imgui.ini may be generated or updated by Dear ImGui to store UI layout. This is normal and does not indicate that input volume files have been modified.

13. Third-Party Components and References

Before compiling, check the availability of all third-party components used in the local build:

The visualization concept follows the general idea of exploded-view representations of complex surfaces, especially:

Olga Karpenko, Wilmot Li, Niloy Mitra, and Maneesh Agrawala. Exploded View Diagrams of Mathematical Surfaces.IEEE Transactions on Visualization and Computer Graphics, 16(6), 2010, 1311–1318. DOI: 10.1109/TVCG.2010.151.

The authors gratefully acknowledge M. Chamberland and H. van de Wetering for their guidance and valuable feedback during the development of this project.

About

Interactive C++/OpenGL tool for exploded-view visualization of NIfTI volume data using Marching Cubes, cutting planes, and edge-enhanced rendering.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

ExplodedVolumes

English | 中文 | Nederlands

Introduction

ExplodedVolumes is a C++17/OpenGL application for interactive visualization of volumetric data. It loads NIfTI volume data, extracts an iso-surface with Marching Cubes, computes or selects an explosion axis, constructs cutting planes, separates the resulting components, and renders the result in both normal and exploded-view modes.

The project is designed as a source-only archive and as a course project of TU Eindhoven. Third-party headers and platform-specific binary libraries are intentionally not bundled. Before compiling, each user must reconstruct the local dependency folder using libraries that match their operating system, CPU architecture, and compiler toolchain.


Table of Contents


1. Project Context

Many volumetric data sets contain internal structures that cannot be adequately understood from the exterior iso-surface alone. An exploded view addresses this limitation by cutting a surface into a sequence of components and translating those components along a chosen direction. The resulting visualization exposes hidden geometry while preserving the spatial relationship between the separated pieces.

In this implementation, the input is a scientific or medical volume stored in NIfTI format. The program extracts a triangulated iso-surface, estimates candidate explosion directions, creates cutting planes, separates the mesh into components, and renders the output in an interactive OpenGL viewer. The rendering style is intentionally edge-enhanced to improve surface readability.


2. Results

Main Interface

Main Interface

Main window with Marching Cubes control panel, explosion axis settings, and explosion view controls

Exploded View

Normal ViewExploded View
Iguana NormalIguana Exploded
chris_t1 Normalchris_t1 Exploded
CT_Abdo NormalCT_Abdo Exploded
CT_Philips NormalCT_Philips Exploded

Comparison between normal rendering (left) and exploded view (right) for multiple datasets

3. Functional Overview

The current implementation provides the following functionality:

  • loading .nii NIfTI volume files through a native file dialog;
  • extracting triangulated iso-surfaces with Marching Cubes;
  • rendering normal and exploded views in an OpenGL 3.3 Core profile context;
  • estimating or selecting explosion axes using PCA-, symmetry-, and combined-strategy code paths;
  • constructing cutting planes and separating the mesh into exploded components;
  • interactively adjusting the iso-level and explosion distance;
  • visualizing the explosion axis;
  • rotating and zooming the camera;
  • applying a framebuffer-based post-processing pass for edge-enhanced rendering;
  • exposing runtime controls through Dear ImGui.

4. Methodological Pipeline

The implementation can be read as the following data-flow pipeline:

NIfTI volume
↓
VolumeData representation
↓
Marching Cubes iso-surface extraction
↓
Explosion-axis estimation or selection
↓
Cutting-plane generation and selection
↓
Surface segmentation
↓
Normal or exploded-view rendering
↓
Post-processing and ImGui overlay

The active rendering loop is located in main.cpp. Rendering and user-interface construction are implemented mainly in visual.cpp, while post-processing is handled by post_processor.cpp. Cutting-plane and exploded-view logic is implemented under planes/, and explosion-axis estimation is implemented under explosionaxis/.


5. Source Tree

A source-only copy of the project has the following approximate structure:

.
├── main.cpp # Program entry point and active render loop
├── data.cpp # NIfTI loading and volume utilities
├── marching_cubes.cpp # Marching Cubes iso-surface extraction
├── visual.cpp # GLFW/OpenGL/ImGui rendering and UI
├── post_processor.cpp # FBO-based post-processing pass
├── glad.c # GLAD OpenGL loader implementation
├── nifti1_io.c # NIfTI reader implementation
├── znzlib.c # NIfTI low-level file I/O helper
├── file_dialog.h # Wrapper around portable-file-dialogs
├── headers/
│ ├── data.h
│ ├── marching_cubes.h
│ ├── visual.h
│ ├── post_processor.h
│ ├── explosionaxis/ # Explosion-axis strategy headers
│ └── planes/ # Cutting-plane and exploded-view headers
├── explosionaxis/ # Explosion-axis strategy implementations
├── planes/ # Cutting-plane, selection, and exploded-view code
├── imgui/ # Dear ImGui implementation files used by the project
└── dependencies/ # Local dependency folder; reconstructed by the user

The dependencies/ directory is normally not committed. It should be created locally according to the platform-specific build instructions below.


6. Dependency Model

6.1 Source-Only Distribution Policy

This project is distributed as source code without third-party binary dependencies. This avoids shipping platform-specific libraries that may be incompatible with a different compiler, operating system, or CPU architecture.

In practice, this indicates:

  • do not expect a pre-filled dependency folder in a clean source archive;
  • reconstruct the dependency folder locally;
  • use Windows libraries only for Windows builds;
  • use macOS libraries only for macOS builds;
  • do not mix binary artifacts from different operating systems, CPU architectures, or compiler toolchains.

6.2 Shared Dependency Layout

The build commands in this README assume the following local layout. Equivalent paths can be used, but the include and library flags must then be adjusted accordingly.

dependencies/
├── include/
│ ├── GLFW/ # GLFW headers
│ ├── glad/ # glad.h
│ ├── KHR/ # khrplatform.h
│ ├── glm/ # GLM headers
│ ├── Eigen/ # Eigen headers, or use an external Eigen include path
│ ├── imgui.h
│ ├── imconfig.h
│ ├── imgui_internal.h
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ ├── imstb_truetype.h
│ ├── imgui_impl_glfw.h
│ ├── imgui_impl_opengl3.h
│ ├── nifti1.h
│ ├── nifti1_io.h
│ ├── nifti1_io_version.h
│ ├── znzlib.h
│ ├── znzlib_version.h
│ └── portable-file-dialogs.h
└── library/
└── platform-specific libraries, such as GLFW and OpenMP runtimes

The following components are used by the application:

DependencyRoleTypical handling
C++17 compilerCompiles the applicationClang, MinGW-w64, or MSVC
OpenGL 3.3Rendering backendProvided by platform and graphics driver
GLFWWindow, OpenGL context, inputHeader + platform-specific library
GLADOpenGL function loaderCompile glad.c; provide matching glad/ and KHR/ headers
Dear ImGuiRuntime GUICompile the bundled ImGui .cpp files; provide matching headers
GLMGraphics mathematicsHeader-only
EigenLinear algebra for axis estimationHeader-only
NIfTI C filesVolume loadingCompile nifti1_io.c and znzlib.c; provide matching headers
portable-file-dialogsNative file dialogSingle header
OpenMPParallel CPU loopsCompiler flag and runtime library
zlibOptional compressed NIfTI supportLink when HAVE_ZLIB is enabled or required by the local NIfTI configuration
PCL / VTK / BoostGeometry and rendering support used by the current MakefileInstall with Homebrew on macOS

6.3 Platform-Specific Binary Rule

Compiled libraries must match the target platform and compiler ABI.

File typeTypical context
.aWindows MinGW-w64 or compatible GCC-style toolchain
.libWindows MSVC
.dllWindows runtime library
.dylibmacOS dynamic library
.frameworkmacOS system or framework dependency

For example, MSVC should not link against MinGW .a files, and macOS .dylib files cannot be used in a Windows build. Apple Silicon builds require arm64-compatible dependencies; Intel macOS builds require x86_64-compatible dependencies.


7. Windows Build

Windows builds should use Windows-compatible headers and libraries only. Do not reuse macOS .dylib files, Homebrew paths, or macOS framework flags.

Create the local dependency directories:

mkdir dependencies
mkdir dependencies\include
mkdir dependencies\library

Populate dependencies\include with the headers listed in Section 6.2, and place the matching Windows GLFW/OpenMP runtime libraries under dependencies\library.

MinGW-w64

Run from the project root in PowerShell:

$Sources=@(
"glad.c","znzlib.c","nifti1_io.c","imgui\imgui.cpp","imgui\imgui_draw.cpp","imgui\imgui_impl_glfw.cpp","imgui\imgui_impl_opengl3.cpp","imgui\imgui_tables.cpp","imgui\imgui_widgets.cpp","explosionaxis\eigen_reflective_symmetry_detector.cpp","explosionaxis\eigen_rotational_symmetry_detector.cpp","explosionaxis\explosion_axis_strategy.cpp","explosionaxis\mitra_reflective_symmetry_detector.cpp","explosionaxis\mitra_rotational_symmetry_detector.cpp","explosionaxis\pca_analyzer.cpp","explosionaxis\pcl_reflective_symmetry_detector.cpp","explosionaxis\pcl_rotational_symmetry_detector.cpp","explosionaxis\vector_ops.cpp","planes\cutting_planes.cpp","planes\exploded_view.cpp","planes\selecting_planes.cpp","data.cpp","main.cpp","marching_cubes.cpp","post_processor.cpp","visual.cpp"
)
g++-std=c++17-O2 -g -fopenmp `-I "dependencies\include"`-I "headers"`-I "headers\explosionaxis"`-I "headers\planes"`$Sources`-L "dependencies\library"`-lglfw3 -lopengl32 -lgdi32 -lole32 -lcomctl32 -loleaut32 -luuid `-o explodedvolumes-mingw.exe

If the GLFW build is dynamic, copy the matching GLFW .dll next to the generated executable.

MSVC

Run from an x64 Native Tools Command Prompt for Visual Studio, or another shell where cl.exe is configured:

setGLFW_LIB=C:\path\to\glfw\lib-vc2022
cl /std:c++17 /EHsc /O2 /openmp ^
/I dependencies\include ^
/I headers ^
/I headers\explosionaxis ^
/I headers\planes ^
glad.c znzlib.c nifti1_io.c ^
imgui\imgui.cpp imgui\imgui_draw.cpp imgui\imgui_impl_glfw.cpp ^
imgui\imgui_impl_opengl3.cpp imgui\imgui_tables.cpp imgui\imgui_widgets.cpp ^
explosionaxis\eigen_reflective_symmetry_detector.cpp ^
explosionaxis\eigen_rotational_symmetry_detector.cpp ^
explosionaxis\explosion_axis_strategy.cpp ^
explosionaxis\mitra_reflective_symmetry_detector.cpp ^
explosionaxis\mitra_rotational_symmetry_detector.cpp ^
explosionaxis\pca_analyzer.cpp ^
explosionaxis\pcl_reflective_symmetry_detector.cpp ^
explosionaxis\pcl_rotational_symmetry_detector.cpp ^
explosionaxis\vector_ops.cpp ^
planes\cutting_planes.cpp planes\exploded_view.cpp planes\selecting_planes.cpp ^
data.cpp main.cpp marching_cubes.cpp post_processor.cpp visual.cpp ^
/Fe:explodedvolumes-msvc.exe ^
/link /LIBPATH:%GLFW_LIB% glfw3.lib opengl32.lib gdi32.lib ole32.lib comctl32.lib oleaut32.lib uuid.lib user32.lib shell32.lib

If the GLFW build is dynamic, copy the matching GLFW .dll next to explodedvolumes-msvc.exe.


8. macOS Build

The current build entry point is the root Makefile.

Install the Homebrew dependency set:

brew install glfw glm eigen boost pcl vtk libomp nlohmann-json

Prepare the local dependency layout expected by the Makefile:

mkdir -p dependencies/include dependencies/library
ln -sf "$(brew --prefix glfw)/lib/libglfw.3.dylib" dependencies/library/libglfw.3.4.dylib
ln -sfn "$(brew --prefix vtk)" dependencies/VTK
ln -sfn "$(brew --prefix glm)/include/glm" dependencies/include/glm
ln -sfn "$(brew --prefix eigen)/include/eigen3/Eigen" dependencies/include/Eigen
ln -sfn "$(brew --prefix boost)/include/boost" dependencies/include/boost

The project-local headers listed in Section 6.2 must also be available under dependencies/include.

Build:

make

If your PCL version differs from the Makefile default:

make PCL_VERSION=1.15.1

For Intel macOS or a custom Homebrew prefix:

make BREW_PREFIX=/usr/local

Clean build outputs:

make clean

9. Running the Application

macOS:

make run

Windows MinGW:

.\explodedvolumes-mingw.exe

Windows MSVC:

explodedvolumes-msvc.exe

The application opens a file dialog. Select a .nii volume file for which you have permission to use and, if applicable, redistribute. Public releases should not include private or identifiable medical data.


10. Interaction Guide

ActionControl
Rotate cameraLeft mouse drag
ZoomMouse wheel
Adjust camera distance+ / -
Close applicationEsc
Change iso-levelImGui Marching Cubes control panel
Toggle exploded viewImGui Explosion View control panel
Adjust explosion distanceImGui Explosion View control panel
Show or hide explosion axisImGui Explosion Axis Settings panel

11. VS Code Configuration Notes

For macOS, create a VS Code build task named Build OpenGL that runs:

make

A launch configuration can use:

{
"program": "${workspaceFolder}/app",
"cwd": "${workspaceFolder}",
"preLaunchTask": "Build OpenGL"
}

Use ${workspaceFolder} rather than ${fileDirname}. The latter changes depending on which file is currently focused in the editor and can lead to inconsistent build or runtime paths.


12. Known Limitations

  • The repository does not yet provide a cross-platform CMake configuration.
  • The source-only distribution requires users to reconstruct third-party headers and platform-specific libraries locally.
  • The current Makefile is macOS-oriented and version-sensitive when PCL or VTK paths change.
  • The current file dialog focuses on .nii input. Additional work may be needed for convenient .nii.gz handling.
  • imgui.ini may be generated or updated by Dear ImGui to store UI layout. This is normal and does not indicate that input volume files have been modified.

13. Third-Party Components and References

Before compiling, check the availability of all third-party components used in the local build:

The visualization concept follows the general idea of exploded-view representations of complex surfaces, especially:

Olga Karpenko, Wilmot Li, Niloy Mitra, and Maneesh Agrawala. Exploded View Diagrams of Mathematical Surfaces.IEEE Transactions on Visualization and Computer Graphics, 16(6), 2010, 1311–1318. DOI: 10.1109/TVCG.2010.151.

The authors gratefully acknowledge M. Chamberland and H. van de Wetering for their guidance and valuable feedback during the development of this project.

About

Interactive C++/OpenGL tool for exploded-view visualization of NIfTI volume data using Marching Cubes, cutting planes, and edge-enhanced rendering.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ExplodedVolumes

English | 中文 | Nederlands

Introduction

ExplodedVolumes is a C++17/OpenGL application for interactive visualization of volumetric data. It loads NIfTI volume data, extracts an iso-surface with Marching Cubes, computes or selects an explosion axis, constructs cutting planes, separates the resulting components, and renders the result in both normal and exploded-view modes.

The project is designed as a source-only archive and as a course project of TU Eindhoven. Third-party headers and platform-specific binary libraries are intentionally not bundled. Before compiling, each user must reconstruct the local dependency folder using libraries that match their operating system, CPU architecture, and compiler toolchain.


Table of Contents


1. Project Context

Many volumetric data sets contain internal structures that cannot be adequately understood from the exterior iso-surface alone. An exploded view addresses this limitation by cutting a surface into a sequence of components and translating those components along a chosen direction. The resulting visualization exposes hidden geometry while preserving the spatial relationship between the separated pieces.

In this implementation, the input is a scientific or medical volume stored in NIfTI format. The program extracts a triangulated iso-surface, estimates candidate explosion directions, creates cutting planes, separates the mesh into components, and renders the output in an interactive OpenGL viewer. The rendering style is intentionally edge-enhanced to improve surface readability.


2. Results

Main Interface

Main Interface

Main window with Marching Cubes control panel, explosion axis settings, and explosion view controls

Exploded View

Normal ViewExploded View
Iguana NormalIguana Exploded
chris_t1 Normalchris_t1 Exploded
CT_Abdo NormalCT_Abdo Exploded
CT_Philips NormalCT_Philips Exploded

Comparison between normal rendering (left) and exploded view (right) for multiple datasets

3. Functional Overview

The current implementation provides the following functionality:

  • loading .nii NIfTI volume files through a native file dialog;
  • extracting triangulated iso-surfaces with Marching Cubes;
  • rendering normal and exploded views in an OpenGL 3.3 Core profile context;
  • estimating or selecting explosion axes using PCA-, symmetry-, and combined-strategy code paths;
  • constructing cutting planes and separating the mesh into exploded components;
  • interactively adjusting the iso-level and explosion distance;
  • visualizing the explosion axis;
  • rotating and zooming the camera;
  • applying a framebuffer-based post-processing pass for edge-enhanced rendering;
  • exposing runtime controls through Dear ImGui.

4. Methodological Pipeline

The implementation can be read as the following data-flow pipeline:

NIfTI volume
↓
VolumeData representation
↓
Marching Cubes iso-surface extraction
↓
Explosion-axis estimation or selection
↓
Cutting-plane generation and selection
↓
Surface segmentation
↓
Normal or exploded-view rendering
↓
Post-processing and ImGui overlay

The active rendering loop is located in main.cpp. Rendering and user-interface construction are implemented mainly in visual.cpp, while post-processing is handled by post_processor.cpp. Cutting-plane and exploded-view logic is implemented under planes/, and explosion-axis estimation is implemented under explosionaxis/.


5. Source Tree

A source-only copy of the project has the following approximate structure:

.
├── main.cpp # Program entry point and active render loop
├── data.cpp # NIfTI loading and volume utilities
├── marching_cubes.cpp # Marching Cubes iso-surface extraction
├── visual.cpp # GLFW/OpenGL/ImGui rendering and UI
├── post_processor.cpp # FBO-based post-processing pass
├── glad.c # GLAD OpenGL loader implementation
├── nifti1_io.c # NIfTI reader implementation
├── znzlib.c # NIfTI low-level file I/O helper
├── file_dialog.h # Wrapper around portable-file-dialogs
├── headers/
│ ├── data.h
│ ├── marching_cubes.h
│ ├── visual.h
│ ├── post_processor.h
│ ├── explosionaxis/ # Explosion-axis strategy headers
│ └── planes/ # Cutting-plane and exploded-view headers
├── explosionaxis/ # Explosion-axis strategy implementations
├── planes/ # Cutting-plane, selection, and exploded-view code
├── imgui/ # Dear ImGui implementation files used by the project
└── dependencies/ # Local dependency folder; reconstructed by the user

The dependencies/ directory is normally not committed. It should be created locally according to the platform-specific build instructions below.


6. Dependency Model

6.1 Source-Only Distribution Policy

This project is distributed as source code without third-party binary dependencies. This avoids shipping platform-specific libraries that may be incompatible with a different compiler, operating system, or CPU architecture.

In practice, this indicates:

  • do not expect a pre-filled dependency folder in a clean source archive;
  • reconstruct the dependency folder locally;
  • use Windows libraries only for Windows builds;
  • use macOS libraries only for macOS builds;
  • do not mix binary artifacts from different operating systems, CPU architectures, or compiler toolchains.

6.2 Shared Dependency Layout

The build commands in this README assume the following local layout. Equivalent paths can be used, but the include and library flags must then be adjusted accordingly.

dependencies/
├── include/
│ ├── GLFW/ # GLFW headers
│ ├── glad/ # glad.h
│ ├── KHR/ # khrplatform.h
│ ├── glm/ # GLM headers
│ ├── Eigen/ # Eigen headers, or use an external Eigen include path
│ ├── imgui.h
│ ├── imconfig.h
│ ├── imgui_internal.h
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ ├── imstb_truetype.h
│ ├── imgui_impl_glfw.h
│ ├── imgui_impl_opengl3.h
│ ├── nifti1.h
│ ├── nifti1_io.h
│ ├── nifti1_io_version.h
│ ├── znzlib.h
│ ├── znzlib_version.h
│ └── portable-file-dialogs.h
└── library/
└── platform-specific libraries, such as GLFW and OpenMP runtimes

The following components are used by the application:

DependencyRoleTypical handling
C++17 compilerCompiles the applicationClang, MinGW-w64, or MSVC
OpenGL 3.3Rendering backendProvided by platform and graphics driver
GLFWWindow, OpenGL context, inputHeader + platform-specific library
GLADOpenGL function loaderCompile glad.c; provide matching glad/ and KHR/ headers
Dear ImGuiRuntime GUICompile the bundled ImGui .cpp files; provide matching headers
GLMGraphics mathematicsHeader-only
EigenLinear algebra for axis estimationHeader-only
NIfTI C filesVolume loadingCompile nifti1_io.c and znzlib.c; provide matching headers
portable-file-dialogsNative file dialogSingle header
OpenMPParallel CPU loopsCompiler flag and runtime library
zlibOptional compressed NIfTI supportLink when HAVE_ZLIB is enabled or required by the local NIfTI configuration
PCL / VTK / BoostGeometry and rendering support used by the current MakefileInstall with Homebrew on macOS

6.3 Platform-Specific Binary Rule

Compiled libraries must match the target platform and compiler ABI.

File typeTypical context
.aWindows MinGW-w64 or compatible GCC-style toolchain
.libWindows MSVC
.dllWindows runtime library
.dylibmacOS dynamic library
.frameworkmacOS system or framework dependency

For example, MSVC should not link against MinGW .a files, and macOS .dylib files cannot be used in a Windows build. Apple Silicon builds require arm64-compatible dependencies; Intel macOS builds require x86_64-compatible dependencies.


7. Windows Build

Windows builds should use Windows-compatible headers and libraries only. Do not reuse macOS .dylib files, Homebrew paths, or macOS framework flags.

Create the local dependency directories:

mkdir dependencies
mkdir dependencies\include
mkdir dependencies\library

Populate dependencies\include with the headers listed in Section 6.2, and place the matching Windows GLFW/OpenMP runtime libraries under dependencies\library.

MinGW-w64

Run from the project root in PowerShell:

$Sources=@(
"glad.c","znzlib.c","nifti1_io.c","imgui\imgui.cpp","imgui\imgui_draw.cpp","imgui\imgui_impl_glfw.cpp","imgui\imgui_impl_opengl3.cpp","imgui\imgui_tables.cpp","imgui\imgui_widgets.cpp","explosionaxis\eigen_reflective_symmetry_detector.cpp","explosionaxis\eigen_rotational_symmetry_detector.cpp","explosionaxis\explosion_axis_strategy.cpp","explosionaxis\mitra_reflective_symmetry_detector.cpp","explosionaxis\mitra_rotational_symmetry_detector.cpp","explosionaxis\pca_analyzer.cpp","explosionaxis\pcl_reflective_symmetry_detector.cpp","explosionaxis\pcl_rotational_symmetry_detector.cpp","explosionaxis\vector_ops.cpp","planes\cutting_planes.cpp","planes\exploded_view.cpp","planes\selecting_planes.cpp","data.cpp","main.cpp","marching_cubes.cpp","post_processor.cpp","visual.cpp"
)
g++-std=c++17-O2 -g -fopenmp `-I "dependencies\include"`-I "headers"`-I "headers\explosionaxis"`-I "headers\planes"`$Sources`-L "dependencies\library"`-lglfw3 -lopengl32 -lgdi32 -lole32 -lcomctl32 -loleaut32 -luuid `-o explodedvolumes-mingw.exe

If the GLFW build is dynamic, copy the matching GLFW .dll next to the generated executable.

MSVC

Run from an x64 Native Tools Command Prompt for Visual Studio, or another shell where cl.exe is configured:

setGLFW_LIB=C:\path\to\glfw\lib-vc2022
cl /std:c++17 /EHsc /O2 /openmp ^
/I dependencies\include ^
/I headers ^
/I headers\explosionaxis ^
/I headers\planes ^
glad.c znzlib.c nifti1_io.c ^
imgui\imgui.cpp imgui\imgui_draw.cpp imgui\imgui_impl_glfw.cpp ^
imgui\imgui_impl_opengl3.cpp imgui\imgui_tables.cpp imgui\imgui_widgets.cpp ^
explosionaxis\eigen_reflective_symmetry_detector.cpp ^
explosionaxis\eigen_rotational_symmetry_detector.cpp ^
explosionaxis\explosion_axis_strategy.cpp ^
explosionaxis\mitra_reflective_symmetry_detector.cpp ^
explosionaxis\mitra_rotational_symmetry_detector.cpp ^
explosionaxis\pca_analyzer.cpp ^
explosionaxis\pcl_reflective_symmetry_detector.cpp ^
explosionaxis\pcl_rotational_symmetry_detector.cpp ^
explosionaxis\vector_ops.cpp ^
planes\cutting_planes.cpp planes\exploded_view.cpp planes\selecting_planes.cpp ^
data.cpp main.cpp marching_cubes.cpp post_processor.cpp visual.cpp ^
/Fe:explodedvolumes-msvc.exe ^
/link /LIBPATH:%GLFW_LIB% glfw3.lib opengl32.lib gdi32.lib ole32.lib comctl32.lib oleaut32.lib uuid.lib user32.lib shell32.lib

If the GLFW build is dynamic, copy the matching GLFW .dll next to explodedvolumes-msvc.exe.


8. macOS Build

The current build entry point is the root Makefile.

Install the Homebrew dependency set:

brew install glfw glm eigen boost pcl vtk libomp nlohmann-json

Prepare the local dependency layout expected by the Makefile:

mkdir -p dependencies/include dependencies/library
ln -sf "$(brew --prefix glfw)/lib/libglfw.3.dylib" dependencies/library/libglfw.3.4.dylib
ln -sfn "$(brew --prefix vtk)" dependencies/VTK
ln -sfn "$(brew --prefix glm)/include/glm" dependencies/include/glm
ln -sfn "$(brew --prefix eigen)/include/eigen3/Eigen" dependencies/include/Eigen
ln -sfn "$(brew --prefix boost)/include/boost" dependencies/include/boost

The project-local headers listed in Section 6.2 must also be available under dependencies/include.

Build:

make

If your PCL version differs from the Makefile default:

make PCL_VERSION=1.15.1

For Intel macOS or a custom Homebrew prefix:

make BREW_PREFIX=/usr/local

Clean build outputs:

make clean

9. Running the Application

macOS:

make run

Windows MinGW:

.\explodedvolumes-mingw.exe

Windows MSVC:

explodedvolumes-msvc.exe

The application opens a file dialog. Select a .nii volume file for which you have permission to use and, if applicable, redistribute. Public releases should not include private or identifiable medical data.


10. Interaction Guide

ActionControl
Rotate cameraLeft mouse drag
ZoomMouse wheel
Adjust camera distance+ / -
Close applicationEsc
Change iso-levelImGui Marching Cubes control panel
Toggle exploded viewImGui Explosion View control panel
Adjust explosion distanceImGui Explosion View control panel
Show or hide explosion axisImGui Explosion Axis Settings panel

11. VS Code Configuration Notes

For macOS, create a VS Code build task named Build OpenGL that runs:

make

A launch configuration can use:

{
"program": "${workspaceFolder}/app",
"cwd": "${workspaceFolder}",
"preLaunchTask": "Build OpenGL"
}

Use ${workspaceFolder} rather than ${fileDirname}. The latter changes depending on which file is currently focused in the editor and can lead to inconsistent build or runtime paths.


12. Known Limitations

  • The repository does not yet provide a cross-platform CMake configuration.
  • The source-only distribution requires users to reconstruct third-party headers and platform-specific libraries locally.
  • The current Makefile is macOS-oriented and version-sensitive when PCL or VTK paths change.
  • The current file dialog focuses on .nii input. Additional work may be needed for convenient .nii.gz handling.
  • imgui.ini may be generated or updated by Dear ImGui to store UI layout. This is normal and does not indicate that input volume files have been modified.

13. Third-Party Components and References

Before compiling, check the availability of all third-party components used in the local build:

The visualization concept follows the general idea of exploded-view representations of complex surfaces, especially:

Olga Karpenko, Wilmot Li, Niloy Mitra, and Maneesh Agrawala. Exploded View Diagrams of Mathematical Surfaces.IEEE Transactions on Visualization and Computer Graphics, 16(6), 2010, 1311–1318. DOI: 10.1109/TVCG.2010.151.

The authors gratefully acknowledge M. Chamberland and H. van de Wetering for their guidance and valuable feedback during the development of this project.

About

Interactive C++/OpenGL tool for exploded-view visualization of NIfTI volume data using Marching Cubes, cutting planes, and edge-enhanced rendering.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ExplodedVolumes

English | 中文 | Nederlands

Introduction

ExplodedVolumes is a C++17/OpenGL application for interactive visualization of volumetric data. It loads NIfTI volume data, extracts an iso-surface with Marching Cubes, computes or selects an explosion axis, constructs cutting planes, separates the resulting components, and renders the result in both normal and exploded-view modes.

The project is designed as a source-only archive and as a course project of TU Eindhoven. Third-party headers and platform-specific binary libraries are intentionally not bundled. Before compiling, each user must reconstruct the local dependency folder using libraries that match their operating system, CPU architecture, and compiler toolchain.


Table of Contents


1. Project Context

Many volumetric data sets contain internal structures that cannot be adequately understood from the exterior iso-surface alone. An exploded view addresses this limitation by cutting a surface into a sequence of components and translating those components along a chosen direction. The resulting visualization exposes hidden geometry while preserving the spatial relationship between the separated pieces.

In this implementation, the input is a scientific or medical volume stored in NIfTI format. The program extracts a triangulated iso-surface, estimates candidate explosion directions, creates cutting planes, separates the mesh into components, and renders the output in an interactive OpenGL viewer. The rendering style is intentionally edge-enhanced to improve surface readability.


2. Results

Main Interface

Main Interface

Main window with Marching Cubes control panel, explosion axis settings, and explosion view controls

Exploded View

Normal ViewExploded View
Iguana NormalIguana Exploded
chris_t1 Normalchris_t1 Exploded
CT_Abdo NormalCT_Abdo Exploded
CT_Philips NormalCT_Philips Exploded

Comparison between normal rendering (left) and exploded view (right) for multiple datasets

3. Functional Overview

The current implementation provides the following functionality:

  • loading .nii NIfTI volume files through a native file dialog;
  • extracting triangulated iso-surfaces with Marching Cubes;
  • rendering normal and exploded views in an OpenGL 3.3 Core profile context;
  • estimating or selecting explosion axes using PCA-, symmetry-, and combined-strategy code paths;
  • constructing cutting planes and separating the mesh into exploded components;
  • interactively adjusting the iso-level and explosion distance;
  • visualizing the explosion axis;
  • rotating and zooming the camera;
  • applying a framebuffer-based post-processing pass for edge-enhanced rendering;
  • exposing runtime controls through Dear ImGui.

4. Methodological Pipeline

The implementation can be read as the following data-flow pipeline:

NIfTI volume
↓
VolumeData representation
↓
Marching Cubes iso-surface extraction
↓
Explosion-axis estimation or selection
↓
Cutting-plane generation and selection
↓
Surface segmentation
↓
Normal or exploded-view rendering
↓
Post-processing and ImGui overlay

The active rendering loop is located in main.cpp. Rendering and user-interface construction are implemented mainly in visual.cpp, while post-processing is handled by post_processor.cpp. Cutting-plane and exploded-view logic is implemented under planes/, and explosion-axis estimation is implemented under explosionaxis/.


5. Source Tree

A source-only copy of the project has the following approximate structure:

.
├── main.cpp # Program entry point and active render loop
├── data.cpp # NIfTI loading and volume utilities
├── marching_cubes.cpp # Marching Cubes iso-surface extraction
├── visual.cpp # GLFW/OpenGL/ImGui rendering and UI
├── post_processor.cpp # FBO-based post-processing pass
├── glad.c # GLAD OpenGL loader implementation
├── nifti1_io.c # NIfTI reader implementation
├── znzlib.c # NIfTI low-level file I/O helper
├── file_dialog.h # Wrapper around portable-file-dialogs
├── headers/
│ ├── data.h
│ ├── marching_cubes.h
│ ├── visual.h
│ ├── post_processor.h
│ ├── explosionaxis/ # Explosion-axis strategy headers
│ └── planes/ # Cutting-plane and exploded-view headers
├── explosionaxis/ # Explosion-axis strategy implementations
├── planes/ # Cutting-plane, selection, and exploded-view code
├── imgui/ # Dear ImGui implementation files used by the project
└── dependencies/ # Local dependency folder; reconstructed by the user

The dependencies/ directory is normally not committed. It should be created locally according to the platform-specific build instructions below.


6. Dependency Model

6.1 Source-Only Distribution Policy

This project is distributed as source code without third-party binary dependencies. This avoids shipping platform-specific libraries that may be incompatible with a different compiler, operating system, or CPU architecture.

In practice, this indicates:

  • do not expect a pre-filled dependency folder in a clean source archive;
  • reconstruct the dependency folder locally;
  • use Windows libraries only for Windows builds;
  • use macOS libraries only for macOS builds;
  • do not mix binary artifacts from different operating systems, CPU architectures, or compiler toolchains.

6.2 Shared Dependency Layout

The build commands in this README assume the following local layout. Equivalent paths can be used, but the include and library flags must then be adjusted accordingly.

dependencies/
├── include/
│ ├── GLFW/ # GLFW headers
│ ├── glad/ # glad.h
│ ├── KHR/ # khrplatform.h
│ ├── glm/ # GLM headers
│ ├── Eigen/ # Eigen headers, or use an external Eigen include path
│ ├── imgui.h
│ ├── imconfig.h
│ ├── imgui_internal.h
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ ├── imstb_truetype.h
│ ├── imgui_impl_glfw.h
│ ├── imgui_impl_opengl3.h
│ ├── nifti1.h
│ ├── nifti1_io.h
│ ├── nifti1_io_version.h
│ ├── znzlib.h
│ ├── znzlib_version.h
│ └── portable-file-dialogs.h
└── library/
└── platform-specific libraries, such as GLFW and OpenMP runtimes

The following components are used by the application:

DependencyRoleTypical handling
C++17 compilerCompiles the applicationClang, MinGW-w64, or MSVC
OpenGL 3.3Rendering backendProvided by platform and graphics driver
GLFWWindow, OpenGL context, inputHeader + platform-specific library
GLADOpenGL function loaderCompile glad.c; provide matching glad/ and KHR/ headers
Dear ImGuiRuntime GUICompile the bundled ImGui .cpp files; provide matching headers
GLMGraphics mathematicsHeader-only
EigenLinear algebra for axis estimationHeader-only
NIfTI C filesVolume loadingCompile nifti1_io.c and znzlib.c; provide matching headers
portable-file-dialogsNative file dialogSingle header
OpenMPParallel CPU loopsCompiler flag and runtime library
zlibOptional compressed NIfTI supportLink when HAVE_ZLIB is enabled or required by the local NIfTI configuration
PCL / VTK / BoostGeometry and rendering support used by the current MakefileInstall with Homebrew on macOS

6.3 Platform-Specific Binary Rule

Compiled libraries must match the target platform and compiler ABI.

File typeTypical context
.aWindows MinGW-w64 or compatible GCC-style toolchain
.libWindows MSVC
.dllWindows runtime library
.dylibmacOS dynamic library
.frameworkmacOS system or framework dependency

For example, MSVC should not link against MinGW .a files, and macOS .dylib files cannot be used in a Windows build. Apple Silicon builds require arm64-compatible dependencies; Intel macOS builds require x86_64-compatible dependencies.


7. Windows Build

Windows builds should use Windows-compatible headers and libraries only. Do not reuse macOS .dylib files, Homebrew paths, or macOS framework flags.

Create the local dependency directories:

mkdir dependencies
mkdir dependencies\include
mkdir dependencies\library

Populate dependencies\include with the headers listed in Section 6.2, and place the matching Windows GLFW/OpenMP runtime libraries under dependencies\library.

MinGW-w64

Run from the project root in PowerShell:

$Sources=@(
"glad.c","znzlib.c","nifti1_io.c","imgui\imgui.cpp","imgui\imgui_draw.cpp","imgui\imgui_impl_glfw.cpp","imgui\imgui_impl_opengl3.cpp","imgui\imgui_tables.cpp","imgui\imgui_widgets.cpp","explosionaxis\eigen_reflective_symmetry_detector.cpp","explosionaxis\eigen_rotational_symmetry_detector.cpp","explosionaxis\explosion_axis_strategy.cpp","explosionaxis\mitra_reflective_symmetry_detector.cpp","explosionaxis\mitra_rotational_symmetry_detector.cpp","explosionaxis\pca_analyzer.cpp","explosionaxis\pcl_reflective_symmetry_detector.cpp","explosionaxis\pcl_rotational_symmetry_detector.cpp","explosionaxis\vector_ops.cpp","planes\cutting_planes.cpp","planes\exploded_view.cpp","planes\selecting_planes.cpp","data.cpp","main.cpp","marching_cubes.cpp","post_processor.cpp","visual.cpp"
)
g++-std=c++17-O2 -g -fopenmp `-I "dependencies\include"`-I "headers"`-I "headers\explosionaxis"`-I "headers\planes"`$Sources`-L "dependencies\library"`-lglfw3 -lopengl32 -lgdi32 -lole32 -lcomctl32 -loleaut32 -luuid `-o explodedvolumes-mingw.exe

If the GLFW build is dynamic, copy the matching GLFW .dll next to the generated executable.

MSVC

Run from an x64 Native Tools Command Prompt for Visual Studio, or another shell where cl.exe is configured:

setGLFW_LIB=C:\path\to\glfw\lib-vc2022
cl /std:c++17 /EHsc /O2 /openmp ^
/I dependencies\include ^
/I headers ^
/I headers\explosionaxis ^
/I headers\planes ^
glad.c znzlib.c nifti1_io.c ^
imgui\imgui.cpp imgui\imgui_draw.cpp imgui\imgui_impl_glfw.cpp ^
imgui\imgui_impl_opengl3.cpp imgui\imgui_tables.cpp imgui\imgui_widgets.cpp ^
explosionaxis\eigen_reflective_symmetry_detector.cpp ^
explosionaxis\eigen_rotational_symmetry_detector.cpp ^
explosionaxis\explosion_axis_strategy.cpp ^
explosionaxis\mitra_reflective_symmetry_detector.cpp ^
explosionaxis\mitra_rotational_symmetry_detector.cpp ^
explosionaxis\pca_analyzer.cpp ^
explosionaxis\pcl_reflective_symmetry_detector.cpp ^
explosionaxis\pcl_rotational_symmetry_detector.cpp ^
explosionaxis\vector_ops.cpp ^
planes\cutting_planes.cpp planes\exploded_view.cpp planes\selecting_planes.cpp ^
data.cpp main.cpp marching_cubes.cpp post_processor.cpp visual.cpp ^
/Fe:explodedvolumes-msvc.exe ^
/link /LIBPATH:%GLFW_LIB% glfw3.lib opengl32.lib gdi32.lib ole32.lib comctl32.lib oleaut32.lib uuid.lib user32.lib shell32.lib

If the GLFW build is dynamic, copy the matching GLFW .dll next to explodedvolumes-msvc.exe.


8. macOS Build

The current build entry point is the root Makefile.

Install the Homebrew dependency set:

brew install glfw glm eigen boost pcl vtk libomp nlohmann-json

Prepare the local dependency layout expected by the Makefile:

mkdir -p dependencies/include dependencies/library
ln -sf "$(brew --prefix glfw)/lib/libglfw.3.dylib" dependencies/library/libglfw.3.4.dylib
ln -sfn "$(brew --prefix vtk)" dependencies/VTK
ln -sfn "$(brew --prefix glm)/include/glm" dependencies/include/glm
ln -sfn "$(brew --prefix eigen)/include/eigen3/Eigen" dependencies/include/Eigen
ln -sfn "$(brew --prefix boost)/include/boost" dependencies/include/boost

The project-local headers listed in Section 6.2 must also be available under dependencies/include.

Build:

make

If your PCL version differs from the Makefile default:

make PCL_VERSION=1.15.1

For Intel macOS or a custom Homebrew prefix:

make BREW_PREFIX=/usr/local

Clean build outputs:

make clean

9. Running the Application

macOS:

make run

Windows MinGW:

.\explodedvolumes-mingw.exe

Windows MSVC:

explodedvolumes-msvc.exe

The application opens a file dialog. Select a .nii volume file for which you have permission to use and, if applicable, redistribute. Public releases should not include private or identifiable medical data.


10. Interaction Guide

ActionControl
Rotate cameraLeft mouse drag
ZoomMouse wheel
Adjust camera distance+ / -
Close applicationEsc
Change iso-levelImGui Marching Cubes control panel
Toggle exploded viewImGui Explosion View control panel
Adjust explosion distanceImGui Explosion View control panel
Show or hide explosion axisImGui Explosion Axis Settings panel

11. VS Code Configuration Notes

For macOS, create a VS Code build task named Build OpenGL that runs:

make

A launch configuration can use:

{
"program": "${workspaceFolder}/app",
"cwd": "${workspaceFolder}",
"preLaunchTask": "Build OpenGL"
}

Use ${workspaceFolder} rather than ${fileDirname}. The latter changes depending on which file is currently focused in the editor and can lead to inconsistent build or runtime paths.


12. Known Limitations

  • The repository does not yet provide a cross-platform CMake configuration.
  • The source-only distribution requires users to reconstruct third-party headers and platform-specific libraries locally.
  • The current Makefile is macOS-oriented and version-sensitive when PCL or VTK paths change.
  • The current file dialog focuses on .nii input. Additional work may be needed for convenient .nii.gz handling.
  • imgui.ini may be generated or updated by Dear ImGui to store UI layout. This is normal and does not indicate that input volume files have been modified.

13. Third-Party Components and References

Before compiling, check the availability of all third-party components used in the local build:

The visualization concept follows the general idea of exploded-view representations of complex surfaces, especially:

Olga Karpenko, Wilmot Li, Niloy Mitra, and Maneesh Agrawala. Exploded View Diagrams of Mathematical Surfaces.IEEE Transactions on Visualization and Computer Graphics, 16(6), 2010, 1311–1318. DOI: 10.1109/TVCG.2010.151.

The authors gratefully acknowledge M. Chamberland and H. van de Wetering for their guidance and valuable feedback during the development of this project.

About

Interactive C++/OpenGL tool for exploded-view visualization of NIfTI volume data using Marching Cubes, cutting planes, and edge-enhanced rendering.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

ExplodedVolumes

English | 中文 | Nederlands

Introduction

ExplodedVolumes is a C++17/OpenGL application for interactive visualization of volumetric data. It loads NIfTI volume data, extracts an iso-surface with Marching Cubes, computes or selects an explosion axis, constructs cutting planes, separates the resulting components, and renders the result in both normal and exploded-view modes.

The project is designed as a source-only archive and as a course project of TU Eindhoven. Third-party headers and platform-specific binary libraries are intentionally not bundled. Before compiling, each user must reconstruct the local dependency folder using libraries that match their operating system, CPU architecture, and compiler toolchain.


Table of Contents


1. Project Context

Many volumetric data sets contain internal structures that cannot be adequately understood from the exterior iso-surface alone. An exploded view addresses this limitation by cutting a surface into a sequence of components and translating those components along a chosen direction. The resulting visualization exposes hidden geometry while preserving the spatial relationship between the separated pieces.

In this implementation, the input is a scientific or medical volume stored in NIfTI format. The program extracts a triangulated iso-surface, estimates candidate explosion directions, creates cutting planes, separates the mesh into components, and renders the output in an interactive OpenGL viewer. The rendering style is intentionally edge-enhanced to improve surface readability.


2. Results

Main Interface

Main Interface

Main window with Marching Cubes control panel, explosion axis settings, and explosion view controls

Exploded View

Normal ViewExploded View
Iguana NormalIguana Exploded
chris_t1 Normalchris_t1 Exploded
CT_Abdo NormalCT_Abdo Exploded
CT_Philips NormalCT_Philips Exploded

Comparison between normal rendering (left) and exploded view (right) for multiple datasets

3. Functional Overview

The current implementation provides the following functionality:

  • loading .nii NIfTI volume files through a native file dialog;
  • extracting triangulated iso-surfaces with Marching Cubes;
  • rendering normal and exploded views in an OpenGL 3.3 Core profile context;
  • estimating or selecting explosion axes using PCA-, symmetry-, and combined-strategy code paths;
  • constructing cutting planes and separating the mesh into exploded components;
  • interactively adjusting the iso-level and explosion distance;
  • visualizing the explosion axis;
  • rotating and zooming the camera;
  • applying a framebuffer-based post-processing pass for edge-enhanced rendering;
  • exposing runtime controls through Dear ImGui.

4. Methodological Pipeline

The implementation can be read as the following data-flow pipeline:

NIfTI volume
↓
VolumeData representation
↓
Marching Cubes iso-surface extraction
↓
Explosion-axis estimation or selection
↓
Cutting-plane generation and selection
↓
Surface segmentation
↓
Normal or exploded-view rendering
↓
Post-processing and ImGui overlay

The active rendering loop is located in main.cpp. Rendering and user-interface construction are implemented mainly in visual.cpp, while post-processing is handled by post_processor.cpp. Cutting-plane and exploded-view logic is implemented under planes/, and explosion-axis estimation is implemented under explosionaxis/.


5. Source Tree

A source-only copy of the project has the following approximate structure:

.
├── main.cpp # Program entry point and active render loop
├── data.cpp # NIfTI loading and volume utilities
├── marching_cubes.cpp # Marching Cubes iso-surface extraction
├── visual.cpp # GLFW/OpenGL/ImGui rendering and UI
├── post_processor.cpp # FBO-based post-processing pass
├── glad.c # GLAD OpenGL loader implementation
├── nifti1_io.c # NIfTI reader implementation
├── znzlib.c # NIfTI low-level file I/O helper
├── file_dialog.h # Wrapper around portable-file-dialogs
├── headers/
│ ├── data.h
│ ├── marching_cubes.h
│ ├── visual.h
│ ├── post_processor.h
│ ├── explosionaxis/ # Explosion-axis strategy headers
│ └── planes/ # Cutting-plane and exploded-view headers
├── explosionaxis/ # Explosion-axis strategy implementations
├── planes/ # Cutting-plane, selection, and exploded-view code
├── imgui/ # Dear ImGui implementation files used by the project
└── dependencies/ # Local dependency folder; reconstructed by the user

The dependencies/ directory is normally not committed. It should be created locally according to the platform-specific build instructions below.


6. Dependency Model

6.1 Source-Only Distribution Policy

This project is distributed as source code without third-party binary dependencies. This avoids shipping platform-specific libraries that may be incompatible with a different compiler, operating system, or CPU architecture.

In practice, this indicates:

  • do not expect a pre-filled dependency folder in a clean source archive;
  • reconstruct the dependency folder locally;
  • use Windows libraries only for Windows builds;
  • use macOS libraries only for macOS builds;
  • do not mix binary artifacts from different operating systems, CPU architectures, or compiler toolchains.

6.2 Shared Dependency Layout

The build commands in this README assume the following local layout. Equivalent paths can be used, but the include and library flags must then be adjusted accordingly.

dependencies/
├── include/
│ ├── GLFW/ # GLFW headers
│ ├── glad/ # glad.h
│ ├── KHR/ # khrplatform.h
│ ├── glm/ # GLM headers
│ ├── Eigen/ # Eigen headers, or use an external Eigen include path
│ ├── imgui.h
│ ├── imconfig.h
│ ├── imgui_internal.h
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ ├── imstb_truetype.h
│ ├── imgui_impl_glfw.h
│ ├── imgui_impl_opengl3.h
│ ├── nifti1.h
│ ├── nifti1_io.h
│ ├── nifti1_io_version.h
│ ├── znzlib.h
│ ├── znzlib_version.h
│ └── portable-file-dialogs.h
└── library/
└── platform-specific libraries, such as GLFW and OpenMP runtimes

The following components are used by the application:

DependencyRoleTypical handling
C++17 compilerCompiles the applicationClang, MinGW-w64, or MSVC
OpenGL 3.3Rendering backendProvided by platform and graphics driver
GLFWWindow, OpenGL context, inputHeader + platform-specific library
GLADOpenGL function loaderCompile glad.c; provide matching glad/ and KHR/ headers
Dear ImGuiRuntime GUICompile the bundled ImGui .cpp files; provide matching headers
GLMGraphics mathematicsHeader-only
EigenLinear algebra for axis estimationHeader-only
NIfTI C filesVolume loadingCompile nifti1_io.c and znzlib.c; provide matching headers
portable-file-dialogsNative file dialogSingle header
OpenMPParallel CPU loopsCompiler flag and runtime library
zlibOptional compressed NIfTI supportLink when HAVE_ZLIB is enabled or required by the local NIfTI configuration
PCL / VTK / BoostGeometry and rendering support used by the current MakefileInstall with Homebrew on macOS

6.3 Platform-Specific Binary Rule

Compiled libraries must match the target platform and compiler ABI.

File typeTypical context
.aWindows MinGW-w64 or compatible GCC-style toolchain
.libWindows MSVC
.dllWindows runtime library
.dylibmacOS dynamic library
.frameworkmacOS system or framework dependency

For example, MSVC should not link against MinGW .a files, and macOS .dylib files cannot be used in a Windows build. Apple Silicon builds require arm64-compatible dependencies; Intel macOS builds require x86_64-compatible dependencies.


7. Windows Build

Windows builds should use Windows-compatible headers and libraries only. Do not reuse macOS .dylib files, Homebrew paths, or macOS framework flags.

Create the local dependency directories:

mkdir dependencies
mkdir dependencies\include
mkdir dependencies\library

Populate dependencies\include with the headers listed in Section 6.2, and place the matching Windows GLFW/OpenMP runtime libraries under dependencies\library.

MinGW-w64

Run from the project root in PowerShell:

$Sources=@(
"glad.c","znzlib.c","nifti1_io.c","imgui\imgui.cpp","imgui\imgui_draw.cpp","imgui\imgui_impl_glfw.cpp","imgui\imgui_impl_opengl3.cpp","imgui\imgui_tables.cpp","imgui\imgui_widgets.cpp","explosionaxis\eigen_reflective_symmetry_detector.cpp","explosionaxis\eigen_rotational_symmetry_detector.cpp","explosionaxis\explosion_axis_strategy.cpp","explosionaxis\mitra_reflective_symmetry_detector.cpp","explosionaxis\mitra_rotational_symmetry_detector.cpp","explosionaxis\pca_analyzer.cpp","explosionaxis\pcl_reflective_symmetry_detector.cpp","explosionaxis\pcl_rotational_symmetry_detector.cpp","explosionaxis\vector_ops.cpp","planes\cutting_planes.cpp","planes\exploded_view.cpp","planes\selecting_planes.cpp","data.cpp","main.cpp","marching_cubes.cpp","post_processor.cpp","visual.cpp"
)
g++-std=c++17-O2 -g -fopenmp `-I "dependencies\include"`-I "headers"`-I "headers\explosionaxis"`-I "headers\planes"`$Sources`-L "dependencies\library"`-lglfw3 -lopengl32 -lgdi32 -lole32 -lcomctl32 -loleaut32 -luuid `-o explodedvolumes-mingw.exe

If the GLFW build is dynamic, copy the matching GLFW .dll next to the generated executable.

MSVC

Run from an x64 Native Tools Command Prompt for Visual Studio, or another shell where cl.exe is configured:

setGLFW_LIB=C:\path\to\glfw\lib-vc2022
cl /std:c++17 /EHsc /O2 /openmp ^
/I dependencies\include ^
/I headers ^
/I headers\explosionaxis ^
/I headers\planes ^
glad.c znzlib.c nifti1_io.c ^
imgui\imgui.cpp imgui\imgui_draw.cpp imgui\imgui_impl_glfw.cpp ^
imgui\imgui_impl_opengl3.cpp imgui\imgui_tables.cpp imgui\imgui_widgets.cpp ^
explosionaxis\eigen_reflective_symmetry_detector.cpp ^
explosionaxis\eigen_rotational_symmetry_detector.cpp ^
explosionaxis\explosion_axis_strategy.cpp ^
explosionaxis\mitra_reflective_symmetry_detector.cpp ^
explosionaxis\mitra_rotational_symmetry_detector.cpp ^
explosionaxis\pca_analyzer.cpp ^
explosionaxis\pcl_reflective_symmetry_detector.cpp ^
explosionaxis\pcl_rotational_symmetry_detector.cpp ^
explosionaxis\vector_ops.cpp ^
planes\cutting_planes.cpp planes\exploded_view.cpp planes\selecting_planes.cpp ^
data.cpp main.cpp marching_cubes.cpp post_processor.cpp visual.cpp ^
/Fe:explodedvolumes-msvc.exe ^
/link /LIBPATH:%GLFW_LIB% glfw3.lib opengl32.lib gdi32.lib ole32.lib comctl32.lib oleaut32.lib uuid.lib user32.lib shell32.lib

If the GLFW build is dynamic, copy the matching GLFW .dll next to explodedvolumes-msvc.exe.


8. macOS Build

The current build entry point is the root Makefile.

Install the Homebrew dependency set:

brew install glfw glm eigen boost pcl vtk libomp nlohmann-json

Prepare the local dependency layout expected by the Makefile:

mkdir -p dependencies/include dependencies/library
ln -sf "$(brew --prefix glfw)/lib/libglfw.3.dylib" dependencies/library/libglfw.3.4.dylib
ln -sfn "$(brew --prefix vtk)" dependencies/VTK
ln -sfn "$(brew --prefix glm)/include/glm" dependencies/include/glm
ln -sfn "$(brew --prefix eigen)/include/eigen3/Eigen" dependencies/include/Eigen
ln -sfn "$(brew --prefix boost)/include/boost" dependencies/include/boost

The project-local headers listed in Section 6.2 must also be available under dependencies/include.

Build:

make

If your PCL version differs from the Makefile default:

make PCL_VERSION=1.15.1

For Intel macOS or a custom Homebrew prefix:

make BREW_PREFIX=/usr/local

Clean build outputs:

make clean

9. Running the Application

macOS:

make run

Windows MinGW:

.\explodedvolumes-mingw.exe

Windows MSVC:

explodedvolumes-msvc.exe

The application opens a file dialog. Select a .nii volume file for which you have permission to use and, if applicable, redistribute. Public releases should not include private or identifiable medical data.


10. Interaction Guide

ActionControl
Rotate cameraLeft mouse drag
ZoomMouse wheel
Adjust camera distance+ / -
Close applicationEsc
Change iso-levelImGui Marching Cubes control panel
Toggle exploded viewImGui Explosion View control panel
Adjust explosion distanceImGui Explosion View control panel
Show or hide explosion axisImGui Explosion Axis Settings panel

11. VS Code Configuration Notes

For macOS, create a VS Code build task named Build OpenGL that runs:

make

A launch configuration can use:

{
"program": "${workspaceFolder}/app",
"cwd": "${workspaceFolder}",
"preLaunchTask": "Build OpenGL"
}

Use ${workspaceFolder} rather than ${fileDirname}. The latter changes depending on which file is currently focused in the editor and can lead to inconsistent build or runtime paths.


12. Known Limitations

  • The repository does not yet provide a cross-platform CMake configuration.
  • The source-only distribution requires users to reconstruct third-party headers and platform-specific libraries locally.
  • The current Makefile is macOS-oriented and version-sensitive when PCL or VTK paths change.
  • The current file dialog focuses on .nii input. Additional work may be needed for convenient .nii.gz handling.
  • imgui.ini may be generated or updated by Dear ImGui to store UI layout. This is normal and does not indicate that input volume files have been modified.

13. Third-Party Components and References

Before compiling, check the availability of all third-party components used in the local build:

The visualization concept follows the general idea of exploded-view representations of complex surfaces, especially:

Olga Karpenko, Wilmot Li, Niloy Mitra, and Maneesh Agrawala. Exploded View Diagrams of Mathematical Surfaces.IEEE Transactions on Visualization and Computer Graphics, 16(6), 2010, 1311–1318. DOI: 10.1109/TVCG.2010.151.

The authors gratefully acknowledge M. Chamberland and H. van de Wetering for their guidance and valuable feedback during the development of this project.

About

Interactive C++/OpenGL tool for exploded-view visualization of NIfTI volume data using Marching Cubes, cutting planes, and edge-enhanced rendering.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ExplodedVolumes

English | 中文 | Nederlands

Introduction

ExplodedVolumes is a C++17/OpenGL application for interactive visualization of volumetric data. It loads NIfTI volume data, extracts an iso-surface with Marching Cubes, computes or selects an explosion axis, constructs cutting planes, separates the resulting components, and renders the result in both normal and exploded-view modes.

The project is designed as a source-only archive and as a course project of TU Eindhoven. Third-party headers and platform-specific binary libraries are intentionally not bundled. Before compiling, each user must reconstruct the local dependency folder using libraries that match their operating system, CPU architecture, and compiler toolchain.


Table of Contents


1. Project Context

Many volumetric data sets contain internal structures that cannot be adequately understood from the exterior iso-surface alone. An exploded view addresses this limitation by cutting a surface into a sequence of components and translating those components along a chosen direction. The resulting visualization exposes hidden geometry while preserving the spatial relationship between the separated pieces.

In this implementation, the input is a scientific or medical volume stored in NIfTI format. The program extracts a triangulated iso-surface, estimates candidate explosion directions, creates cutting planes, separates the mesh into components, and renders the output in an interactive OpenGL viewer. The rendering style is intentionally edge-enhanced to improve surface readability.


2. Results

Main Interface

Main Interface

Main window with Marching Cubes control panel, explosion axis settings, and explosion view controls

Exploded View

Normal ViewExploded View
Iguana NormalIguana Exploded
chris_t1 Normalchris_t1 Exploded
CT_Abdo NormalCT_Abdo Exploded
CT_Philips NormalCT_Philips Exploded

Comparison between normal rendering (left) and exploded view (right) for multiple datasets

3. Functional Overview

The current implementation provides the following functionality:

  • loading .nii NIfTI volume files through a native file dialog;
  • extracting triangulated iso-surfaces with Marching Cubes;
  • rendering normal and exploded views in an OpenGL 3.3 Core profile context;
  • estimating or selecting explosion axes using PCA-, symmetry-, and combined-strategy code paths;
  • constructing cutting planes and separating the mesh into exploded components;
  • interactively adjusting the iso-level and explosion distance;
  • visualizing the explosion axis;
  • rotating and zooming the camera;
  • applying a framebuffer-based post-processing pass for edge-enhanced rendering;
  • exposing runtime controls through Dear ImGui.

4. Methodological Pipeline

The implementation can be read as the following data-flow pipeline:

NIfTI volume
↓
VolumeData representation
↓
Marching Cubes iso-surface extraction
↓
Explosion-axis estimation or selection
↓
Cutting-plane generation and selection
↓
Surface segmentation
↓
Normal or exploded-view rendering
↓
Post-processing and ImGui overlay

The active rendering loop is located in main.cpp. Rendering and user-interface construction are implemented mainly in visual.cpp, while post-processing is handled by post_processor.cpp. Cutting-plane and exploded-view logic is implemented under planes/, and explosion-axis estimation is implemented under explosionaxis/.


5. Source Tree

A source-only copy of the project has the following approximate structure:

.
├── main.cpp # Program entry point and active render loop
├── data.cpp # NIfTI loading and volume utilities
├── marching_cubes.cpp # Marching Cubes iso-surface extraction
├── visual.cpp # GLFW/OpenGL/ImGui rendering and UI
├── post_processor.cpp # FBO-based post-processing pass
├── glad.c # GLAD OpenGL loader implementation
├── nifti1_io.c # NIfTI reader implementation
├── znzlib.c # NIfTI low-level file I/O helper
├── file_dialog.h # Wrapper around portable-file-dialogs
├── headers/
│ ├── data.h
│ ├── marching_cubes.h
│ ├── visual.h
│ ├── post_processor.h
│ ├── explosionaxis/ # Explosion-axis strategy headers
│ └── planes/ # Cutting-plane and exploded-view headers
├── explosionaxis/ # Explosion-axis strategy implementations
├── planes/ # Cutting-plane, selection, and exploded-view code
├── imgui/ # Dear ImGui implementation files used by the project
└── dependencies/ # Local dependency folder; reconstructed by the user

The dependencies/ directory is normally not committed. It should be created locally according to the platform-specific build instructions below.


6. Dependency Model

6.1 Source-Only Distribution Policy

This project is distributed as source code without third-party binary dependencies. This avoids shipping platform-specific libraries that may be incompatible with a different compiler, operating system, or CPU architecture.

In practice, this indicates:

  • do not expect a pre-filled dependency folder in a clean source archive;
  • reconstruct the dependency folder locally;
  • use Windows libraries only for Windows builds;
  • use macOS libraries only for macOS builds;
  • do not mix binary artifacts from different operating systems, CPU architectures, or compiler toolchains.

6.2 Shared Dependency Layout

The build commands in this README assume the following local layout. Equivalent paths can be used, but the include and library flags must then be adjusted accordingly.

dependencies/
├── include/
│ ├── GLFW/ # GLFW headers
│ ├── glad/ # glad.h
│ ├── KHR/ # khrplatform.h
│ ├── glm/ # GLM headers
│ ├── Eigen/ # Eigen headers, or use an external Eigen include path
│ ├── imgui.h
│ ├── imconfig.h
│ ├── imgui_internal.h
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ ├── imstb_truetype.h
│ ├── imgui_impl_glfw.h
│ ├── imgui_impl_opengl3.h
│ ├── nifti1.h
│ ├── nifti1_io.h
│ ├── nifti1_io_version.h
│ ├── znzlib.h
│ ├── znzlib_version.h
│ └── portable-file-dialogs.h
└── library/
└── platform-specific libraries, such as GLFW and OpenMP runtimes

The following components are used by the application:

DependencyRoleTypical handling
C++17 compilerCompiles the applicationClang, MinGW-w64, or MSVC
OpenGL 3.3Rendering backendProvided by platform and graphics driver
GLFWWindow, OpenGL context, inputHeader + platform-specific library
GLADOpenGL function loaderCompile glad.c; provide matching glad/ and KHR/ headers
Dear ImGuiRuntime GUICompile the bundled ImGui .cpp files; provide matching headers
GLMGraphics mathematicsHeader-only
EigenLinear algebra for axis estimationHeader-only
NIfTI C filesVolume loadingCompile nifti1_io.c and znzlib.c; provide matching headers
portable-file-dialogsNative file dialogSingle header
OpenMPParallel CPU loopsCompiler flag and runtime library
zlibOptional compressed NIfTI supportLink when HAVE_ZLIB is enabled or required by the local NIfTI configuration
PCL / VTK / BoostGeometry and rendering support used by the current MakefileInstall with Homebrew on macOS

6.3 Platform-Specific Binary Rule

Compiled libraries must match the target platform and compiler ABI.

File typeTypical context
.aWindows MinGW-w64 or compatible GCC-style toolchain
.libWindows MSVC
.dllWindows runtime library
.dylibmacOS dynamic library
.frameworkmacOS system or framework dependency

For example, MSVC should not link against MinGW .a files, and macOS .dylib files cannot be used in a Windows build. Apple Silicon builds require arm64-compatible dependencies; Intel macOS builds require x86_64-compatible dependencies.


7. Windows Build

Windows builds should use Windows-compatible headers and libraries only. Do not reuse macOS .dylib files, Homebrew paths, or macOS framework flags.

Create the local dependency directories:

mkdir dependencies
mkdir dependencies\include
mkdir dependencies\library

Populate dependencies\include with the headers listed in Section 6.2, and place the matching Windows GLFW/OpenMP runtime libraries under dependencies\library.

MinGW-w64

Run from the project root in PowerShell:

$Sources=@(
"glad.c","znzlib.c","nifti1_io.c","imgui\imgui.cpp","imgui\imgui_draw.cpp","imgui\imgui_impl_glfw.cpp","imgui\imgui_impl_opengl3.cpp","imgui\imgui_tables.cpp","imgui\imgui_widgets.cpp","explosionaxis\eigen_reflective_symmetry_detector.cpp","explosionaxis\eigen_rotational_symmetry_detector.cpp","explosionaxis\explosion_axis_strategy.cpp","explosionaxis\mitra_reflective_symmetry_detector.cpp","explosionaxis\mitra_rotational_symmetry_detector.cpp","explosionaxis\pca_analyzer.cpp","explosionaxis\pcl_reflective_symmetry_detector.cpp","explosionaxis\pcl_rotational_symmetry_detector.cpp","explosionaxis\vector_ops.cpp","planes\cutting_planes.cpp","planes\exploded_view.cpp","planes\selecting_planes.cpp","data.cpp","main.cpp","marching_cubes.cpp","post_processor.cpp","visual.cpp"
)
g++-std=c++17-O2 -g -fopenmp `-I "dependencies\include"`-I "headers"`-I "headers\explosionaxis"`-I "headers\planes"`$Sources`-L "dependencies\library"`-lglfw3 -lopengl32 -lgdi32 -lole32 -lcomctl32 -loleaut32 -luuid `-o explodedvolumes-mingw.exe

If the GLFW build is dynamic, copy the matching GLFW .dll next to the generated executable.

MSVC

Run from an x64 Native Tools Command Prompt for Visual Studio, or another shell where cl.exe is configured:

setGLFW_LIB=C:\path\to\glfw\lib-vc2022
cl /std:c++17 /EHsc /O2 /openmp ^
/I dependencies\include ^
/I headers ^
/I headers\explosionaxis ^
/I headers\planes ^
glad.c znzlib.c nifti1_io.c ^
imgui\imgui.cpp imgui\imgui_draw.cpp imgui\imgui_impl_glfw.cpp ^
imgui\imgui_impl_opengl3.cpp imgui\imgui_tables.cpp imgui\imgui_widgets.cpp ^
explosionaxis\eigen_reflective_symmetry_detector.cpp ^
explosionaxis\eigen_rotational_symmetry_detector.cpp ^
explosionaxis\explosion_axis_strategy.cpp ^
explosionaxis\mitra_reflective_symmetry_detector.cpp ^
explosionaxis\mitra_rotational_symmetry_detector.cpp ^
explosionaxis\pca_analyzer.cpp ^
explosionaxis\pcl_reflective_symmetry_detector.cpp ^
explosionaxis\pcl_rotational_symmetry_detector.cpp ^
explosionaxis\vector_ops.cpp ^
planes\cutting_planes.cpp planes\exploded_view.cpp planes\selecting_planes.cpp ^
data.cpp main.cpp marching_cubes.cpp post_processor.cpp visual.cpp ^
/Fe:explodedvolumes-msvc.exe ^
/link /LIBPATH:%GLFW_LIB% glfw3.lib opengl32.lib gdi32.lib ole32.lib comctl32.lib oleaut32.lib uuid.lib user32.lib shell32.lib

If the GLFW build is dynamic, copy the matching GLFW .dll next to explodedvolumes-msvc.exe.


8. macOS Build

The current build entry point is the root Makefile.

Install the Homebrew dependency set:

brew install glfw glm eigen boost pcl vtk libomp nlohmann-json

Prepare the local dependency layout expected by the Makefile:

mkdir -p dependencies/include dependencies/library
ln -sf "$(brew --prefix glfw)/lib/libglfw.3.dylib" dependencies/library/libglfw.3.4.dylib
ln -sfn "$(brew --prefix vtk)" dependencies/VTK
ln -sfn "$(brew --prefix glm)/include/glm" dependencies/include/glm
ln -sfn "$(brew --prefix eigen)/include/eigen3/Eigen" dependencies/include/Eigen
ln -sfn "$(brew --prefix boost)/include/boost" dependencies/include/boost

The project-local headers listed in Section 6.2 must also be available under dependencies/include.

Build:

make

If your PCL version differs from the Makefile default:

make PCL_VERSION=1.15.1

For Intel macOS or a custom Homebrew prefix:

make BREW_PREFIX=/usr/local

Clean build outputs:

make clean

9. Running the Application

macOS:

make run

Windows MinGW:

.\explodedvolumes-mingw.exe

Windows MSVC:

explodedvolumes-msvc.exe

The application opens a file dialog. Select a .nii volume file for which you have permission to use and, if applicable, redistribute. Public releases should not include private or identifiable medical data.


10. Interaction Guide

ActionControl
Rotate cameraLeft mouse drag
ZoomMouse wheel
Adjust camera distance+ / -
Close applicationEsc
Change iso-levelImGui Marching Cubes control panel
Toggle exploded viewImGui Explosion View control panel
Adjust explosion distanceImGui Explosion View control panel
Show or hide explosion axisImGui Explosion Axis Settings panel

11. VS Code Configuration Notes

For macOS, create a VS Code build task named Build OpenGL that runs:

make

A launch configuration can use:

{
"program": "${workspaceFolder}/app",
"cwd": "${workspaceFolder}",
"preLaunchTask": "Build OpenGL"
}

Use ${workspaceFolder} rather than ${fileDirname}. The latter changes depending on which file is currently focused in the editor and can lead to inconsistent build or runtime paths.


12. Known Limitations

  • The repository does not yet provide a cross-platform CMake configuration.
  • The source-only distribution requires users to reconstruct third-party headers and platform-specific libraries locally.
  • The current Makefile is macOS-oriented and version-sensitive when PCL or VTK paths change.
  • The current file dialog focuses on .nii input. Additional work may be needed for convenient .nii.gz handling.
  • imgui.ini may be generated or updated by Dear ImGui to store UI layout. This is normal and does not indicate that input volume files have been modified.

13. Third-Party Components and References

Before compiling, check the availability of all third-party components used in the local build:

The visualization concept follows the general idea of exploded-view representations of complex surfaces, especially:

Olga Karpenko, Wilmot Li, Niloy Mitra, and Maneesh Agrawala. Exploded View Diagrams of Mathematical Surfaces.IEEE Transactions on Visualization and Computer Graphics, 16(6), 2010, 1311–1318. DOI: 10.1109/TVCG.2010.151.

The authors gratefully acknowledge M. Chamberland and H. van de Wetering for their guidance and valuable feedback during the development of this project.

About

Interactive C++/OpenGL tool for exploded-view visualization of NIfTI volume data using Marching Cubes, cutting planes, and edge-enhanced rendering.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ExplodedVolumes

English | 中文 | Nederlands

Introduction

ExplodedVolumes is a C++17/OpenGL application for interactive visualization of volumetric data. It loads NIfTI volume data, extracts an iso-surface with Marching Cubes, computes or selects an explosion axis, constructs cutting planes, separates the resulting components, and renders the result in both normal and exploded-view modes.

The project is designed as a source-only archive and as a course project of TU Eindhoven. Third-party headers and platform-specific binary libraries are intentionally not bundled. Before compiling, each user must reconstruct the local dependency folder using libraries that match their operating system, CPU architecture, and compiler toolchain.


Table of Contents


1. Project Context

Many volumetric data sets contain internal structures that cannot be adequately understood from the exterior iso-surface alone. An exploded view addresses this limitation by cutting a surface into a sequence of components and translating those components along a chosen direction. The resulting visualization exposes hidden geometry while preserving the spatial relationship between the separated pieces.

In this implementation, the input is a scientific or medical volume stored in NIfTI format. The program extracts a triangulated iso-surface, estimates candidate explosion directions, creates cutting planes, separates the mesh into components, and renders the output in an interactive OpenGL viewer. The rendering style is intentionally edge-enhanced to improve surface readability.


2. Results

Main Interface

Main Interface

Main window with Marching Cubes control panel, explosion axis settings, and explosion view controls

Exploded View

Normal ViewExploded View
Iguana NormalIguana Exploded
chris_t1 Normalchris_t1 Exploded
CT_Abdo NormalCT_Abdo Exploded
CT_Philips NormalCT_Philips Exploded

Comparison between normal rendering (left) and exploded view (right) for multiple datasets

3. Functional Overview

The current implementation provides the following functionality:

  • loading .nii NIfTI volume files through a native file dialog;
  • extracting triangulated iso-surfaces with Marching Cubes;
  • rendering normal and exploded views in an OpenGL 3.3 Core profile context;
  • estimating or selecting explosion axes using PCA-, symmetry-, and combined-strategy code paths;
  • constructing cutting planes and separating the mesh into exploded components;
  • interactively adjusting the iso-level and explosion distance;
  • visualizing the explosion axis;
  • rotating and zooming the camera;
  • applying a framebuffer-based post-processing pass for edge-enhanced rendering;
  • exposing runtime controls through Dear ImGui.

4. Methodological Pipeline

The implementation can be read as the following data-flow pipeline:

NIfTI volume
↓
VolumeData representation
↓
Marching Cubes iso-surface extraction
↓
Explosion-axis estimation or selection
↓
Cutting-plane generation and selection
↓
Surface segmentation
↓
Normal or exploded-view rendering
↓
Post-processing and ImGui overlay

The active rendering loop is located in main.cpp. Rendering and user-interface construction are implemented mainly in visual.cpp, while post-processing is handled by post_processor.cpp. Cutting-plane and exploded-view logic is implemented under planes/, and explosion-axis estimation is implemented under explosionaxis/.


5. Source Tree

A source-only copy of the project has the following approximate structure:

.
├── main.cpp # Program entry point and active render loop
├── data.cpp # NIfTI loading and volume utilities
├── marching_cubes.cpp # Marching Cubes iso-surface extraction
├── visual.cpp # GLFW/OpenGL/ImGui rendering and UI
├── post_processor.cpp # FBO-based post-processing pass
├── glad.c # GLAD OpenGL loader implementation
├── nifti1_io.c # NIfTI reader implementation
├── znzlib.c # NIfTI low-level file I/O helper
├── file_dialog.h # Wrapper around portable-file-dialogs
├── headers/
│ ├── data.h
│ ├── marching_cubes.h
│ ├── visual.h
│ ├── post_processor.h
│ ├── explosionaxis/ # Explosion-axis strategy headers
│ └── planes/ # Cutting-plane and exploded-view headers
├── explosionaxis/ # Explosion-axis strategy implementations
├── planes/ # Cutting-plane, selection, and exploded-view code
├── imgui/ # Dear ImGui implementation files used by the project
└── dependencies/ # Local dependency folder; reconstructed by the user

The dependencies/ directory is normally not committed. It should be created locally according to the platform-specific build instructions below.


6. Dependency Model

6.1 Source-Only Distribution Policy

This project is distributed as source code without third-party binary dependencies. This avoids shipping platform-specific libraries that may be incompatible with a different compiler, operating system, or CPU architecture.

In practice, this indicates:

  • do not expect a pre-filled dependency folder in a clean source archive;
  • reconstruct the dependency folder locally;
  • use Windows libraries only for Windows builds;
  • use macOS libraries only for macOS builds;
  • do not mix binary artifacts from different operating systems, CPU architectures, or compiler toolchains.

6.2 Shared Dependency Layout

The build commands in this README assume the following local layout. Equivalent paths can be used, but the include and library flags must then be adjusted accordingly.

dependencies/
├── include/
│ ├── GLFW/ # GLFW headers
│ ├── glad/ # glad.h
│ ├── KHR/ # khrplatform.h
│ ├── glm/ # GLM headers
│ ├── Eigen/ # Eigen headers, or use an external Eigen include path
│ ├── imgui.h
│ ├── imconfig.h
│ ├── imgui_internal.h
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ ├── imstb_truetype.h
│ ├── imgui_impl_glfw.h
│ ├── imgui_impl_opengl3.h
│ ├── nifti1.h
│ ├── nifti1_io.h
│ ├── nifti1_io_version.h
│ ├── znzlib.h
│ ├── znzlib_version.h
│ └── portable-file-dialogs.h
└── library/
└── platform-specific libraries, such as GLFW and OpenMP runtimes

The following components are used by the application:

DependencyRoleTypical handling
C++17 compilerCompiles the applicationClang, MinGW-w64, or MSVC
OpenGL 3.3Rendering backendProvided by platform and graphics driver
GLFWWindow, OpenGL context, inputHeader + platform-specific library
GLADOpenGL function loaderCompile glad.c; provide matching glad/ and KHR/ headers
Dear ImGuiRuntime GUICompile the bundled ImGui .cpp files; provide matching headers
GLMGraphics mathematicsHeader-only
EigenLinear algebra for axis estimationHeader-only
NIfTI C filesVolume loadingCompile nifti1_io.c and znzlib.c; provide matching headers
portable-file-dialogsNative file dialogSingle header
OpenMPParallel CPU loopsCompiler flag and runtime library
zlibOptional compressed NIfTI supportLink when HAVE_ZLIB is enabled or required by the local NIfTI configuration
PCL / VTK / BoostGeometry and rendering support used by the current MakefileInstall with Homebrew on macOS

6.3 Platform-Specific Binary Rule

Compiled libraries must match the target platform and compiler ABI.

File typeTypical context
.aWindows MinGW-w64 or compatible GCC-style toolchain
.libWindows MSVC
.dllWindows runtime library
.dylibmacOS dynamic library
.frameworkmacOS system or framework dependency

For example, MSVC should not link against MinGW .a files, and macOS .dylib files cannot be used in a Windows build. Apple Silicon builds require arm64-compatible dependencies; Intel macOS builds require x86_64-compatible dependencies.


7. Windows Build

Windows builds should use Windows-compatible headers and libraries only. Do not reuse macOS .dylib files, Homebrew paths, or macOS framework flags.

Create the local dependency directories:

mkdir dependencies
mkdir dependencies\include
mkdir dependencies\library

Populate dependencies\include with the headers listed in Section 6.2, and place the matching Windows GLFW/OpenMP runtime libraries under dependencies\library.

MinGW-w64

Run from the project root in PowerShell:

$Sources=@(
"glad.c","znzlib.c","nifti1_io.c","imgui\imgui.cpp","imgui\imgui_draw.cpp","imgui\imgui_impl_glfw.cpp","imgui\imgui_impl_opengl3.cpp","imgui\imgui_tables.cpp","imgui\imgui_widgets.cpp","explosionaxis\eigen_reflective_symmetry_detector.cpp","explosionaxis\eigen_rotational_symmetry_detector.cpp","explosionaxis\explosion_axis_strategy.cpp","explosionaxis\mitra_reflective_symmetry_detector.cpp","explosionaxis\mitra_rotational_symmetry_detector.cpp","explosionaxis\pca_analyzer.cpp","explosionaxis\pcl_reflective_symmetry_detector.cpp","explosionaxis\pcl_rotational_symmetry_detector.cpp","explosionaxis\vector_ops.cpp","planes\cutting_planes.cpp","planes\exploded_view.cpp","planes\selecting_planes.cpp","data.cpp","main.cpp","marching_cubes.cpp","post_processor.cpp","visual.cpp"
)
g++-std=c++17-O2 -g -fopenmp `-I "dependencies\include"`-I "headers"`-I "headers\explosionaxis"`-I "headers\planes"`$Sources`-L "dependencies\library"`-lglfw3 -lopengl32 -lgdi32 -lole32 -lcomctl32 -loleaut32 -luuid `-o explodedvolumes-mingw.exe

If the GLFW build is dynamic, copy the matching GLFW .dll next to the generated executable.

MSVC

Run from an x64 Native Tools Command Prompt for Visual Studio, or another shell where cl.exe is configured:

setGLFW_LIB=C:\path\to\glfw\lib-vc2022
cl /std:c++17 /EHsc /O2 /openmp ^
/I dependencies\include ^
/I headers ^
/I headers\explosionaxis ^
/I headers\planes ^
glad.c znzlib.c nifti1_io.c ^
imgui\imgui.cpp imgui\imgui_draw.cpp imgui\imgui_impl_glfw.cpp ^
imgui\imgui_impl_opengl3.cpp imgui\imgui_tables.cpp imgui\imgui_widgets.cpp ^
explosionaxis\eigen_reflective_symmetry_detector.cpp ^
explosionaxis\eigen_rotational_symmetry_detector.cpp ^
explosionaxis\explosion_axis_strategy.cpp ^
explosionaxis\mitra_reflective_symmetry_detector.cpp ^
explosionaxis\mitra_rotational_symmetry_detector.cpp ^
explosionaxis\pca_analyzer.cpp ^
explosionaxis\pcl_reflective_symmetry_detector.cpp ^
explosionaxis\pcl_rotational_symmetry_detector.cpp ^
explosionaxis\vector_ops.cpp ^
planes\cutting_planes.cpp planes\exploded_view.cpp planes\selecting_planes.cpp ^
data.cpp main.cpp marching_cubes.cpp post_processor.cpp visual.cpp ^
/Fe:explodedvolumes-msvc.exe ^
/link /LIBPATH:%GLFW_LIB% glfw3.lib opengl32.lib gdi32.lib ole32.lib comctl32.lib oleaut32.lib uuid.lib user32.lib shell32.lib

If the GLFW build is dynamic, copy the matching GLFW .dll next to explodedvolumes-msvc.exe.


8. macOS Build

The current build entry point is the root Makefile.

Install the Homebrew dependency set:

brew install glfw glm eigen boost pcl vtk libomp nlohmann-json

Prepare the local dependency layout expected by the Makefile:

mkdir -p dependencies/include dependencies/library
ln -sf "$(brew --prefix glfw)/lib/libglfw.3.dylib" dependencies/library/libglfw.3.4.dylib
ln -sfn "$(brew --prefix vtk)" dependencies/VTK
ln -sfn "$(brew --prefix glm)/include/glm" dependencies/include/glm
ln -sfn "$(brew --prefix eigen)/include/eigen3/Eigen" dependencies/include/Eigen
ln -sfn "$(brew --prefix boost)/include/boost" dependencies/include/boost

The project-local headers listed in Section 6.2 must also be available under dependencies/include.

Build:

make

If your PCL version differs from the Makefile default:

make PCL_VERSION=1.15.1

For Intel macOS or a custom Homebrew prefix:

make BREW_PREFIX=/usr/local

Clean build outputs:

make clean

9. Running the Application

macOS:

make run

Windows MinGW:

.\explodedvolumes-mingw.exe

Windows MSVC:

explodedvolumes-msvc.exe

The application opens a file dialog. Select a .nii volume file for which you have permission to use and, if applicable, redistribute. Public releases should not include private or identifiable medical data.


10. Interaction Guide

ActionControl
Rotate cameraLeft mouse drag
ZoomMouse wheel
Adjust camera distance+ / -
Close applicationEsc
Change iso-levelImGui Marching Cubes control panel
Toggle exploded viewImGui Explosion View control panel
Adjust explosion distanceImGui Explosion View control panel
Show or hide explosion axisImGui Explosion Axis Settings panel

11. VS Code Configuration Notes

For macOS, create a VS Code build task named Build OpenGL that runs:

make

A launch configuration can use:

{
"program": "${workspaceFolder}/app",
"cwd": "${workspaceFolder}",
"preLaunchTask": "Build OpenGL"
}

Use ${workspaceFolder} rather than ${fileDirname}. The latter changes depending on which file is currently focused in the editor and can lead to inconsistent build or runtime paths.


12. Known Limitations

  • The repository does not yet provide a cross-platform CMake configuration.
  • The source-only distribution requires users to reconstruct third-party headers and platform-specific libraries locally.
  • The current Makefile is macOS-oriented and version-sensitive when PCL or VTK paths change.
  • The current file dialog focuses on .nii input. Additional work may be needed for convenient .nii.gz handling.
  • imgui.ini may be generated or updated by Dear ImGui to store UI layout. This is normal and does not indicate that input volume files have been modified.

13. Third-Party Components and References

Before compiling, check the availability of all third-party components used in the local build:

The visualization concept follows the general idea of exploded-view representations of complex surfaces, especially:

Olga Karpenko, Wilmot Li, Niloy Mitra, and Maneesh Agrawala. Exploded View Diagrams of Mathematical Surfaces.IEEE Transactions on Visualization and Computer Graphics, 16(6), 2010, 1311–1318. DOI: 10.1109/TVCG.2010.151.

The authors gratefully acknowledge M. Chamberland and H. van de Wetering for their guidance and valuable feedback during the development of this project.

About

Interactive C++/OpenGL tool for exploded-view visualization of NIfTI volume data using Marching Cubes, cutting planes, and edge-enhanced rendering.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

ExplodedVolumes

English | 中文 | Nederlands

Introduction

ExplodedVolumes is a C++17/OpenGL application for interactive visualization of volumetric data. It loads NIfTI volume data, extracts an iso-surface with Marching Cubes, computes or selects an explosion axis, constructs cutting planes, separates the resulting components, and renders the result in both normal and exploded-view modes.

The project is designed as a source-only archive and as a course project of TU Eindhoven. Third-party headers and platform-specific binary libraries are intentionally not bundled. Before compiling, each user must reconstruct the local dependency folder using libraries that match their operating system, CPU architecture, and compiler toolchain.


Table of Contents


1. Project Context

Many volumetric data sets contain internal structures that cannot be adequately understood from the exterior iso-surface alone. An exploded view addresses this limitation by cutting a surface into a sequence of components and translating those components along a chosen direction. The resulting visualization exposes hidden geometry while preserving the spatial relationship between the separated pieces.

In this implementation, the input is a scientific or medical volume stored in NIfTI format. The program extracts a triangulated iso-surface, estimates candidate explosion directions, creates cutting planes, separates the mesh into components, and renders the output in an interactive OpenGL viewer. The rendering style is intentionally edge-enhanced to improve surface readability.


2. Results

Main Interface

Main Interface

Main window with Marching Cubes control panel, explosion axis settings, and explosion view controls

Exploded View

Normal ViewExploded View
Iguana NormalIguana Exploded
chris_t1 Normalchris_t1 Exploded
CT_Abdo NormalCT_Abdo Exploded
CT_Philips NormalCT_Philips Exploded

Comparison between normal rendering (left) and exploded view (right) for multiple datasets

3. Functional Overview

The current implementation provides the following functionality:

  • loading .nii NIfTI volume files through a native file dialog;
  • extracting triangulated iso-surfaces with Marching Cubes;
  • rendering normal and exploded views in an OpenGL 3.3 Core profile context;
  • estimating or selecting explosion axes using PCA-, symmetry-, and combined-strategy code paths;
  • constructing cutting planes and separating the mesh into exploded components;
  • interactively adjusting the iso-level and explosion distance;
  • visualizing the explosion axis;
  • rotating and zooming the camera;
  • applying a framebuffer-based post-processing pass for edge-enhanced rendering;
  • exposing runtime controls through Dear ImGui.

4. Methodological Pipeline

The implementation can be read as the following data-flow pipeline:

NIfTI volume
↓
VolumeData representation
↓
Marching Cubes iso-surface extraction
↓
Explosion-axis estimation or selection
↓
Cutting-plane generation and selection
↓
Surface segmentation
↓
Normal or exploded-view rendering
↓
Post-processing and ImGui overlay

The active rendering loop is located in main.cpp. Rendering and user-interface construction are implemented mainly in visual.cpp, while post-processing is handled by post_processor.cpp. Cutting-plane and exploded-view logic is implemented under planes/, and explosion-axis estimation is implemented under explosionaxis/.


5. Source Tree

A source-only copy of the project has the following approximate structure:

.
├── main.cpp # Program entry point and active render loop
├── data.cpp # NIfTI loading and volume utilities
├── marching_cubes.cpp # Marching Cubes iso-surface extraction
├── visual.cpp # GLFW/OpenGL/ImGui rendering and UI
├── post_processor.cpp # FBO-based post-processing pass
├── glad.c # GLAD OpenGL loader implementation
├── nifti1_io.c # NIfTI reader implementation
├── znzlib.c # NIfTI low-level file I/O helper
├── file_dialog.h # Wrapper around portable-file-dialogs
├── headers/
│ ├── data.h
│ ├── marching_cubes.h
│ ├── visual.h
│ ├── post_processor.h
│ ├── explosionaxis/ # Explosion-axis strategy headers
│ └── planes/ # Cutting-plane and exploded-view headers
├── explosionaxis/ # Explosion-axis strategy implementations
├── planes/ # Cutting-plane, selection, and exploded-view code
├── imgui/ # Dear ImGui implementation files used by the project
└── dependencies/ # Local dependency folder; reconstructed by the user

The dependencies/ directory is normally not committed. It should be created locally according to the platform-specific build instructions below.


6. Dependency Model

6.1 Source-Only Distribution Policy

This project is distributed as source code without third-party binary dependencies. This avoids shipping platform-specific libraries that may be incompatible with a different compiler, operating system, or CPU architecture.

In practice, this indicates:

  • do not expect a pre-filled dependency folder in a clean source archive;
  • reconstruct the dependency folder locally;
  • use Windows libraries only for Windows builds;
  • use macOS libraries only for macOS builds;
  • do not mix binary artifacts from different operating systems, CPU architectures, or compiler toolchains.

6.2 Shared Dependency Layout

The build commands in this README assume the following local layout. Equivalent paths can be used, but the include and library flags must then be adjusted accordingly.

dependencies/
├── include/
│ ├── GLFW/ # GLFW headers
│ ├── glad/ # glad.h
│ ├── KHR/ # khrplatform.h
│ ├── glm/ # GLM headers
│ ├── Eigen/ # Eigen headers, or use an external Eigen include path
│ ├── imgui.h
│ ├── imconfig.h
│ ├── imgui_internal.h
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ ├── imstb_truetype.h
│ ├── imgui_impl_glfw.h
│ ├── imgui_impl_opengl3.h
│ ├── nifti1.h
│ ├── nifti1_io.h
│ ├── nifti1_io_version.h
│ ├── znzlib.h
│ ├── znzlib_version.h
│ └── portable-file-dialogs.h
└── library/
└── platform-specific libraries, such as GLFW and OpenMP runtimes

The following components are used by the application:

DependencyRoleTypical handling
C++17 compilerCompiles the applicationClang, MinGW-w64, or MSVC
OpenGL 3.3Rendering backendProvided by platform and graphics driver
GLFWWindow, OpenGL context, inputHeader + platform-specific library
GLADOpenGL function loaderCompile glad.c; provide matching glad/ and KHR/ headers
Dear ImGuiRuntime GUICompile the bundled ImGui .cpp files; provide matching headers
GLMGraphics mathematicsHeader-only
EigenLinear algebra for axis estimationHeader-only
NIfTI C filesVolume loadingCompile nifti1_io.c and znzlib.c; provide matching headers
portable-file-dialogsNative file dialogSingle header
OpenMPParallel CPU loopsCompiler flag and runtime library
zlibOptional compressed NIfTI supportLink when HAVE_ZLIB is enabled or required by the local NIfTI configuration
PCL / VTK / BoostGeometry and rendering support used by the current MakefileInstall with Homebrew on macOS

6.3 Platform-Specific Binary Rule

Compiled libraries must match the target platform and compiler ABI.

File typeTypical context
.aWindows MinGW-w64 or compatible GCC-style toolchain
.libWindows MSVC
.dllWindows runtime library
.dylibmacOS dynamic library
.frameworkmacOS system or framework dependency

For example, MSVC should not link against MinGW .a files, and macOS .dylib files cannot be used in a Windows build. Apple Silicon builds require arm64-compatible dependencies; Intel macOS builds require x86_64-compatible dependencies.


7. Windows Build

Windows builds should use Windows-compatible headers and libraries only. Do not reuse macOS .dylib files, Homebrew paths, or macOS framework flags.

Create the local dependency directories:

mkdir dependencies
mkdir dependencies\include
mkdir dependencies\library

Populate dependencies\include with the headers listed in Section 6.2, and place the matching Windows GLFW/OpenMP runtime libraries under dependencies\library.

MinGW-w64

Run from the project root in PowerShell:

$Sources=@(
"glad.c","znzlib.c","nifti1_io.c","imgui\imgui.cpp","imgui\imgui_draw.cpp","imgui\imgui_impl_glfw.cpp","imgui\imgui_impl_opengl3.cpp","imgui\imgui_tables.cpp","imgui\imgui_widgets.cpp","explosionaxis\eigen_reflective_symmetry_detector.cpp","explosionaxis\eigen_rotational_symmetry_detector.cpp","explosionaxis\explosion_axis_strategy.cpp","explosionaxis\mitra_reflective_symmetry_detector.cpp","explosionaxis\mitra_rotational_symmetry_detector.cpp","explosionaxis\pca_analyzer.cpp","explosionaxis\pcl_reflective_symmetry_detector.cpp","explosionaxis\pcl_rotational_symmetry_detector.cpp","explosionaxis\vector_ops.cpp","planes\cutting_planes.cpp","planes\exploded_view.cpp","planes\selecting_planes.cpp","data.cpp","main.cpp","marching_cubes.cpp","post_processor.cpp","visual.cpp"
)
g++-std=c++17-O2 -g -fopenmp `-I "dependencies\include"`-I "headers"`-I "headers\explosionaxis"`-I "headers\planes"`$Sources`-L "dependencies\library"`-lglfw3 -lopengl32 -lgdi32 -lole32 -lcomctl32 -loleaut32 -luuid `-o explodedvolumes-mingw.exe

If the GLFW build is dynamic, copy the matching GLFW .dll next to the generated executable.

MSVC

Run from an x64 Native Tools Command Prompt for Visual Studio, or another shell where cl.exe is configured:

setGLFW_LIB=C:\path\to\glfw\lib-vc2022
cl /std:c++17 /EHsc /O2 /openmp ^
/I dependencies\include ^
/I headers ^
/I headers\explosionaxis ^
/I headers\planes ^
glad.c znzlib.c nifti1_io.c ^
imgui\imgui.cpp imgui\imgui_draw.cpp imgui\imgui_impl_glfw.cpp ^
imgui\imgui_impl_opengl3.cpp imgui\imgui_tables.cpp imgui\imgui_widgets.cpp ^
explosionaxis\eigen_reflective_symmetry_detector.cpp ^
explosionaxis\eigen_rotational_symmetry_detector.cpp ^
explosionaxis\explosion_axis_strategy.cpp ^
explosionaxis\mitra_reflective_symmetry_detector.cpp ^
explosionaxis\mitra_rotational_symmetry_detector.cpp ^
explosionaxis\pca_analyzer.cpp ^
explosionaxis\pcl_reflective_symmetry_detector.cpp ^
explosionaxis\pcl_rotational_symmetry_detector.cpp ^
explosionaxis\vector_ops.cpp ^
planes\cutting_planes.cpp planes\exploded_view.cpp planes\selecting_planes.cpp ^
data.cpp main.cpp marching_cubes.cpp post_processor.cpp visual.cpp ^
/Fe:explodedvolumes-msvc.exe ^
/link /LIBPATH:%GLFW_LIB% glfw3.lib opengl32.lib gdi32.lib ole32.lib comctl32.lib oleaut32.lib uuid.lib user32.lib shell32.lib

If the GLFW build is dynamic, copy the matching GLFW .dll next to explodedvolumes-msvc.exe.


8. macOS Build

The current build entry point is the root Makefile.

Install the Homebrew dependency set:

brew install glfw glm eigen boost pcl vtk libomp nlohmann-json

Prepare the local dependency layout expected by the Makefile:

mkdir -p dependencies/include dependencies/library
ln -sf "$(brew --prefix glfw)/lib/libglfw.3.dylib" dependencies/library/libglfw.3.4.dylib
ln -sfn "$(brew --prefix vtk)" dependencies/VTK
ln -sfn "$(brew --prefix glm)/include/glm" dependencies/include/glm
ln -sfn "$(brew --prefix eigen)/include/eigen3/Eigen" dependencies/include/Eigen
ln -sfn "$(brew --prefix boost)/include/boost" dependencies/include/boost

The project-local headers listed in Section 6.2 must also be available under dependencies/include.

Build:

make

If your PCL version differs from the Makefile default:

make PCL_VERSION=1.15.1

For Intel macOS or a custom Homebrew prefix:

make BREW_PREFIX=/usr/local

Clean build outputs:

make clean

9. Running the Application

macOS:

make run

Windows MinGW:

.\explodedvolumes-mingw.exe

Windows MSVC:

explodedvolumes-msvc.exe

The application opens a file dialog. Select a .nii volume file for which you have permission to use and, if applicable, redistribute. Public releases should not include private or identifiable medical data.


10. Interaction Guide

ActionControl
Rotate cameraLeft mouse drag
ZoomMouse wheel
Adjust camera distance+ / -
Close applicationEsc
Change iso-levelImGui Marching Cubes control panel
Toggle exploded viewImGui Explosion View control panel
Adjust explosion distanceImGui Explosion View control panel
Show or hide explosion axisImGui Explosion Axis Settings panel

11. VS Code Configuration Notes

For macOS, create a VS Code build task named Build OpenGL that runs:

make

A launch configuration can use:

{
"program": "${workspaceFolder}/app",
"cwd": "${workspaceFolder}",
"preLaunchTask": "Build OpenGL"
}

Use ${workspaceFolder} rather than ${fileDirname}. The latter changes depending on which file is currently focused in the editor and can lead to inconsistent build or runtime paths.


12. Known Limitations

  • The repository does not yet provide a cross-platform CMake configuration.
  • The source-only distribution requires users to reconstruct third-party headers and platform-specific libraries locally.
  • The current Makefile is macOS-oriented and version-sensitive when PCL or VTK paths change.
  • The current file dialog focuses on .nii input. Additional work may be needed for convenient .nii.gz handling.
  • imgui.ini may be generated or updated by Dear ImGui to store UI layout. This is normal and does not indicate that input volume files have been modified.

13. Third-Party Components and References

Before compiling, check the availability of all third-party components used in the local build:

The visualization concept follows the general idea of exploded-view representations of complex surfaces, especially:

Olga Karpenko, Wilmot Li, Niloy Mitra, and Maneesh Agrawala. Exploded View Diagrams of Mathematical Surfaces.IEEE Transactions on Visualization and Computer Graphics, 16(6), 2010, 1311–1318. DOI: 10.1109/TVCG.2010.151.

The authors gratefully acknowledge M. Chamberland and H. van de Wetering for their guidance and valuable feedback during the development of this project.

About

Interactive C++/OpenGL tool for exploded-view visualization of NIfTI volume data using Marching Cubes, cutting planes, and edge-enhanced rendering.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages