Introduction: 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.
- 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.
- Adjust the line of code inside the
setup()function to read:
drawData = loadTable("drawDataYourName.csv", "header");
- 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.
- Run the sketch!
- The image is saved in the "layersVisualized" folder.
- 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).
- 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.
- Scale the rainbow-coloured layers image to fit the image of the STL.
- Set the opacity mode of the top layer (rainbow) to "Overlay".
- 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.