Author Archives: Rene K. Mueller

3D Printing: YAGV: Yet Another G-code Viewer Fork

One of the oldest standalone G-code viewers yagv (Yet Another G-code Viewer) I forked and added following features:

  • ported to Python3
  • new color scheme (white background)
  • parsing G-code comments, determining wall, infill, support structure and render with different colors
  • support for Slic3r, PrusaSlicer, Cura/cura-slicer, Mandoline and Slicer4RTN (non-planar)
  • panning implemented (properly works with zoom and rotation)
    • same mouse button layout as OpenSCAD
  • more test G-code included in tests/

Example of non-planar G-code:


Note: I opened a Pull Request (PR) but not sure if it’s accepted.

See Also

3D Printing: Non-Planar Slicing with Planar Slicer


  • 2021/04/09: spherical slicing redone, slightly better than before
  • 2021/04/03: cylindrical & spherical slices added
  • 2021/03/26: refocusing to non-planar slicing with planar slicing
  • 2021/03/14: starting write-up with basic illustrations


After discovering the 4-axis Rotating Tilted Nozzle (RTN) and its prototype of RotBot as developed by ZHAW and their conic slicing method, it became clear to me a 5-axis 3D printer with variable tilting nozzle is the way to go as it is a superset of 4-axis and 3-axis 3D printing.

With that in mind, I realized there was time to explore non-planar slicing with planar slicers in more details.

Slicing Methods

Let’s provide an overview of various slicing methods:

Horizontal Slices

Vertical slicing creates horizontal slices, the traditional aka planar slicing method, so issues and limitations are well known:

  • simple to slice
  • only challenge is to create support structure for overhangs to ensure all printed layers have layers beneath
  • no collision detection needed, as all already printed layers are beneath

Tilted Slices

Tilted slices are kind of new(er) and became known with belt printers, usually 45° tilted:

Transformation is [ x, y, z – y ]

  • simple to slice
  • belt-printer: no collision detection is needed
  • can print 90° overhangs in one direction only

There are patches for Cura available to slice for belt printer, additional the experimental Slicer4RTN also provides tilted slicing.

Conical Slices

New slicing method as introduced by ZHAW researchers and announced in 2021/01 utilizing planar slicer:

  • requires a center of the conic layers
  • can print 90° overhangs, two distinct modes: inside out (outside cone), or outside in (inside cone) depending on direction to a central slicing cone center
  • requires rotating and tilted nozzle aka Rotating Tilted Nozzle (RTN)
  • angle of conic slicing can be changed from 45° to 20° and models become printable with vertical nozzle with reduced print quality

Transformation is [ x, y, z + sqrt( x2 + y2) ]

I implemented a conic slicer named Slicer4RTN in 2021/03. There are more complex conic transformations possible, e.g. map the x/y angle via atan(y/x) but just adding sqrt(x2 + y2) to z does achieve a conic slice.

Cylindrical Slices

Early tests using planar slicers to slice also cylindrical, like this:

Transformation is [ atan(y/x), z, sqrt(x2 + y2) ]

It can be printed on a fixed vertical rod, with a rotating and tilting nozzle, or horizontal rotating rod (like a lathe) and vertical nozzle then:

I came up with this way by myself based on the study on conic(al) slicing but I was made aware researchers Coupek, Friedrich, Battran, Riedel back in 2018 published a paper on this method already.

(Hemi-)Spherical Slices

Early tests using planar slicers to slice also spherical, like this:

Transformation is [ sqrt(x2 + y2 + z2), atan(y/x), atan(z/sqrt(x2 + y2)) ]

It can be printed with a 5-axis like PAX printhead, it’s main advantage is to getting close to print continuous overhangs of any angle.

I suspect at least one more suitable and simpler sphere transformation, as soon I came up with such I add it on this blog-post.


It is possible to slice non-planar with planar slicers by mapping to and from the space of the slicing you like to have; yet in the slicing procedure some margins are introduced which need to be compensated – the planar slicer needs to work reliable, Slic3r 1.2.9 and CuraEngine 4.4.1 / cura-slicer perform reliable, whereas PrusaSlicer 2.1.1 makes assumptions of the printability and exits when no printable G-code can be produced, not recommended for this case therefore.

The simpler the transformation forward and backward, the more precise G-code can be obtained, e.g. tilted and conic slices provide precise G-code, whereas cylindrical and spherical slices are harder to tune with the planar slicer.


3D Printing: Cura CLI Wrapper (cura-slicer)


  • 2021/03/24: 0.0.5: public release


I’m a great admirer of the Ultimaker Cura slicer since years, yet I predominantly have been using CuraEngine on the command-line via Print3r, which hides all the tedious configuration. But it came the point (2021/03) when I needed to have a simpler interface than CuraEngine – hence I wrote Cura CLI Wrapper, the executable cura-slicer looks like prusa-slicer or slic3r and has similar usage.

Speciality is to query all the settings from cura-slicer directly:

% cura-slicer --help
acceleration_enabled = 0 (default)
acceleration_infill = 3000 [mm/s²] (default)
acceleration_ironing = 3000 [mm/s²] (default)
acceleration_layer_0 = 3000 [mm/s²] (default)
acceleration_prime_tower = 3000 [mm/s²] (default)
acceleration_print = 3000 [mm/s²] (default)
acceleration_print_layer_0 = 3000 [mm/s²] (default)
acceleration_roofing = 3000 [mm/s²] (default)
acceleration_skirt_brim = 3000 [mm/s²] (default)
acceleration_support = 3000 [mm/s²] (default)
acceleration_support_bottom = 3000 [mm/s²] (default)
acceleration_support_infill = 3000 [mm/s²] (default)
acceleration_support_interface = 3000 [mm/s²] (default)
acceleration_support_roof = 3000 [mm/s²] (default)

