Variable Slicing for 3D Printing on Autodesk Ember




VariSlice™ is an open workflow for automatically slicing STL files at variable layer heights.

Picking the layer thickness for a 3D print is hard! Do you pick thick layers so your part prints fast, or do you pick thinner layers so you get better quality?? Now you can have the best of both!

VariSlice™ takes an STL file, looks at the slopes of all of the triangles inside and slices it at variable layer thicknesses that optimize for both print speed and print resolution.

The algorithm is free and open: licensed with Creative Commons Attribution 3.0

Step 1: Design 3D Model in Fusion 360

Start by making your 3D model of interest in Fusion 360 or your favorite CAD program. Export as an STL.

Step 2: Import STL Into Meshmixer

We'll use Meshmixer to do two things:

1. Flip the YZ axes (if necessary)

2. Export the STL in ASCII format.

Open Meshmixer, go to Preferences > File > Flip Z-Y axis on Import-Export. Make sure this is disabled. Import the STL. Then enable "Flip Z-Y axis" option. Go to Export and under the drop-down menu be sure to select "STL ASCII Format (*.stl)".

This step is necessary because the VariSlice script uses a Z-up coordinate system. If you get strange results from VariSlice, this is most likely the source of error.

Also, our script that parses the STL needs the file to be in human-readable ASCII format.

Step 3: Import STL Into Print Studio and Slice at 5 Μm Layers

Slice the STL at 5 µm layers and save the tar.gz file. We slice at 5 µm layers because the variable layer thicknesses will range between 100 and 10 µm in steps of 5 µm.

Step 4: Unzip File and Locate Contents in "/slices" Directory.

Unzip the printer file, and put the folder containing slice_n.png’s into folder called “slices” in the main sketch directory (the printsettings file can stay with PNG’s). Raname to something like “nameSlice”.

Step 5: Open the "variSlice.pde" File

There are several lines of code (at the very top) that you will have to adjust.

  • stlPath: This string is the location of the STL relative to the main sketch directory. Should look something like String stlPath = “STLs/nameOfFile.stl”;
  • exportNumber: This is number/string for exporting a CSV file that is useful for visualizing the layer thicknesses. Later on in this Instructable I’ll show how to use this file. This file is not necessary for printing.
  • slicesPath: This is the location of the slices that you moved in step 5. Should look like String slicesPath = “slices/nameSlice”;
  • savePath: This is where the layersettings file will be saved. Also, the selected slice_n.png’s will go here as well.

Step 6: Run the VariSlice.pde Sketch.

How the sketch works:

  • parseTheBunny() — loads the ASCII STL as an array of Strings. Each line is an element in the array. It identifies triangles (or "facets") in the STLs and saves the XYZ coordinates of each triangle's vertices in a Triangle object.
  • calcSlopeHeight() — a simple calculation that iterates through an array of every Triangle object and finds the minimum and maximum slope of the entire Triangle array. The slope is equal to the angle of a Triangle's normal vector and the Z axis (either the positive or negative direction, whichever is the smaller angle). The slope should always be less than 90°. This function is useful for debugging but not necessary for the overall program.
  • buildLayers() — This is the main algorithm that determines the layer thicknesses. It selects the appropriate layer thickness one layer at a time, starting at the bottom. We start at the bottom (z=0) of the STL, and start with the thickest layer thickness we are considering (e.g. 100 µm or 0.100 mm). The function finds every triangle in the range of z = 0 to z = 0.100 mm. It then finds the slope of all of these triangles and looks at only the lowest slope (the most horizontal). It asks itself, given a certain maximum stepover (like 0.05 mm, which is the pixel size on the Ember projector) is the current layer thickness good enough? If it is good enough, it records this at the thickness for the first layer and moves the z-value up to 0.100 and starts the process again. If 100 µm is too thick of a layer, it says, how about 95 µm? If yes, build it, if not, how about 90 µm? This goes until a layer thickess is good enough, or if we're using the thinnest layer thickness we will consider.
  • createTable() — This function saves a CSV file with info that is useful for debugging. It is also useful for visualizing the layers using the drawLayersGeneral.pde Processing sketch. The CSV file it creates is not necessary for printing on Ember.
  • createLayerSettings() — This function saves a CSV file called "layersettings.csv". The Ember printer needs this this file to print.
  • selectSlices() — Remember when we sliced the STL with 5 µm layers? This function selects certain slices and saves them to a folder with the layersettings.csv file. The work done in buildLayers() is what determines what slices are selected.

When you run the variSlice.pde sketch, it creates a directory called "perLayerWithSlices." Inside will be folders containing the layersettings.csv file (the spreadsheet that tells the Ember printer how to print each layer) and the series of PNGs which represent the geometry of each layer.

Step 7: Copy the Printsettings File From the “nameSlice” Folder and Paste It Into the Folder Inside the “perLayerWithSlices” Directory.

This is the same folder that contains the “perlayersettings.csv” file as well as a stack of PNG files.

Step 8: Compress the Contents of This Folder As a .zip File

Open the folder, select all the items, then compress them. Do not compress the folder that contains these files -- this will not work.

Step 9: Send This .zip File to Your Ember and Print Away!!!!


Step 10: Visualizing VariSlice With the DrawLayersGeneral.pde Sketch

