Medical imaging desktop application · 2026
DICOM to 3D-printable STL, in a native desktop app
A surgeon needed CT scans turned into physical 3D-printed models for pre-operative planning. Existing tools are heavy, slow, and built for radiologists rather than for the operating theatre. I built a native application that goes from a folder of DICOM files to a printable STL in one sitting.
- My role
- Sole engineer on the Windows shell and the shared C++ core
- Stack
- C++
- DCMTK
- Marching cubes
- SwiftUI
- SceneKit
- Qt 6
- OpenGL
- CMake
The problem
Clinical 3D reconstruction software is large, expensive, and tuned for diagnostic reading rather than for producing a physical model. A surgeon who wants a printed bone to rehearse against has to move data through several tools and wait.
The brief was a single application that ingests a raw DICOM series, lets a clinician isolate the anatomy they care about, and writes a watertight mesh ready for a printer. It had to run natively on both macOS and Windows, and it had to be fast enough to use interactively rather than as a batch job.
How it fits together
Architecture
DICOM series on disk
|
v
+---------------------------+
| ingestion (DCMTK) | parse headers, order slices,
| | rescale to Hounsfield units
+---------------------------+
|
v
+---------------------------+
| contiguous voxel buffer | one linear allocation
+---------------------------+
|
+----+--------------------+-------------------+
| | |
v v v
tri-axis slicing segmentation markups /
axial|coronal|sag threshold, paint, measurement
(texture pipeline) seed grow (threaded)
|
v
+--------------------+
| marching cubes |
+--------------------+
|
+--------+--------+
| |
v v
3D preview binary STL export
(SceneKit / GL) -> 3D printerWhat I built
One C++ core, two native shells
All the real work happens in a platform-agnostic C++ layer: DICOM parsing on a trimmed DCMTK build, a contiguous 3D voxel buffer, segmentation, and mesh extraction. macOS drives it from SwiftUI and SceneKit; Windows drives it from Qt 6 and OpenGL widgets, through a small C bridge. Neither shell reimplements any logic, so the two platforms cannot drift apart in behaviour.
Volume data laid out for speed
The volume lives in one tightly packed linear buffer rather than a slice-of-pointers structure. Segmentation passes are multi-threaded across CPU cores, which is what makes thresholding, interactive paint, and seed-growing feel immediate instead of batch. Window and level adjustment is a texture operation, so contrast changes are instant.
Marching cubes to a printable mesh
Once a region is isolated, marching cubes extracts an iso-surface which renders in a hardware-accelerated 3D view for inspection before anything is written. Export emits binary STL that a slicer accepts directly. Multi-segment exports fuse into a single file so a model with several structures prints as one object.
The product
Screenshots are from the real application. Client identifiers and any personal data have been redacted.







Where it landed
- A clinician goes from a DICOM folder to a printable STL without leaving the application.
- Feature parity across macOS and Windows from one shared C++ core.
- Eleven pull requests merged into the project, including the entire Windows Qt 6 shell.
- Large-volume handling hardened: fixed the hangs and crashes that big series triggered on Windows.