which lists ~570 settings as of CuraEngine 4.4.1 and its defaults and from where the defaults come from (definition defaults, config or cli), and you can query also a term e.g. like ‘brim’:

% cura-slicer --help brim
acceleration_skirt_brim = 3000 [mm/s²] (default)
brim_gap = 0 [mm] (default)
brim_line_count = 0 (config)
brim_outside_only = 1 (default)
brim_replaces_support = 1 (default)
brim_width = 8 [mm] (default)
jerk_skirt_brim = 20 [mm/s] (default)
prime_tower_brim_enable = 0 (default)
skirt_brim_line_width = 0.4 [mm] (default)
skirt_brim_material_flow = 100 [%] (default)
skirt_brim_minimal_length = 250 [mm] (default)
skirt_brim_speed = 30 [mm/s] (default)
support_brim_enable = 0 (default)
support_brim_line_count = 20 (default)
support_brim_width = 8 [mm] (default)

and with -v switch you even get a more descriptive output:

% cura-slicer --help brim -v
== acceleration_skirt_brim (Skirt/Brim Acceleration) ==
   The acceleration with which the skirt and brim are printed. Normally this is done with the initial layer acceleration, but sometimes you might want to print the skirt or brim at a different acceleration.
   acceleration_skirt_brim = 3000 [mm/s²] (default)

== brim_gap (Brim Distance) ==
   The horizontal distance between the first brim line and the outline of the first layer of the print. A small gap can make the brim easier to remove while still providing the thermal benefits.
   brim_gap = 0 [mm] (default)

== brim_line_count (Brim Line Count) ==
   The number of lines used for a brim. More brim lines enhance adhesion to the build plate, but also reduces the effective print area.
   brim_line_count = 0 (config)

== brim_outside_only (Brim Only on Outside) ==
   Only print the brim on the outside of the model. This reduces the amount of brim you need to remove afterwards, while it doesn't reduce the bed adhesion that much.
   brim_outside_only = 1 (default)

Essentially it makes Cura and CuraEngine easy to use on the command-line and provides a way to learn of the hundreds of settings available.


USAGE Cura-Slicer 0.0.5 aka Cura-CLI-Wrapper (CuraEngine 4.4.1): [<opts>] <file.stl> ...
      -v or --verbose         increase verbosity
      -vv or --verbose=2          "       "
      --version               display version and exit
      --load=<config>         load config file
      --load <config>           "         "
      --output=<fn>           set output filename
      --output <fn>             "         "
      -o <fn>                   "         "
      --<k>=<v>               set CuraEngine settings (keys with '-' will be converted to '_')
      -h or --help            display all settings
      -h or --help <term> ..  display settings matching term

      cura-slicer --help
      cura-slicer --help retract
      cura-slicer -hv retract 
      cura-slicer sphere.stl
      cura-slicer overhang.stl --output=sample.gcode
      cura-slicer overhang.stl --layer-height=0.1 --support-enable=true -o sample.gcode


The user settings reside in ~/.config/cura-slicer/base.ini and will not be overwritten when upgrading Cura-CLI-Wrapper, make your changes there.

The system-wide settings reside in /usr/share/cura-slicer/base.ini and should not be be changed as it will be overwritten when upgrading Cura-CLI-Wrapper.



% cura-slicer cube.stl
== Cura-Slicer 0.0.3 aka Cura-CLI-Wrapper (CuraEngine 4.4.1) == 
processing cube.stl, slicing to cube.gcode
   took 0.62 secs total, done.

% cura-slicer --support-enable=true overhang-inout.stl
== Cura-Slicer 0.0.3 aka Cura-CLI-Wrapper (CuraEngine 4.4.1) == 
processing overhang-inout.stl, slicing to overhang-inout.gcode
   took 0.99 secs total, done.


Whereever I used CuraEngine before in my existing software packages I will switch to Cura-CLI-Wrapper with cura-slicer.

3D Printing: Slicer4RTN Released 2021/03/22

Just for sake of completeness a blog-post: I just released the source-code for Slicer4RTN. All developments will be documented there.

% slicer4rtn --subdivide=5 --recenter cube.stl
== Slicer4RTN 0.4.5 ==
processing 'cube.stl':
   1/5 read stl
      1/5 subdivide (44 vertices)
      2/5 subdivide (188 vertices)
      3/5 subdivide (764 vertices)
      4/5 subdivide (3068 vertices)
      5/5 subdivide (12284 vertices)
   2/5 map vertices
   3/5 write temporary stl
   4/5 slice (slic3r) stl
=> Processing triangulated mesh
=> Generating perimeters
=> Preparing infill
=> Infilling layers
=> Exporting G-code to ./tmp-204390.gcode
Done. Process took 0 minutes and 1.313 seconds
Filament required: 758.4mm (5.4cm3)
   5/5 remap gcode to 'cube.gcode' (18932 lines)
== took 4 secs total, done.

That’s it.

3D Printing: GCode File Preview in GNOME

When dealing with a lot of G-code it comes handy to have a small thumbnail preview in the file browser under GNOME, hence I coded this package.

It supports Slic3r, Prusa Slicer and Cura.



The package includes gcode2png which can be used standalone as well.

20mm cube sliced with Slic3r and converted with gcode2png to PNG
USAGE gcode2png 0.0.7: [<opts>] <file.gcode> ... 
      --version               print version and exit
      --autolevel             level Z minimum to 0 (default: off)
      --output=<fn>           override .gcode -> .png conversion
      --size=<w>x<h>          set size of image (default: 512x512)
      --rotate=<x>,<y>,<z>    rotate model (default: 30,0,-20)
      --dist=<d>              set distance multiplier (default: 1)
      --color=<r>,<g>,<b>     set color (default: .1,.8,.1)
      --grid=0 or 1           set grid (default: 1)
      --grid_size=<s>         set grid size (default: 10)
      --nozzle=<d>            set nozzle diameter (default: 0.4)
      --complete=<i>          set completeness: 0..1 or 0%..100%
      gcode2png gcube.gcode
      gcode2png --output=cube-normal.png cube.gcode
      gcode2png --color=1,0,0 3DBenchy.gcode
      gcode2png --complete=50% 3DBenchy.gcode

That’s it.

3D Printing: Multi-Axis Printing & Overhangs


  • 2021/03/14: more detailed references, published
  • 2021/03/11: starting write-up with basic illustration


I thought to compose a summary of the features of 3 types of 3D printers I currently work on, and its relations to print 90° overhangs – main motivation to go beyond 3-axis 3D printing:

Functionality Commonalities

  • a 5-axis printer PAX has the same features as a 4-axis printer RTN and 3-axis printer plus it can print at any tilt angle, printing 90° or more overhangs
  • a 4-axis printer RTN prints conic- or angled sliced models so it can print 90° overhangs in all directions (conic slice) from a central point or single direction (angled slice); the tilt angle is fixed at 45°; Z sliced horizontal layers must be post-processed1) to be printable in good quality
  • a 3-axis printer by default cannot print 90° overhangs without support (unless it’s tilted 45° as for belt-printer, then only in one direction), but may print conic sliced models with 20-25° cone angle, hence print 90° overhangs from a central point, and behave partially like a 4-axis printer
  1. a suitable Zrot must be calculated and added to extrusion commands of the G-code, see this example.

Printing an Conic Sliced Overhang

Conic sliced, in this case 45° conic angle, model nr 6 (table-like), with 45° tilted nozzle (simulation, animation)

Conic Sliced on 3-axis

A well tuned and well designed part-cooler is prerequisite to print conic-sliced models at cone angle of 20-25°, and currently there is no conic slicer which can properly segment sub-volumes yet (2021/03) to switch from horizontal- and conic-slicing (with two modes of outside/inside cone) where suitable.

Conic Sliced on 4-axis RTN

Conic- or angled slicing is recommended in order to print with Rotating Tilted Nozzle (RTN) or post-processing of existing horizontal sliced G-code is required to provide additional Zrot information to print in good quality.

Conic Sliced on 5-axis PAX

and nearly the same with PAX90 (tilt angle 0..90° only) with shorter arm:

A 5-axis Penta Axis (PAX) supports other slice methods than horizontal-, angled- or conic-sliced, but any variable build-orientation, but will make the slicing software very complex to recognize those sub-volumes suitable for advanced slicing methods.

This also means, a 5-axis PAX slicer with proper settings can produce G-code for 5-, 4- and 3-axis 3D printers with combining the horizontal-, angled- and cone slicing for sub-volumes or segments.

Traditionally Horizontal Layers

Slic3r 1.2.9 and Ultimaker Cura 4.8 as comparison:


That’s it.

3D Printing: 90° Overhangs without Support Structure with Non-Planar Slicing on 3-axis Printer


  • 2021/03/22: slicer4rtn released, see announcement
  • 2021/03/19: some information on use of slicer4rtn (not yet released)
  • 2021/03/09: removed lengthy “Test Protocol” and extended “Gallery” section a bit
  • 2021/03/08: slicer4rtn at 0.2.4 (still unreleased) resulting in better prints, blog-post linked at hackaday
  • 2021/03/05: 95° and 100° overhangs are printable too, more bug-fixes in slicer4rtn
  • 2021/03/04: fixing various bugs in slicer4rtn as disovered printing more complex pieces, supporting prusa-slicer as well aside slic3r, pushing the limits with overhangs
  • 2021/03/02: documenting my findings, a few photos, some early conclusions (not even one day old), conic sliced and tilt sliced.
90° Overhangs without support structure on 3-axis 3D printer


It has been target of many efforts to print 90° overhangs without support on 3-axis 3D printers as with ordinary Z slicing, each layer requires a support underneath; hence, every overhang then needs a support structure if the model itself doesn’t provide it.

But if . . . one slices non-planar? That’s what I thought about for a couple of years and kept it in the back of my mind. In January 2021 I came across Rotating Tilted Nozzle (RTN) aka RotBot as developed by ZHAW University of Applied Sciences Zurich (Switzerland). I began to design my own approach of the printhead and then started to code my own conic slicer (slicer4rtn), as the paper which might explain it wasn’t published yet by ZHAW.

While reflecting on the output of the 4-axis conic sliced models, I thought what if I simply make the cone angle flatter than 45° but 15-25° so the vertical nozzle can print it?

Overhang model conic sliced at 25° angle
slicer4rtn --angle=22.5 sliced overhang model, meant for 4-axis printer, but printed on 3-axis printer

Conic Slices Simulation

A simple overhang model (nr 3) conic sliced at 25° for 0.4mm nozzle, 0.2mm layer height:

Tilted Slices Simulation

The same overhang model (nr 3) tilt sliced at 25° for 0.4mm nozzle, 0.2mm layer height (like with belt printer):

Conic Slices Print Tests

And on the afternoon of March 1st 2021 I ran my G-code for the first time on an ordinary 3-axis printer, a cheap CTC DIY I3 Pro B (Prusa-i3 like), in the attempt to print 90° overhangs, with a conic sliced overhang model:

Wow – it seems to have worked! There were still some issues, like the nozzle without extrusion moved into the print as I forgot map linear motions without extrusion also to conic coordinates as well, and some other minor things.

You may consider this a “backport” of 4-axis slicing procedure back to a 3-axis 3D printing procedure.

Next Day Attempts

Conic Slices

The print is still pretty ugly due to the obvious under-extrusion, but the geometry seems to work overall. The overhang on the left-front isn’t evenly, as the outer wall print speed is still too high.

Tilted Slices

Very clean print so far but the overhang is limited to one direction (see below of overall considerations).


Well, it works, but here are some limitations of using non-planar slicing:

Conic Slices

  • conic sliced overhangs need to be going out- or inward from a central point
    • more complex pieces need to be volume decomposed or segmented, e.g. some sub-volume sliced ordinary vertically Z-wise, others conic sliced where needed – this is part of my research on 4-axis and 5-axis printers; and I was hoping some of the findings can be applied to 3-axis 3D printer as well (as this post shows)
  • the printhead geometry with heatblock sock, part-cooler, LED light they quickly come into way with larger pieces and larger overhangs
    • this might look minor, but part coolers play significant role for quality prints, so they need to be optimized for non-planar printing
  • cone angle
    • 15° works, sufficient space around the nozzle, but on the edge for overhangs, better surface quality
    • 20° works better, layers more stable beneath the overhang
    • 25° works too, but is the limit on my E3D V6 clone, poorer surface quality, but overhang prints better
  • print quality is sub-optiomal, as the nozzle runs over its own extruded filament and any “flat” surface becomes jittery as it’s not longer flat (toward Z) printed

Tilted Slices

  • single direction angled slice like with belt-printer
  • only one direction overhang possible, but good quality
  • tilt angle:
    • 25° works good, yet, the heatblock comes into the way rather quickly with my sample overhang model

Conic vs Tilted Slices

Issues to Resolve

  • more tests
  • more beautiful prints
    • fine tune extrusion rate: the current slicer4rtn does a simple/poor interpolation causing rough top surfaces (under- vs overextrusion)
    • fine tune outer wall of overhangs, slow them down
      • --slicer.external-perimeter-speed=10% (Slic3r)
  • support more slicers
    • Slic3r: supported since slicer4rtn 0.0.1
    • Prusa Slicer: supported since slicer4rtn 0.1.2 (0.1.1 was broken) but often refuses to slice model, e.g. cube fails in inverted cone space
    • Cura Engine: not yet
    • see Conic Slicing for RTN for up-to-date list
  • support skirts (again): due the slicer algorithm the skirt must omitted before pre-processing but be added at last stage or post-processing
  • redesign my part cooler so I can test print larger overhang pieces
  • find collision algorithm (along with given parametric printhead geometry), that’s part of the 4-axis and 5-axis slicing procedure


2-sided overhang model nr 4 (conic sliced)

Trying out an overhang model which extends -Y and Y (as side-ways the part-cooler comes into the way)

There are still inconsistencies with extrusion calculation, but the prints getting cleaner.

4-sided overhang model nr 6 (conic sliced)

Sample print comes soon as I need to redesign my part cooler so I can print this piece.

1-sided long 4mm thick overhang model nr 3 (conic sliced)

Long 40mm overhang, just 4mm thick extending nose . . .

1-sided long 2mm thick overhang model nr 3 (conic sliced)

Long 40mm overhang, just 2mm thin extending nose, let’s push the limits of what’s possible:

OK print so far, better than anticipated, but still a way to improve it. Reprint with a newer version of slicer4rtn (0.2.3):

  • better surface, no stringing anymore
  • faster print speed but also more geometric inconsistency like bending up
  • underside is more uneven but also cleaner than all the previous (pre- 0.2.0 of slicer4rtn)

1-sided short 2mm thick 95° overhang model nr 3 (conic sliced)

Just trying more overhang, let’s see.

Obviously there is more than 95° overhang possible, so let’s try …

1-sided short 2mm thick 100° overhang model nr 3 (conic sliced)

Even steeper overhang, let’s see.

This is truly promising, up to 100° overhangs printable with vertical nozzle as mounted on most 3-axis 3D printers . . .

Slicer4RTN Settings

As of the publication of this blog-post (2021/03) no slicer is available but slicer4rtn will be made available soon which was released 2021/03/22.

  • Caution: you need to be an experienced 3D printing enthusiast to proceed, you need to know and realize what you do:
    • pay close attention of the printhead geometry, such as the nozzle and heatblock, and the part cooler which limits the non-planar printing
    • depending on the angle, and the direction of extrusion more or less extrusion distortion will occur
Issues to look at when printing conic sliced models with vertical nozzle on a 3-axis 3D printer

  • --angle=20 is a good start, you may go as low as 15°, and perhaps at max at 30° depending on your nozzle and heatblock, if you aim to print 90° overhangs
  • --layer-height=0.2 is a good start too, the thinner the layers the better overhangs can be printed
  • if you have trouble with over- or under-extrusion and your printer otherwise well tuned, then use --erate=f as extrusion-rate tuning, whereas f = 0.5..1.5 or so, if you have to go below or above, something else is wrong.
  • conic slicing is complex(er), you need to think in new terms:
    • the slicing procedure requires a conic slicing center
      • to and from that center overhangs can be printed well
      • if you have multiple centers, slicer4rtn does not yet support volume segmenting to support multiple centers
      • slicer4rtn requires manually entered conic slicing center
    • it requires fine-grained faces so the slicing works well, use --subdivide=5 or higher for simple pieces, e.g. like a cube or low-poly models in generals

Tuning 3-axis 3D Printer

Following changes are recommended:

  • increase Z axis speed: within the start G-code the line M203 Z.. (replace .. with an actual number) to increase speed of Z-axis
    • depending on the pitch of your Z-lead screw or threaded rods, you may set it to Z4, Z6, or higher, so the motion speed comes close to X- and Y-axis to improve print quality
    • if it’s set too high, your stepper motor will block and not move at all
      • my setup with M6 threaded rod for Z (200 full steps = 1mm):
        • M203 Z8, 8mm/s => 8 revolutions/s => 1600 full steps/s: FAILED (blocked motor)
        • M203 Z6, 6mm/s => 6 revolutions/s => 1200 full steps/s: FAILED (stuttering motor at times, mechanical not reliable)
        • M203 Z4, 4mm/s => 4 revolutions/s => 800 full steps/s: OK
        • M203 Z3, 3mm/s -> 3 revolutions/s => 600 full steps/s: OK
  • slow down perimeter (overhangs): use --external-perimeter-speed=20% or a bit more, it prints overhangs better, leave it at 50% if prints look good
  • X- and Y axis speed: try to match your Z speed, so the overall printing is evenly:
    • Slic3r
      • perimeter-speed
      • bridge-speed
      • infill-speed
  • miscellaneous hints:
    • slicer setting solid-infill-below-area = 10 (make infill work at small(er) pieces too)



That’s it.

3D Printing: Conic Slicing for Rotating Tilted Nozzle (RTN) / 4 Axis

State: early draft, mostly simulations with a few tests with 3-axis printer only

Conic sliced overhang model with two overhangs, printing with Rotating Tilted Nozzle (RTN) 90° overhang structure without support structure


  • 2021/03/22: slicer4rtn released, see dedicated page Slicer4RTN
  • 2021/03/16: removing details on slicer4rtn as a new dedicated page is in the working (coming soon)
  • 2021/03/08: slicer4rtn 0.2.3 reached (still unreleased), better prints, documenting various settings in more details
  • 2021/03/05: added proper ZHAW reference in the introduction and a few notes
  • 2021/02/27: removed some redundant illustrations and remade some of them, outside-cone vs inside-cone mode & printing
  • 2021/02/26: added inside-cone printing example for inner overhang mode, also early information of slicer4rtn; more animations to observe details of produced G-code, using now also OpenSCAD to simulate G-code and actual nozzle position
  • 2021/02/24: better tests with 20mm cube and overhang structure, included two short G-code simulations as videos, added 20mm sphere and 3D Benchy and discover first issues with volume decomposition and overhang recognition
  • 2021/02/23: first write up, pseudo code and first attempt to conic slice 20mm cube

As I progress I will update this blog-post.


The main idea is to utilize existing 3D printing slicers but create conic slices for the Rotating Tilted Nozzle (RTN) 4 Axis Printer. ZHAW published in their announcement in 2021/01 something about utilizing existing slicers, but the details remained concealed and later published as a paper but I did not want to wait and pondered on the problem, and came up with a solution. In its current state it’s purely theoretical and untested for now (2021/02) barely tested yet.

Michael Wüthrich confirmed my solution is comparable with their solution. ZHAW planned their paper to be published sometime 2021. So, the main credit goes to ZHAW and the researchers (Prof. Dr. Wilfried Elspass, Dr. Christian Jaeger, Michael Wüthrich, Maurus Gubser, Philip Bos and Simon Holdener) there, I was just impatient and tried to find a solution with the information available.

I also adapted some of the notions Wüthrich introduced in the Novel 4-Axis 3D Printing Process to Print Overhangs Without Support Material paper, e.g. “outside-cone” and “inside-cone” printing as featured in an earlier blog-post already.

Non-Planar Conic Slices

The 4-axis Rotating Tilted Nozzle (RTN) physical setup implies its slices are of non-planar conic shape, allowing to print overhangs without support structure, such as:

Conic slices of an overhang model

I also like to master the conic slices properly as they promise to become a subset of 5 axis printhead (PAX) features too – so it’s worth the effort even if the RTN itself might be too limited in its application with its fixed tilt – we will see.


In a nutshell the steps are following:

  1. sub-divide faces of the model (fine-grained)
  2. map model to inverse conic space
  3. send to slicer
  4. remap G-code to conic space
  5. adding Zrot to G-code

Conic Space Mapping

(x1,y1,z1,rot) = conicSpaceMapping(cx,cy,x,y,z,dir);


  • cx, cy are the conic axis coordinates
  • x, y, z are the input coordinates
  • x1, y1, z1 are the output coordinates
  • rot the rotation angle x,y vs cx,cy
  • dir is either direct (default) or inverse
function conicSpaceMapping(cx,cy,x,y,z,dir='direct') {
   dx = x-cx; 
   dy = y-cy;
   d = sqrt(dx*dx + dy*dy);
   rot = atan2(dy,dx);
   return (x,y,dir=="direct" ? z-d : z+d,rot);


The entire procedure goes like this:

m = loadModel("cube.stl");
m = subDivide(m,5);
for(p of m.vertices) {
    m.vertices[i] = conicSpaceMapping(cx,cy,p.x,p.y,p.z,'inverse');

gcode = sliceModel(m);

foreach(line of gcode) {
   (code,x,y,z,e) = extractCoordsExtrusion(line);
   (x1,y1,z1,zrot) = conicSpaceMapping(cx,cy,x,y,z,'direct');

Note: the pseuco-code is incomplete as extrusion E is not yet taken care of, as soon I found a definitive solution I will write it up.


I implemented the pseudo-code with some more details like taking care of G-code E extrusion as well and fine-step linear extrusion – here some early tests using OpenSCAD as STL & G-code viewer and Slic3r as actual slicer:

20mm Cube Conic Sliced

Snapshots of progress of conic sliced 20mm cube:

20mm cube conic sliced G-code
20mm cube conic sliced with rotating tilted nozzle simulation

Overhang Conic Sliced

Snapshots of progress of conic sliced Overhang:

Conic sliced overhang model
Conic sliced overhang model including rotating tilted nozzle simulation

Gallery of Conic Sliced Models

Detailed snapshots of overhang nr 3

Detailed snapshots of model nr 6 (table-like)

Some more models with their in-between states, using Cura as model and G-code viewer:

Issues to Resolve

  • test actual G-code in real life
  • find good pre-processing face sub-division strategy
    • in its current form the algorithm requires fine-grained sub-divided faces otherwise inaccurate G-code is created which cannot be recovered
  • slice more complex parts
    • 3D Benchy: requires more thorough examination, e.g. volume decomposition to segment roof apart:

  • document all details
  • release source code to public


Some close-ups of conic sliced models:

Outside- vs Inside-Cone Printing

As pointed out in the previous blog-post, the RTN has two main modes of operation, outside-cone and inside-cone printing to cover outside overhangs and inside overhangs – the slicer must recognize those and switch operation mode. Further, these two modes cannot easily be mixed, and need to be segmented or separated, hence speaking of volume segmentation.

This poses significant grow of complexity from just planar slicing, the 4 axis RTN provides features to print 90° overhangs without support structure, but only when the part can be properly analysed and segmented so that those operational mode can be applied.

The difference between inside- and outside-cone printing is to change the order of conic mapping for the model and post slicing:

outside-cone mode

  1. map model inverse conic
  2. slice model
  3. map G-code direct conic

inside-cone mode

  1. map model direct conic
  2. slice model
  3. map G-code inverse conic, Zrot + 180°


The pseudo-code turned into an actual application I named slicer4rtn and is a command-line tool, slicing STL into G-code:

% slicer4rtn --subdivide=5 --recenter cube.stl
== Slicer4RTN 0.4.1 ==
processing 'cube.stl':
   1/5 read stl
      1/5 subdivide (44 vertices)
      2/5 subdivide (188 vertices)
      3/5 subdivide (764 vertices)
      4/5 subdivide (3068 vertices)
      5/5 subdivide (12284 vertices)
   2/5 map vertices
   3/5 write temporary stl
   4/5 slice (slic3r) stl
=> Processing triangulated mesh
=> Generating perimeters
=> Preparing infill
=> Infilling layers
=> Exporting G-code to ./temp-603919.gcode
Done. Process took 0 minutes and 1.362 seconds
Filament required: 710.9mm (5.0cm3)
   5/5 remap gcode to 'cube.gcode' (16214 lines)
== took 3 secs total, done.

I gonna released Slicer4RTN eventually 2021/03/22, in its early version the model currently can only be sliced for outside-cone or inside-cone printing, so the volume decomposition or segmentation needs to be done separately. For now it helps me to verify some of the 4-axis and 5-axis printer designs I work on.

Ashtar K RTN printing conic sliced 20mm cube (close up, animation)
Ashtar K RTN printing conic sliced overhang model without support structure (close up, animation)
Ashtar K RTN printing conic sliced overhang model nr 6 (table-like) without support structure (close up, animation)

Test Prints

As soon I built the RTN printhead on one of my printers I will post photos of the first prints. For now (2021/03) I only printed conic sliced pieces on a 3-axis 3D printer.


With conic sliced G-code there are many first layers . . .

That’s it.

3D Printing: Ashtar Series Printhead Options 2021/02

The past weeks (2021/02) I worked on various printhead designs, to summarize and provide an overview by mounting them on Ashtar K:

Also improved the display controller to simulate Marlin firmware and list heads and tool selection (MSE), coordinates (IDEX) or rotation angles (RTN & PAX).

So far all options are available for Ashtar C, D and M as well, but currently (2021/02) are just in draft and mostly untested.

RTN and PAX promise printable support-free overhangs, yet no public available slicing software exists to really take advantage of those two designs, as new algorithms of volume decomposition, sub-volume sequencing, collision detection are required and mostly debated in scientific papers as 2021/02 and only few companies, e.g. HAGE and VSHAPER, implemented new 5-axis 3D printing procedures, and DotXControl advertises a 5 Axis Slicer.

That’s it.

3D Printing: Penta Axis (PAX) / 5 Axis Printing Option – Draft

Status: very early draft, inverse kinematics resolved


  • 2021/02/28: added animation PAX printing a 4-axis/RTN sliced overhang model
  • 2021/02/17: added two brief animations of inverse kinematics
  • 2021/02/08: inverse kinematics working, printhead mounted on Ashtar K as draft
  • 2021/02/06: machine vs nozzle coordinates, forward/reverse transformation requirements, heatsink fan and part cooler added
  • 2021/02/04: starting with collecting ideas and first drafts


After I saw 5- and 6-axis printers at Formnext 2019 and particularly seeing the belt printers able to print 90° overhangs in one direction without support, and then RotBot by ZHAW, a Rotating Tilted Nozzle (RTN) printer, where the 90° overhangs in different directions (given some conditions) can be printed without support – so it was more natural to consider to make the tilting nozzle angle (trot) flexible as well, 0 – 180°.

  • 0°: nozzle looking down, ordinary orientation with Z sliced layers 3D printing
  • 45°: belt printer or rotating tilted nozzle (RTN) printer, printing 90° overhangs in one or more directions *)
  • 90°: printing horizontally outward
  • 135°: printing upward 45°
  • 180°: printing upward entirely

*) Rotating Tilted Nozzle capability printing 90° overhangs depends on location and symmetric alignments, no slicing software yet available.

Flexible Tilting

2 Axes with NEMA 17

Let’s look at bit closer to the new rotating axes implemented with direct drive NEMA 17 stepper motors:

  • Z rotation (aka Zrot) with
    • NEMA 17 39/40mm long (45Nm) or
    • NEMA 17 25mm/180g (13Nm)
  • Tilt rotation (aka Trot) with
    • NEMA 17 20mm/140g (16Nm) or
    • NEMA 17 25mm/180g (13Nm)

both provide 1.8° (or optionally 0.9°) resolution per full step, or

  • 8 microsteps (20% force) 0.225° @1.8°step (0.1125° @0.9°step) per microstep
    • Z rotation 9 Nm (or 2.6Nm)
    • T rotation 3.2 Nm
  • 16 microsteps (10% force) 0.1125° @1.8°step (0.0565° @0.9°step) per microstep
    • Z rotation 4.5 Nm (or 1.3Nm)
    • T rotation 1.6 Nm

For now, for sake of simplicity, both axes are in direct drive – if precision requirements dictate a simple reduction gear 1:4 or 1:5 (see below for some more details).

Taking Advantage of 5 Axis

In 5 axis CNC context there are multiple configurations possible such as table/table, head/head and table/head – as I came from the Rotating Tilted Nozzle (RTN) the extra 2 axis are added to the head, hence head/head configuration.

Tilt rotation 0 .. 180°

The Trot of 0° is the equivalent of ordinary 3D printer with top/down oriented nozzle, the 45° the belt printer or RotBot/RTN, and 90° printing vertical walls with the nozzle perpendicular, and 90-135° printing up-side down – I’m not sure if 135-180° is that useful, perhaps making underlying structures really smooth. For now I keep the tilt rotation from 0° to 180° even though I think I’m going to use 0-135° in real life application when the actual print procedure is developed, planar or non-planar slicing.


5 Axis Kinematics

LinuxCNC 5 Axis kinematics describes the notations and provides a starting point and I realized quickly that in CNC context the 5 axis operations is quite thoroughly explored, but much fewer focus on 5 axis additive manufacturing yet (see below at References).

In order to reflect the rotation per axis, the notion A, B and C are adopted, which can be described in OpenSCAD as

translate([X,Y,Z]) rotate([A,B,C]) ...
X,Y,Z (tool coordinate) and I,J,K (tool vector)

Further the CNC notion I, J and K are used as tool vector, the way the nozzle points away. G-code supports natively G1 X Y Z I J K which is machine independent. The machine specific firmware then computes the machine coordinates and rotating angles so the machine tool tip reaches those coordinates with that particular tool vector.

Tool/Nozzle vs Machine Coordinates

Absolute coordinates X, Y, Z of the nozzle tip and angles Zrot, Trot and given the Z rotation arm there is a mapping required to Xm, Ym, Zm with same Zrot, Trot.

The forward transformation in OpenSCAD:

translate([Xm,Ym,Zm]) rotate([0,0,Zrot]) rotate([Trot,0,0]) translate([0,0,-45]) sphere(0.1); // nozzle tip at X, Y, Z with I, J, K
45mm vertical offset of tilt axis to nozzle tip

or expressing it as a list:

  1. at 0, 0, 0 (origin)
  2. translate([Xm,Ym,Zm])
  3. rotate([0,0,Zrot])
  4. rotate([Trot,0,0])
  5. translate([0,0,-45])
  6. at X, Y, Z

The -45 is the 45mm vertical offset of the tilt rotation to the tip of the nozzle.

In OpenSCAD it’s the reverse order, and enumerate matrices (used further below):

  1. at X, Y, Z
  2. translate([0,0,45]) aka M1
  3. rotate([-Trot,0,0]) aka M2
  4. rotate([0,0,-Zrot]) aka M3
  5. translate([ Xm, Ym, Zm ]) aka MR, by inverting matrix the Xm, Ym, Zm can be extracted
  6. at 0, 0, 0 (origin)

Each transformation can be represented by a 4×4 matrix, the sequence of transformations are the multiplication of such, and when multiplying symbolical a single 4×4 matrix will result. When keeping the symbolical notion the inverse transformation can be obtained with one operation and getting Xm, Ym, Zm from X, Y, Z, Zrot, Trot, and that very computation needs to be done in the firmware and controller in order to process X, Y, Z, Zrot, Trot as G1 X.. Y.. Z.. A.. B.. and the internally Xm, Ym, Zm is processed to achieve that tool coordinate; A = Zrot, B = Trot .


G1 X.. Y.. Z.. A.. B..


Zrot = A
Trot = B
Xm, Ym, Zm computed via reverse/inverse transformation on the controller

Numerical Inverse Transformation

Just for sake of confirming the reverse/inverse transformation utilizing m4.scad:

include <m4.scad>

Zrot = 45;
Trot = 45;

M1 =       [ [ 1, 0, 0, 0 ],
             [ 0, 1, 0, 0 ],
             [ 0, 0, 1, 45 ],
             [ 0, 0, 0, 1 ] ];

M2 =       [ [ 1, 0, 0, 0 ],
             [ 0, cos(-Trot), -sin(-Trot), 0 ],
             [ 0, sin(-Trot), cos(-Trot), 0 ],
             [ 0, 0, 0, 1 ] ];

M3 =       [ [ cos(-Zrot), -sin(-Zrot), 0, 0 ],
             [ sin(-Zrot), cos(-Zrot), 0, 0 ],
             [ 0, 0, 1, 0 ],
             [ 0, 0, 0, 1 ] ];

MR = m4inv(M1 * M2 * M3);
// or MR = m4inv(m4tr([0,0,45])*m4rx(-Trot)*m4rz(-Zrot));

which outputs

ECHO: [[1, 0, 0, 0], [0, 0.707107, -0.707107, 31.8198], [0, 0.707107, 0.707107, -31.8198], [0, 0, 0, 1]]

so MR contains the inverse matrix of the previous transformations, so I can extract the translation vector, the 4th column [ MR[0][3], MR[1][3], MR[2][3] ] or m4trv(MR) to compensate X, Y, Z, Zrot, Trot -> Xm, Ym, Zm:

Testing Inverse Kinematics (IK)

PAX printhead on Ashtar K, inverse kinematics tested: X=150, Y=0, Z=0, Zrot=0..180°, Trot=0..45° (animated)

Perhaps it’s worth to actually calculate symbolical forward and inverse transformation matrix using e.g. Matlab or alike to have transformations in one operation instead multiplying three matrices and inverting it – depending what hardware is used as controller multiplying individual matrices is faster than trying to have a complex single step matrix construct.

Although Marlin firmware supports Delta printer with complex delta inverse kinematics, not sure I can add mine as well, or I have to go with Duet RepRap firmware which seems more suitable (see notes below).

Nozzle Precision from Trot

The 45mm offset of the last rotation massivly contributes to the loss of nozzle position resolution:

s = 2 π * r / 360 = section length per degree

s = π * 45mm / 180 = 0.785mm/° which means:

  • 8 microsteps with 1.8° full step: 0.225°/microstep => 176.7μm/microstep
  • 16 microsteps with 1.8° full step: 0.1125°/microstep => 88.3μm/microstep
  • 8 microsteps with 0.9° full step: 0.1125°/microstep => 88.3μm/microstep
  • 16 microsteps with 0.9° full step: 0.0565°/microstep => 44.4μm/microstep

so the direct drive using the shafts of the NEMA 17 will provide OK resolution, but for anything a bit more serious, a reduction gear might be worth to use.

G-code & Firmware

As I likely will generate machine independent G-code as G1 X Y Z I J K, the slicer stage will likely operate in X, Y, Z and Zrot and Trot as well – so we end up with a data pipeline like this:

  1. Slicer: X, Y, Z, Zrot, Trot
  2. G-code: G1 X Y Z I J K
  3. Firmware: X Y Z I J K => Xm, Ym, Zm and I J K => Zrot, Trot

Alternatively, instead using I J K notion use the G-code A and B as two rotational axes as Duet RepRap Firmware offers G1 X Y Z A B then it’s a bit simpler:

  1. Slicer: X, Y, Z, Zrot=>A, Trot=>B
  2. G-code G1 X Y Z A B
  3. Firmware: X Y Z A B => Xm, Ym, Zm and A=>Zrot, B=>Trot

Reviewing existing slicer/printing software to see which notion is more suitable, and perhaps cover both to stay flexible.

From Xm, Ym, Zm, Zrot, Trot to X, Y, Z

Issues to Resolve

  • Bowden tube- & cable management: properly resolve it, guides etc.
  • Develop the transformation/inverse kinematics X, Y, Z, Zrot, Trot <=> Xm, Ym, Zm, Zrot, Trot as well X, Y, Z, I, J, K <=> Xm, Ym, Zm, Zrot, Trot as required for slicing, and firmware stage, done
  • Calculate the precision of X, Y, Z in relation of Xm, Ym, Zm and Zrot, Trot, whether or how the motor resolution affect axes => getting a grasp how the overall precision of the final setup
  • Direct drive mechanical precision with 8/16 microsteps, repeatability, and heat dissipation from motor (see tweet)
  • Slicer/print software supporting 5 axis nozzle
    • Duet RepRap Firmware: supports ABCD rotational axes
    • Marlin firmware capabilities, as it support Delta printers, inverse kinematics (IK) calculations seem supported well, question is how simple to add my own custom IK as well
    • printing: recognize model features or base design on seams or boundaries, like OPENCASCADE (STEP/IGES support)
    • printing: use vertical slicing as fallback, given no other printing method is suitable
    • explore different print modes like RotBot/RTN
      • recognize rotational objects: print from inside out like with a lath but adding material
      • detect steep overhangs, find proper way to print them
    • collision detection, e.g. tilt rotation becomes available at a certain Z level as below the upside looking nozzle will touch the build plate with the opposite end – the slicing/print software must be aware of the printhead geometry to calculate what’s possible to print and how



  • many new ways to print in (almost) all directions
  • hopefully print 90° and more overhangs without support at all


  • significant mechanical complexity
    • mechanical limitations arise with new freedom of rotation of printhead
    • collision detection becomes essential which in Z sliced layers is not an issue at all
  • significant software complexity, no current 3D printing software available to take advantage of 5 axis printing

Ashtar K with 5 Axis (PAX) Printhead

Experimental mounting on Ashtar K to see how it looks, including display showing rotations of Zrot (A), Trot (B) too.

Note: the display shows original tool coordinates, whereas the firmware does tool translation aka inverse kinematics as shown in the screenshots with the display readable.

PAX printhead on Ashtar K with virtual Marlin firmware display (animated)

With all the freedom to angle the nozzle, all of the sudden the part cooler air nozzle shape becomes an issue, and has to become narrow as well; and overall geometry of the printhead becomes quite relevant when planning print sequences (collision detection).

PAX can operate in 4-axis mode, e.g. printing a conic sliced (4-axis RTN) overhang model (without support structure) in 4-axis Rotating Tilted Nozzle (RTN) mode (45° titled nozzle):

Ashtar K PAX printing 4-axis/RTN sliced overhang model (animation)

PAX Tilt 180 vs 90

The PAX which tilts up to 180° will be referenced further as PAX or PAX 180, the 360° Z rotation is implied then too, as comparison of PAX 90 tilting to 90° only with shorter arm:

As the slicing strategy isn’t determined, it’s not yet clear if tilt 90..180° is required or not. In case only 0..90° is sufficient, the Z rotation arm can be shortened.


5 Axis

4 Axis

As I progress I will update this blog-post.

That’s it.