The drawLayersGeneral.pde sketch takes the drawData.csv file generated by the variSlice.pde sketch and creates a graphic that represents the layer thicknesses of your geometry.

  1. Copy the drawDataYourName.csv file generated by variSlice.pde into the data folder of the drawLayersGeneral.pde sketch. The drawDataYourName.csv file is located in the "output" folder in the variSlice main directory.
  2. Adjust the line of code inside the setup() function to read: drawData = loadTable("drawDataYourName.csv", "header");
  3. Adjust the size() function so that the height (second value) matches the height of your STL. I used a scale factor such that 1 pixel = 10 µm. So if your STL is 25 mm tall, the height of the image should be 2500 pixels.
  4. Run the sketch!
  5. The image is saved in the "layersVisualized" folder.
  6. Open your STL in some CAD or 3D visualizing software (I used Fusion 360), and take a screenshot of your STL against a white background. You should be using an orthogonal projection from the front or side (not top or bottom).
  7. Open up this screenshot in a image editing software like Photoshop or GIMP. On a separate layer, paste the image generated by the drawLayersGeneral.pde sketch.
  8. Scale the rainbow-coloured layers image to fit the image of the STL.
  9. Set the opacity mode of the top layer (rainbow) to "Overlay".
  10. Enjoy your preview of your VariSliced STL!

Fun fact: The drawLayersGeneral.pde sketch does not have any military experience. It is however, a broader implementation of a previously written, less flexible Processing sketch.

Step 11: Troubleshooting

¿¿¿Having problems with VariSlice???

Here are a few tips that may help.

  • The algorithm assumes that the bottom of the STL is at Z=0. Any part of your STL that's located below Z=0 will effectively be cut off.
  • If the bottom of the STL is greater than the smallest layer thickness (for my values that's 10 µm), then the algorithm will assume it's done before it's even started.
  • Different CAD programs have different conventions for which axis is "up". Typically either the positive Y or Z axis is considered "up". The VariSlice algorithm assume a +Z-up orientation. Meshmixer can be used to flip the Y and Z axes if necessary.
  • To identify if the "up" axis is the issue, check the printout of the VariSlice sketch. Looks for the "max STL height" and "min STL height". The min STL height should be a value very close to zero. The max STL height should match what you expect -- if it matches another dimension of your STL, it is likely an axis orientation problem.
Design Now: 3D Design Contest 2016

Participated in the
Design Now: 3D Design Contest 2016

2 People Made This Project!


  • Sensors Contest

    Sensors Contest
  • Pets Challenge

    Pets Challenge
  • Beauty Tips Contest

    Beauty Tips Contest

17 Discussions


8 months ago

I read some information about "Adaptive Slicing",

I think the method on this website is very similar to "stepwise uniform refinement".
consider the "cusp height" of the triangle,and use cusps as a reference for layer thickness.
How does the program on this website determine the layer thickness?
If it is similar to what I said above, how should the variables be adjusted?


11 months ago

Not sure if this thread is being monitored anymore... but I was attempting to use this again after a hiatus, but the program runs to completion - too fast - and doesn't output anything. Looking for some offline help.

1 reply

Reply 11 months ago

I figured it out: The Z axis was loading incorrectly.

I had to import the STL into meshmixer, and re-save it. Even though it came into meshmixer correctly orientated as an export from SolidWorks.


1 year ago

I think for the DrawLayerGeneral it has some bugs, when i run the code, it always error, it says there is no thickness and height in the table. anyone know how to solve this?


Question 1 year ago on Introduction

Hello, I downloded the file and extracted it. How can I run it?


1 year ago

I have two Questions:

1) does the ember recognize .zip or it must be .tar.gzip.

2) does the ember automatically look in the .csv file automatically or there is a setting that should be chose in order for the printer to look into each layer settings.


1 year ago

Hey guys. I took the algorithm and made a numpy version of it for a Cura plugin that I'm working on. The repo can be found at I'm still working on making the CuraEngine use the found layer heights as input, but the algorithm and plugin work nicely already. I had to rewrite some logic to better fit numpy (array mutations are preferred over manual iterations), it parses about 30k triangles every 5 seconds on a Lenovo P51. Always open to suggestions and pull requests to make it better!

1 reply

Reply 1 year ago

More details in this issue thread: In short: a first version is now working in Cura. Will add a message here when I know more about potential release dates.

Steve Crayonsmartinbogo

Reply 2 years ago

Thanks for the heads up! VariSlice is open source so they are totally allowed to copy/modify the code. Also it's entirely possible (even likely) that their work was developed independently. A variable slice alogorithm has been developed on Slic3r for years.


2 years ago

love you guys at Autodesk. Innovative ideas with humor. Want to work for you guys one day.


2 years ago

Would love to see this for FDM printers. it is a game changer!


2 years ago

Can't wait to see this as a polished and included option in PrintStudio. I found that you can control the layer thickness by changing the listed variableLayers values. I dropped the min value to 5um and it worked!


2 years ago

I like this idea. Bummer it can't work for FDM (at the moment). I suppose someone could create a script that would modify the output to work with FDM printers based on common characteristics like minimum and maximum layer heights. I'd try but I am not a programmer. A script would also have to account for speed and temps too, so it might not be as trivial as I first thought. Just think of all the material we could save if this method were more universal!


2 years ago

cool stuff, hope this could be adapted for FDM - as I read it, it is only for SLA (DLP) processes at the moment...?


2 years ago

Verry good thing. I don't understand everything because I don't speak
english. But I am interested to do that for my Ultimaker printer. If
someone know whow can I do and explain it to me I will thanks him.


2 years ago

neat trick!