PrusaSlicer: Source Code Anatomy [Part 1, History and Overview]

Aliaksei Petsiuk
6 min readFeb 7, 2023

--

This article is part of a cycle devoted to the PrusaSlicer source code structure analysis. These works are under development and will continue to be updated.

PrusaSlicer is the heir of Slic3r developed by Alessandro Ranellucci.

PrusaSlicer (2016) and its ancestors: SLic3r (2011) and SkeinForge (2008)

The core software library is libslic3r, written in C++ for fast geometric processing of complex 3D models. A brief history of one and a half years of development reveals more details:

Slic3r was born in late 2011 as an attempt to modernize the 3D printing toolchain. It simplified slicing by reducing configuration to just three options (nozzle diameter, filament diameter, temperature) and it also made slicing a lot faster. The goal was to have clean, structured code for prototyping new features and getting a powerful slicing engine.

Slic3r had introduced a good number of new features:

  • Automatic detection of bridges — detects each bridge independently and only extends it by the distance strictly needed for anchoring
  • Micro layering — different layer heights may be used for infill, perimeters as well as to various regions of the model
  • Brim — addition to the print used to hold the edges of a printing part, which can prevent warping and help with bed adhesion
  • Cooling logic — controls both cooling fan and print speed in a single integrated logic
  • Sequential printing — have the printer print one object completely at a time
  • Avoiding crossing perimeters — bends travel moves so that they don’t cross objects when not strictly needed — and when it’s needed, it tries to cross a vertex rather than a flat surface
  • Different extrusion widths — for each print part (perimeters, infill, support, first layer, etc.)
  • Extra perimeters — automatically increases the number of perimeters in those layers where slopes would expose some of the infill producing sub-optimal results
  • Multiple extruders — native support for multi-material files. It was one of the first applications able to read and write AMF files. It also allowed using a secondary extruder for support material, opening the way to soluble support
  • Only infill where needed — detect what upper parts of the object require infill for supporting the ceiling
  • Different number of top and bottom layers — allows making vases from solid objects
  • Acceleration control — allows fine-tuning your firmware by assigning different acceleration limits to each part of the print (perimeters, infill, bridges)
  • Automatic logic for generating internal bridges over sparse infill — improves the quality of top surfaces

PrusaSlicer, in turn, created:

  • Multiple G-code flavors supported (RepRap, Makerbot, Mach3, Machinekit, etc.)
  • Ability to plate multiple objects having distinct print settings
  • STL auto-repair (tolerance for broken models)
  • Combines infill every ’n’ perimeters layer to speed up printing
  • Spiral vase mode for continuous printing
  • Fine-grained configuration of speed, acceleration, and extrusion width
  • Several infill patterns including honeycombs, spirals, Hilbert curves
  • Standby temperature and automatic wiping for multi-extruder printing
  • Support for post-processing scripts
  • Cooling logic controlling fan speed and dynamic print speed

The Slic3r library is widely distributed: SuperSlicer represents another fork based on it, and OctoPrint has a plugin that allows connecting Slic3r for slicing. It may also be worth noting a single-file embedded C-based Slic3r remake attempt, developed by dronus.

Both Slic3r and PrusaSlicer programs allow running the whole process in the backend, using a command line interface. This allows other developers to focus on their own GUIs by easily integrating main slicing features under the hood.

Below is an example of using the slicer via the command line. Here we are passing the saved project (models.3mf) along with its slicing configurations baked in the 3D Manufacturing Format (3MF) and receiving the output printer instructions as a models.gcode:

Usage: prusa-slicer [ ACTIONS ] [ TRANSFORM ] [ OPTIONS ] [ FILES ]
Actions: --export-gcode
Transform: --cut 3
Options: --loglevel 5 --output models.gcode
Files: models.gcode, models.3mf
PrusaSlicer running in the backend through the command line interface

PrusaSlicer allows to store complex compound models along with slicing configurations, materials, and colors in 3MF format. This is an open-source XML-based data-storing architecture developed by 3MF Consortium. To have a look in 3MF file contents — just rename .3mf to .zip and extract the data to another folder. You will then get a number of files with metadata, mesh structure, configuration files, etc.

Dependencies

The main software dependencies are listed below:

  • Boost — a set of C++ libraries that provides support for tasks and structures such as linear algebra, pseudorandom number generation, multithreading, image processing, regular expressions, and unit testing. It contains 164 individual libraries. It provides free peer-reviewed portable C++ source libraries.
  • Eigen — a high-level C++ library of template headers for linear algebra, matrix and vector operations, geometrical transformations, numerical solvers, and related algorithms. Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.
  • Clipper — The Clipper2 library performs intersection, union, difference, and XOR boolean operations on both simple and complex polygons. It also performs polygon offsetting. This is a major update of my original Clipper library that was written over 10 years ago. That library I’m now calling Clipper1 and while it still works very well, Clipper2 is better in just about every way.
  • LibIGL — a simple header-only C++ geometry processing library. We have a wide functionality including the construction of sparse discrete differential geometry operators and finite-elements matrices such as the cotangent Laplacian and diagonalized mass matrix, simple facet, and edge-based topology data structures, mesh-viewing utilities for OpenGL and GLSL, and many core functions for matrix manipulation.
  • OpenGL — OpenGL is a cross-language, cross-platform application programming interface for rendering 2D and 3D vector graphics. The API is typically used to interact with a graphics processing unit, to achieve hardware-accelerated rendering.
  • CGAL — CGAL is a software project that provides easy access to efficient and reliable geometric algorithms in the form of a C++ library. CGAL is used in various areas needing geometric computation, such as geographic information systems, computer-aided design, molecular biology, medical imaging, computer graphics, and robotics.

There are many lines of code in PrusaSlicer, but the whole process can be roughly divided into two parts: 1️⃣ slicing and 2️⃣ gcode generation.

1. Slicing

// Loading 3D models and processing configurations
FullPrintConfig fff_print_config;
Model model = Model::read_from_file(...);

// Creating a printable object data structure
Print fff_print;
PrintBase *print = static_cast<PrintBase *>(&fff_print);

// Applying the configurations and processing the created object
print -> apply(model, fff_print_config);
print -> process();

2. GCode Generation

// Create a gcode object and apply the required configurations
std::unique_ptr<GCode>gcode(new GCode);
gcode->apply_print_config(...);
GCode::GCodeOutputStream file(..., gcode->m_processor);

// Collect the sliced layers for printing
std::vector<GCode::LayerToPrint> layers_to_print =
GCode::collect_layers_to_print(object);
GCode::LayerToPrint &layer = layers_to_print[layer_number];

// And write the corresponding gcode after processing each layer
GCode::LayerResult result;
for (every layer){
result = gcode->process_layer(...);
file.write(result.gcode);
}

--

--

Aliaksei Petsiuk

Researcher at Western University (Canada) focusing on computer vision in additive manufacturing. https://www.linkedin.com/in/apetsiuk/