Designing voxel models

Designing volumetric propertiea is quite a difficult task in the current software culture. None of the standard CAD programs work with volumetric specifications (in my limited experience).

Gladly there is Autodesk Monolith. You can import an STL, which is converted into a voxel field with densities of 100% inside the STL and 0% outside.

You can then model your properties by painting the voxel colors; you need to uncheck geometry so that you only affect the voxel colors, not the densities.

Set the visualization alpha really low so that you can easily see what’s going on inside the model.

When you’re ready go to the rasterization tab and select to only export the material ratio. You can then export the voxel model to a sequence of images. The image lightness encodes the material ratio and the alpha channel encodes the material density.

This is a really nice tool if you want to draw volumetric material property specifications. It can be used to specify an image sequence to be used in Cura as a density voxel model for 3d printing with FDM.

Voxel models

Cura now supports voxel models, by loading in a sequence of images if the first image ends in a number.

The XY are stretched so that the object fits inside while the XY ratio is maintained.
The Z of the images is independently stretched so that all images cover the whole 3D model.

I’ve used it to create some prints which are based on DICOM files from CT-scans.

Note that the surface model is extracted from the DICOM files in a separate program (3D slicer).
I converted the DICOM files into standard png images using MATLAB.

Then I converted the images such that the highest density equaled the density I had set in Cura and a cropped them to where the surface model reached.

This is the result:

This is a sample MATLAB code:

files = dir('osseux/*.dcm');
for file = files'
path = strcat(file.folder, "/",;
a = dicomread(path);
min_val = 300.0 / 32768.0 + .5;
max_val = 1800 / 32768.0 + .5;
minn = min(min(a));
maxx = max(max(a));
a_mapped = uint16(int32(a) + 32768);
adjusted = imadjust(a_mapped, [min_val max_val], [0.0 1.0], 1.2);
[filepath,name,ext] = fileparts(;
outfile = strcat(file.folder, '/output/', name, ".png");
imwrite(65535 - adjusted, outfile{1});

Don’t blame me if this crappy hacked together code doesn’t work on your machine! 😉

Here’s a sample converted .cdm file: