SciSlice is a program that creates custom tool paths for Fused Filament Fabrication 3D printers (also known as FDM™). The motivation for creating this program was to allow the user to independently adjust as many printing parameters as possible for the purpose of researching and characterizing each parameter's effect on a part's properties. These printing parameters can be changed between layers and even within sub-regions of a layer. The program cannot create support structure.
SciSlice can tool path both STL files and pre-defined shapes. Executing RUN_ME.py with Python 3+ will display a GUI through which you can enter all of the parameters for printing.
SciSlice is best at using its predefined outlines and varying many printing parameters. It tool paths these part in a reasonable amount of time and, through caching, can make multiple parts per print with little additional computation. If you want to print five tensile specimens in one print, possibly all the same, possibly all different, this is the program for you. SciSlice does this quickly with an easy method for adjusting parameters and saving those parameters for later use and reference.
SciSlice is reasonably good at slicing simple STL files, especially if you want to treat the STL as an extrusion and just extract a single "loop" from the STL and use that as the outline for your part. With a little extra effort creating a separate parameters JSON file it will also do multiple STL files at once, each with different layer parameters.
If you want to slice a whole STL, you will find SciSlice to be a little slow. It also has difficulty handling more complex STLs, especially with thin features. Its weakness in this area is mostly from using Shapely to create offsets (shells). I would be interested in learning of other libraries which could handle offsets in a faster and more robust fashon. SciSlice cannot create support structure.
If you want to create your own predefined outlines please look at the doneshapes.py module for examples. linegroup.py contains several helper methods to make creating outlines relatively easy with only a little Python programming experience.
If you have no idea how to get started using SciSlice hopefully these instructions will help. If you kind of know what you are doing then use this as an outline to really mess it all up.
Note: I would really like to get SciSlice onto Anaconda so it can be installed, with all its dependencies, simply using:
conda install -c vanhulleone SciSlice
However, after many attempts I can't seem to figure out how to get the directory structure correct. If anyone knows how to do this I would appreciate assistance. It will make installation and updating much easier for the users. Thanks.
You will need Python 3.5+ and all of the required dependencies to run SciSlice. Downloading and installing Anaconda will get you Python and most of the needed libraries (dependencies). Anaconda can be found on the Continuum website. Choose the Python 3.5 version installer appropriate for your operating system. This is a pretty large installation so it will take a bit.
matplotlib
NumPy
trimesh
Shapely
Pygame
Rtree
Even though Anaconda comes with many libraries already installed I managed to design SciSlice to need several libraries which are not included. Sorry about that. Luckily Anaconda comes with a program called Conda which makes this processes fairly easy. First you need to get to the Anaconda prompt. On my Windows machine I went to the Start Menu -> All Programs -> Anaconda3 -> Anaconda Prompt. Selecting Anaconda Prompt will pop up a black command line
window. From this window you will be able to install the additional libraries: Pygame, Shapely, Rtree, and trimesh.
In the command prompt type:
conda install -c cogsci pygame
This will install Pygame from the CogSci profile on anaconda.org.
Next install Shapely with the same process but from the IOOS channel.
conda install -c IOOS shapely
Third, install Rtree also from the IOOS channel.
conda install -c IOOS rtree
Finally we need trimesh. As of this writing there was not a Conda version of trimesh so we will use pip.
pip install trimesh
All in a row you will have typed into the command prompt (hitting enter after each line and waiting for each install):
conda install -c cogsci pygame
conda install -c ioos shapely
conda install -c ioos rtree
pip install trimesh
Now you have the additional libraries needed to run SciSlice.
The most up-to-date version of SciSlice is located on GitHub in its repository. Once there select the clone/download dropdown (a green button) and download the .zip file. Extract the file into whichever folder you like and you have it installed.
Since SciSlice is not fully stable yet it may be worth while to download Git Desktop so you can clone the repository to more easily and quickly download bug fixes.
To run the program either cd into the folder in which you unzipped the program and then type in the
Conda prompt python RUN_ME.py
or open Spyder, which came with the Anaconda installation, open the RUN_ME.py
and run the program from Spyder.
After downloading the zip file and extracting it in an appropriate location and installing
the dependencies simply run RUN_ME.py in your preferred Python IDE or from the command line. A GUI
interface will be displayed which allows for either entering new parameters or for uploading previously
defined parameter files (JSON files). The user adjustable printing parameters are broken into
five sections:
Parameters types are indicated after the name of the parameter. Types [enclosed in square brackets] can be lists, comma or space separated. For part parameters the longest list determines how many parts are printed all other parameters are repeated, one for each part, until the longest list is exhausted. For layer parameters the parameters are cycled layer by layer until the specified number of layers have been printed.
The sorting of parameters displayed below into the categories: part, layer, print, printer; are the current division as downloaded. Most parameters can be switched into any other group by altering the parameters list in RUN_ME.py. See the advanced user section for more details.
To know which parameters are in which group simply select the group from the right hand side buttons.
Part parameters are parameters that are constant throughout a single part but can
change between parts (except for outline). The longest list of part parameters
determines how many parts will be created. The part parameters are:
- Outline
- Pattern
- Extrusion factor
- Print Speed (mm/min*)
- Shift X
- Shift Y
- Shift Z
- Number of Layers
- Design Type (not implemented)
- Brims
- Horizontal Expansion
- randomStartLoc
The outline of the part to be made. The drop down menu is populated by the properly decorated functions in the doneshapes.py module. See doneshapes for more information on the outline dropdown options.
This is the infill pattern which will be used to fill your part. If you choose noInfill
remember
to select at least one shell.
Extrusion factor is used to calculate the extrusion rate for each layer.
extrusion_rate = extrusionFactor*layer_height*nozzle_diameter/filament_area
Use this to determine how full of a bead area you want or to compensate for under/over filling
cause by inaccurate feeding speeds (which should be fixed in your firmware) or
manufacturing tolerances in your filament.
Print speed is how fast the print head moves while printing.
*The output is actually unit agnostic and will depend on how your firmware interrupts its feed rate commands. It seems most slicing software uses mm/sec at the GUI but the RepRap G-code they create and send to the printer is still defined in mm/min. So instead of asking you for units of mm/sec and then dividing by 60 behind the scenes SciSlice just asks for a number and writes it. Who chose to not ask for feed rate in the native machine units anyway?
To print multiple parts without them attempting to occupy the same space you must use shiftX and shiftY. These shifts are absolute shifts (they are not relative to the previous shift). Since it does not make sense to have two parts printed in the same location at least one of these two parameters should be the longest list of part parameters and determine how many parts are printed.
Adjust parts in the Z direction. Mostly used for pragmatically accounting for an improperly leveled/zeroed bed.
How many layers are printed in the part. The layer parameters are continuously
cycled until this number is reached for the part being printed. They are then reset
for the next part. For Outlines which come from an STL, if you want to print all
of their layers then you must enter the flag -1 into numLayers
. If you enter
any number larger than zero for an STL then that number of layers will be printed.
In the future I would like to implement slices in numLayer
so you could easily print
sub-slices of an STL.
The number of brims to place around the first layer. The brims will be printed
around the exterior side of every loop on the part including internal holes
at a distance of nozzleDiameter
between each brim. The brims are printed in order
farthest from part to closest to part.
Custom infill patterns can be designed for your part. The pattern must be of
type LineGroup. The pattern is extended by copying the design and then
connecting the start of the first line in the copy the end of the last of
the original and saving that as the new original. This process is repeated
until the design is sufficiently longer than the outline. This whole new
line group is then copied and translated in Y by pathWidth
until a full
field is created. Please read the comments in the
InFill
module for more details.
If your prints are coming out incorrectly sized in the XY plane then you can use this value
to adjust them. A positive value will offset the outer outline
by that value making it larger
(and holes smaller). A negative value will decrease the size of the part (and increase hole sizes).
randomStartLocation
allows the layers to be started at pseudo-random locations instead
of always the minimum X and Y locations. If randomStartLocation
is set to 0 then each layer
will always start at the point in the toolpath closest to the point (minX, minY). Any other integer value will
be used as the seed for the random number generation. Since this value is the seed, identical
prints which are tool pathed at different times will still produce the same "random" starting
locations. The point is chosen by finding the LineGroup with the left most point, the minX,
and then choosing a random point from that LineGroup. For single region shapes with at least one
shell this will ensure that the random point is on the outer most shell, although it could start
at the outer most shell of a hole. For shapes without a shell this will pick a random location
from the infill. For multi-region parts this technique will cause the tool path to only start
somewhere on the left most region and nowhere else. Hopefully this will be fixed.
Layer parameters are unique to each layer of a part. Each list of parameters is
cycled until the value in numLayers for the part is met. The lists are then started
over at the start of the next part. The layer parameters are:
- Infill Angle (degrees)
- Path Width (mm)
- Layer Height (mm)
- Infill Shift X (mm)
- Infill Shift Y (mm)
- Number of Shells
- Infill Overlap (mm)
The angle of the infill for the part. Zero (0) degrees is in the positive X direction with the positive angles moving around counter clockwise.
The distance between the centerlines of two adjacent passes. This is an orthogonal distance, not a normal distance. If you had a zig-zag infill pattern v^v^v^v when that pattern is turned into a field it would only be shifted in the Y direction by pathwidth. If the angle were 90 degrees that would mean a path width of 1.0mm would create a normal distance of 0.707mm which will then effect your solidity ratio.
Sometimes when the infill is created it is not centered properly in the shape
or you may want to do testing that creates beads which sit in the valley of the lower
bead instead of directly on top of it
O O O O O
O O O O O
O O O O O
vs
O O O O O
. O O O O
O O O O O
Infill shift X and Y are hacks used so you can adjust the infill to fine tune
your pattern.
The number of shells you want around the part. Shells are created by a
normal offset pathWidth
away from the previous shell/outline. Keep in mind that
to tool path the infill properly a trim shell is created by the program. For example
if three shells are prescribed a fourth trim shell is created inside the third
shell to properly trim the infill.
How much the infill should overlap with the inner most shell. To create the infill a trimshape
must first be created offset inside the inner most shell by a distance of nozzleDiameter
,
or in the case of no shells offset from the defined outline. This shape is then used to trim the
infill throwing away any new lines which do not lie inside the trimshape
. If the infill is not bonding well
to the shell infillOverlap
can be increased making a trimshape
which is closer to the inner most shell allowing
the infill and shell to squish together more completely. If there is overfilling with the shell this value can be
decreased. Due to computational uncertainties between lines in the trimShape
and lines in the infill which are
co-linear overlapping it is best to not set this value directly at zero. A value of 0.0002 has
been found to produce the best results; including lines which we want to be included without
over filling the shell-infill boundary.
- start_Gcode_FileName - Name of the file which contains all of the starting Gcode commands
- end_Gcode_FileName - File with end Gcode commands The program currently looks into the Start_End_Gcode folder when searching for these files.
- bed_temp (C) - flag =
#BED_TEMP
- extruder_temp (C) - flag =
#EXTRUDER_TEMP
The start G-code file must be properly formatted in order to allow the bed and extruder temperatures
to be set in the output machine code file. The constants.py module defines the two flags which must
be used in the start file. They are #BED_TEMP
and #EXTRUDER_TEMP
placing these flags after
the appropriate machine code will allow SciSlice to write the values into the output machine code file.
For standard RepRap G-code the temperature section will look as follows:
M109 #EXTRUDER_TEMP ;
M190 #BED_TEMP ;
These are parameters related to the printer itself.
- nozzleDiameter (mm) - Nozzle outlet diameter
- filamentDiameter (mm)- The diameter of the incoming filament.
- RAPID (mm/min) - How fast the printer should move when not printing
- The RepRap wiki (9 July 2016) says "The RepRap firmware spec treats G0 and G1 as the same command, since it's just as efficient as not doing so." I strongly disagree with this statement. A G01 is a feed command and as such needs an F value to know how fast to move. A G00 command should be a rapid command where the printer knows its max velocity and therefore does not require an F feed rate. Because of the RepRap design choice G00 needs a feed rate command requiring the programmer/operator to know each individual machine's max speed and creates larger programs by needing the additional text on every G00 line. How is that just as efficient?
- retractDistance (mm) - how far to retract the filament to prevent nozzle drool when traversing around the part.
- retractMinTravel - if the move to the next printing position is less than
this value the head is not lifted up, no filament retract is performed, and it is moved
at the print velocity. If the move to the next printing position is larger than
this value the head is lifted by
ZHopHeight
and the material is retracted byretractDistance
- ZHopeHeight (mm) - Distance up the head is moved when traversing the part.
- APPROACH_FR (mm/min) - Speed the printer should move when approaching the part. A slightly slower speed helps prevent hard crashes and allows the filament more time to move forward in the nozzle in preparation for printing.
- comment - Every system seems to require a different comment character. Enter the required comment character here.
All of the parameters are saved in a JSON file. When the program is first loaded the parameters from
the DEFAULT.json file in the JSON sub-directory are loaded into the GUI. After you have changed the parameters
to your desired values you can save them by hitting the Save
button at the top of the gui. A file navigation
window should pop up. If you have saved parameters and wish to use them again select the Upload
button
and chose your desired parameter file. If you always use a similar parameter profile you can save over
the DEFAULT.json file and your parameters will be loaded at startup. However, if you are using a git client
to pull new changes you will have to make sure your default parameters are not changed during the next pull
and merge.
The Create 3D Model
button calculates the tool paths for your current parameters and generates
a window showing you the printed tool path. Instructions are included on the window for how to navigate
through the window and how to change which layers you are viewing. At this time the line thickness does not
represent the actual thickness of the printed tool path. Also, there is a known issue when rotating the part
more than 180 degrees. You don't actually see the bottom of the part but instead it is flipped and you see the
top again. You are more then welcome to provide a patch which fixes either of the problems (or anything else
for that matter)
When the Generate Code
button is selected a file chooser pop-up window is created. After the output file
has been chosen the tool path is first calculated if needed* and then is converted into the desired machine
language. Currently the default choices are Gcode or RobotCode. Gcode is RepRap G-code in the Marlin flavor and specifically set up for a Taz5 printer. RobotCode is in ABB's RAPID language and is currently being used
for UW-Madison PEC's IRB120 robot for full 5-axis 3D printing research.
* "if needed": When either Create 3D model
or Generate Code
are selected the program creates a temporary
machine code file. If Generate Code
is selected again and the parameters have not changed, this temporary
file is copied to the desired location and name instead of re-calculating the tool path and machine code.
This saves a lot of time on larger parts. However, the current parameter checking only checks the parameters
from the gui, not any additional parameters from a multi-region file. To curcumvent this problem you can either comment out the section of code responsible for the parameter checking. This code is in RUN_ME.py
module inside the convert() method and is marked which a comment. (currently around line 720) or make a small
change to one parameter in the GUI such as a sub-micro change to infillOverlap
. I hope to enable
adding the multi-region parameters to the main parameter JSON file preventing this problem.
The doneshapes.py module contains all of the functions which generate the drop-down lists for
outline and pattern. Outlines are marked with an @outline
decorator and patterns are marked with
an @infill
decorator. Type hints are used in the functions to help the user know what information
should be entered into the text field. File name parameters named fname
will have a file chooser
pop-up button created.
- fromSTL
- fromSTL_oneLevel
- multiRegion
- multiRegion_oneLevel
- regularDogBone
- wideDogBone
- circle
- rectangle
- polygon
Take in and tool path entire .STL files. They enable choosing a file (the STL for fromSTL and the
parameter file for multiRegion).
The change_units_from
parameter allows you to say in what
units your STL(s) are in so they can be converted to millimeters. This conversion is done by Trimesh.
The most common units are m, mm, and in. With a wide range of units allowed. For both of these options numLayers
is usually set to the flag -1.
Since SciSlice cannot create support structure the STL files are often extrusions.
To make slicing faster and more repeatable both fromSTL and multiRegion have a _oneLevel
counterpart that allows
the user to specify a sliceHeight
. A single outline will be created from the slice at that height which will be used to create the entire part. You are required to set numLayers
if this option is used.
An ASTM D-638 type 1 tensile specimen.
Same general shape as the ASTM D638 but allows you to specify a gage width, either wider or more narrow.
Both multiRegion options allow the user to use multiple STL files in a single print and provide
different parameters for each region. This is especially useful when a user wants to control the layer
orientation in specific regions to ensure beads align with tensile forces.
To use multiRegion you must create an additional JSON file and place it in the same directory
as the STL files it references. The file must contain a list of
dictionaries, each dictionary containing the file name of the STL which should be used and the
parameters for that file. Any parameter from the GUI can be specified in the JSON without
receiving an error however not all of the parameters will actually work for each region. Currently
only the parameters used by the make_region()
function in figura.py plus layerHeight
(used by
the Region
class in doneshapes.py) will actually affect each region.
An example JSON is given below:
[{"fileName": "C-Bracket_0_90.stl",
"numShells": [0,1],
"pathWidth": [0.5, 1.0],
"infillAngleDegrees": [0, 90.0],
"infillShiftX": [0.0],
"infillShiftY": [0.0],
"layerHeight": [0.1,0.2]},
{"fileName": "C-Bracket_minus45.stl",
"numShells": [0],
"pathWidth": [0.5],
"infillAngleDegrees": [-45,0],
"infillShiftX": [0.0],
"infillShiftY": [0.0],
"infillOverlap": [0.0002]},
{"fileName": "C-Bracket_plus45.STL",
"numShells": [0],
"infillAngleDegrees": [45],
"infillShiftX": [2,7],
"infillShiftY": [0.0],
"infillOverlap": [0.0002]}]
The JSON format is a little particular so remember to not have any trailing commas. The parameter names can be in any order and each region does not need to specify the same parameters. Any parameter not listed will default to the parameter in the GUI. After each region has been made they will all be toolpathed together as a layer. To help prevent typos I like to save a parameters JSON and then copy the needed dictionary entries into my multiRegion file.
SciSlice enables a user to decide which parameters are for parts and which are for layers. If multiple
parts are being printed and you want to change the layer height between parts but have it be constant within
a part, you would have to change layerHeight
into the PART
group.
Inside the RUN_ME.py module in the Page_Variables class there is a list named parameters
.
parameters
is a list of namedtuples, one for almost every parameter in the GUI.
(The two dropdowns are in the dropdowns
list, the radio buttons are handled elsewhere.)
The first vlue in the namedtuple is the parameter name, next is what type of variable
it accepts, declared from the constants provided above. All Layer and Part parameters must be lists so they
can be properly handles by the zipVariables_gen()
generator in parameters.py. The final field is a
tuple containing the variable groups constants. If the tuple contains PART
then the variable will
be used as a part parameter. If it contains LAYER
then it iwll be a layer parameter. If both LAYER
and PART
appear in the tuple, no error is thrown, the variable will appear under both buttons
but LAYER
will win for the actual tool path creation. Please note that in Python parentheses
are used for tuples but if only one item is in the parentheses a tuple will not be created. It
instead must have a trailing comma. (42)
means simply fourty two. (42,)
is a tuple of length one
containing the number fourty two. Through this technique you can also change which parameters are
in the COMMON
group.
If you have Python and the appropriate dependencies installed you can use
Notepad++ to run the RUN_ME.py file.
To do this in the menu bar select Run-> Run (F5) type the following:
<your python path>\python.exe -i "$(FULL_CURRENT_PATH)"
<your python path>
is the actual path to python. For me Python was in my
Anaconda3 folder. FULL_CURRENT_PATH
is a variable in Notepad++ so type
that exactly. On my computer the full command was:
C:\Anaconda3\python.exe -i "$(FULL_CURRENT_PATH)"
Now select save. For a command I chose ctrl-r and hit ok. Now you can hit your
hot keys (ctrl-r) and Notepad++ will call Python and run your program.