Tag Archives: CLI



  • 2023/01/22: published, adding machine_uuid details
  • 2023/01/09: keeping in sync with actual development
  • 2022/12/28: starting writeup


Prynt3r (prynt3r) is the Python reimplementation (2022) of my own Print3r (print3r) which was written in Perl back in ~2017.


  • print, slice or preview 3D print jobs (gcode, stl, obj, 3mf, svg, scad, etc)
  • pure command-line interface (CLI)
  • multiple slicers are supported (slic3r, prusa, cura, kirimoto, mandoline, etc), yet, with common slicer agnostic settings
  • multiple printer profiles
  • remote/network printing built-in (tcp, rrf)
  • all prints are logged with all settings incl. unique identifier per print job1)
  1. ability to uniquely identify parts by attaching QR codes of RFID stickers with print UID to tie physical part with print job


After download and installation, you can start to configure and use it:


          ____    .              __ _____         .
     *   / __ \_______* ______  / /|__  /_____                 *
        / /_/ / ___/ / / / __ \/ __//_ </ ___/  .         |             *
   .   / ____/ /  / /_/ / / / / /____/ / /              -=*=-      .
      /_/   /_/   \__, /_/ /_/\__/____/_/        *   .    |
                 /____/                     V0.0.8           *          .

Prynt3r 0.0.8 USAGE: [<opts>] <cmd> <arg1> ...

      slice <file1> ...    slice file(s) into single gcode, e.g. use -o <fn> or --output=<fn>
      print <file1> ...    slice and send gcode to printer local or remote, e.g. define -d <dev> or --device=<dev>
      preview <file1> ...  slice file(s) into single gcode and launch gcode viewer
      gconsole             starts interactive g-code console
      log [<s>] [#<n>]     list log, query term <s> or list log entry '#<n>', with --output or -o you can list only particul
      client               start client process, so remote prynt3r can access it

      stl, obj, off, 3mf, ply, scad, jscad, zcad, vdb, svg

      --help               print this message
      --version            print version and exit

      --device=<dev>       set device (default: /dev/ttyUSB0)
        -d <dev>

      --printer=<name>     set printer name (default: default)
        -p <name>

      --slicer=<slicer>    set slicer: cura, cura-legacy, cura4, cura5, curax, prusa, slic3r, slic3r-pe, slicer4rtn, cura-slicer, super, mandoline, 5dmaker, kirimoto, zplus, lab, vox3l, voxgl, metatron, enoch, goslice, (default: slic3r)
        -s <slicer>

      --gcode-viewer=<cmd> set gcode previewer (default: yagv)

      --verbose=<n>        increase verbosity
      --extended or -x     extended output, e.g. for 'log' command
      --quiet or -q        stay quiet, only output warnings or errors

      --output=<fn>        slice: slicing into a particular file 'prynt3r slice cube.stl -o test.gcode' or
         -o <fn>              log: 'prynt3r log -o uid,files,args' to list particular fields of the log file

      --placement=<loc>    set location: 'none', 'center', 'random' (default: none)

      --rotate=<x>,<y>,<z> rotate model(s)
      --scale=<f>          scale model(s) uniformly
      --scale=<x>,<y>,<z>  scale model(s), if value has 'mm' appended, then axis is set absolute
                              e.g. "0,0,20mm" scales model(s) to 20mm Z height, all axes with 0 scales

      --multiply-part=<n>  multiply model(s)

      --recenter=<s>       recenter models (default: 1), recommended when rotating
      --relevel=<s>        relevel models (default: 1), recommended when rotating

      --uid=<uid>          set uid for print process (otherwise unique will be generated)
      --keep               keep all temporary files (for debugging)

      --scad               treat arguments as OpenSCAD code, e.g. --scad 'cube(20)'
         --scadlib=<lib>[,<lib2>]   consider libraries as well, e.g. --scadlib=parts.scad
      --zcad               treat arguments as OpenZCAD code
      --jscad              treat arguments as OpenJSCAD code

  slicing options (slicer independent):
      --machine-name=<v>         set machine name (default: "Unknown")
      --machine-uuid=<v>         set machine uuid (default: "")
      --machine-width=<v>        set machine width (default: 200.0)
      --machine-depth=<v>        set machine depth (default: 200.0)
      --machine-height=<v>       set machine height (default: 180.0)
      --nozzle-diameter=<v>      set nozzle diameter (default: "0.4")
      --line-width=<v>           set line width (default: 0.4)
      --layer-height=<v>         set layer height (default: "0.3")
      --filament-diameter=<v>    set filament diameter (default: "1.75")
      --fill-density=<v>         set fill density (default: "20")
      --temperature=<v>          set temperature (default: "200")
      --first-layer-temperature=<v> set first layer temperature (default: "210")
      --bed-temperature=<v>      set bed temperature (default: "45")
      --first-layer-height=<v>   set first layer height (default: "0.25")
      --first-layer-speed=<v>    set first layer speed (default: "20")
      --skirts=<v>               set skirts (default: "2")
      --brims=<v>                set brims (default: "0")
      --rafts=<v>                set rafts (default: "0")
      --support=<v>              set support (default: "none")
      --support-angle=<v>        set support angle (default: "60")
      --seam=<v>                 set seam (default: "aligned")
      --top-thickness=<v>        set top thickness (default: "0")
      --bottom-thickness=<v>     set bottom thickness (default: "0")
      --wall-thickness=<v>       set wall thickness (default: "0")
      --perimeters=<v>           set perimeters (default: "2")
      --top-layers=<v>           set top layers (default: "2")
      --bottom-layers=<v>        set bottom layers (default: "2")
      --start-gcode=<v>          set start gcode (default: "G28 X0 Y0\\nG1 X100 F6000\\nG28 Z0\\nM206 X0 Y-25 Z0.15\\n\n")
      --end-gcode=<v>            set end gcode (default: "G1 Y290 F6000\\nM104 S0\\nM140 S0\\nM84\\n")
      --abort-gcode=<v>          set abort gcode (default: "M104 S0 ; extruder heater off\\nM140 S0 ; heated bed heater off (if you have it)\\nG1 X10 F9000 ; go way to the left\\nM84     ; motors off\\n")
      --prepend-gcode=<v>        set prepend gcode (default: "")
      --retraction-length=<v>    set retraction length (default: "2")
      --retraction-speed=<v>     set retraction speed (default: "70")
      --print-speed=<v>          set print speed (default: "60")
      --travel-speed=<v>         set travel speed (default: "130")
      --perimeter-speed=<v>      set perimeter speed (default: "60")
      --small-perimeter-speed=<v> set small perimeter speed (default: "15")
      --infill-speed=<v>         set infill speed (default: "80")
      --bridge-speed=<v>         set bridge speed (default: "60")
      --extruders-count=<v>      set extruders count (default: "1")
      --cool-fan-speed=<v>       set cool fan speed (default: "100")
      --cool-fan-speed-min=<v>   set cool fan speed min (default: "30")
      --cool-fan-speed-max=<v>   set cool fan speed max (default: "100")

      prynt3r print cube.stl
      prynt3r print cube.scad
      prynt3r -p prusa-i3 print --scad 'cube(20)'
      prynt3r -p ashtar-k-1 -s cura5 slice cube.3mf
      prynt3r -p ashtar-k-1 -s cura5 print structure.vdb -d tcp:
      prynt3r -s prusa slice cube.stl -o a.gcode
      prynt3r preview cube.stl
      prynt3r log
      prynt3r log cube.stl -v
      prynt3r log '#100' -xv
      prynt3r log -o uid,args,files
      prynt3r -d /dev/ttyACM0 client &
      prynt3r -d /dev/ttyACM1 gconsole
      > M115


First you need to adjust the profile for your 3D printer(s):

% cd ~/.config/prynt3r/printer
% cp /usr/share/prynt3r/printer/default.ini myprinter.ini

as next edit myprinter.ini according the specifications of your printer, after that your profile is available as -p myprinter or --printer=myprinter when calling prynt3r:

% prynt3r -p myprinter print --scad 'cube(20)' --fill-density=0

Machine UUID

Optionally, if you run a bunch of 3D printers, define machine_uuid in your .ini file, which references the Marlin’s UUID or RepRapFirmware’s Board ID or as fallback the MAC of the Wi-Fi – this is what the machine_uuid is verified with on serial or remote connection.

Retrieve the UUID with

prynt3r -d /dev/ttyACM0 gconsole

and then send M115 and M122, like:

Marlin M115

% FIRMWARE_NAME:Marlin (Sep 23 2022 16:48:31) SOURCE_CODE_URL:github.com/MarlinFirmware/Marlin PROTOCOL_VERSION:1.0 MACHINE_TYPE:Ashtar K E3 #3 L8 EXTRUDER_COUNT:3 UUID:8309209b-1c20-11ed-861d-0122ac4e0002

RepRapFirmware M122

RepRapFirmware for Duet 3 Mini 5+ version 3.4.0alpha (2021-07-09 08:59:45) running on Duet 3 Mini5plus Ethernet (standalone mode)
Board ID: ABR3A-KA67A-J03J0-40TFS-21D0Z-RTDXU
Used output buffers: 1 of 40 (2 max)
=== RTOS ===
Static ram: 102768
Dynamic ram: 105632 of which 0 recycled
Never used RAM 35304, free system stack 155 words
Tasks: NETWORK(ready,25.8%,546) ETHERNET(notifyWait,0.0%,662) HEAT(notifyWait,0.0%,361) Move(notifyWait,0.1%,302) CanReceiv(notifyWait,0.0%,939) CanSender(notifyWait,0.0%,371) CanClock(delaying,0.0%,340) TMC(notifyWait,1.1%,112) MAIN(running,72.1%,438) IDLE(ready,0.1%,29) AIN(delaying,0.8%,262), total 100.0%
Owned mutexes: USB(MAIN)

without Board ID, checking the WiFi MAC:

- WiFi -
Network state is active
WiFi module is connected to access point
Failed messages: pending 0, notready 0, noresp 0
Bad header: 0/0
WiFi firmware version 1.26-08S32-D
WiFi MAC address ad:15:a3:15:6c:95
WiFi Vcc 0.00, reset reason Power up
WiFi flash size 0, free heap 151828

A printer is identified with:

  • CLI: printer nickname with --printer=<nick> or -p <nick>
  • <nick>.ini: machine_name=“Full Name” where you write it out exactly, e.g. “Ashtar K #3 PAX”, which means it’s Ashtar K number 3 with PAX extension
  • <nick>.ini: machine_uuid=<uid> where you ensure the actual identity with the hardware at time of connecting

Networked Printing

You can print to a computer which has 3D printers connected to, if you run

prynt3r -d /dev/ttyACM0 client &
prynt3r -d /dev/ttyACM1 client &

on the host which has the printer(s) attached, and then on your main computer:

prynt3r -d tcp:host:0 -p myprinter1 print --scad 'cube(20)'
prynt3r -d tcp:host:1 -p myprinter2 print --scad 'cube(20)'

RepRapFirmware Wi-Fi/Ethernet

[Coming Soon] If you run RepRapFirmware like on Duet3D boards, then you can reference them as such:

prynt3r -d rrf: -p myprinter1 print --scad 'cube(20)'

it will upload the .gcode and run it, yet, prynt3r will wait until the print is finished.

Prynt3r vs Print3r

So far the slicer independent settings of Print3r are the same as for Prynt3r, so you can migrate the ~./config/print3r/printer/* into ~/.config/prynt3r/printer/* simply, the same with the macros.

Migrate from Print3r to Prynt3r

cd ~
mkdir .config/prynt3r
cp -rp .config/print3r/* .config/prynt3r/

The same as print3r:

  • printer profiles
  • slicer profiles incl. mapping
  • macro profiles
  • protocol for remote printing

The differences as print3r:

  • new: better usage output with actual list of slicer independent settings
  • new: written in Python
  • new: smaller code-base (Py ~1.2K lines vs Perl 4.1K lines)
    • one main reason is using trimesh doing import/export/manipulation of meshs incl. diverse mesh formats
  • removed: no gcode rendering into PNG



Note: As of 2023 I started a rewrite Prynt3r in Python, reimplementing Print3r (Perl).

Print3r or print3r (pronounced print-three-r) is a command line tool (CLI) which supports:

  • multiple different slicers (Cura, Slic3r, PrusaSlicer, Mandoline, KiriMotoSlicer) with same unified settings
  • multiple 3D formats more than what each slicer supports:
    • STL, OBJ, OFF, AMF, 3MF, 3MJ and also
    • OpenSCAD (.scad), OpenJSCAD (.jscad), ScriptCAD (.sccad)
    • FCStd, IGES, STEP and Brep (using FreeCAD2Any helper)
  • networked/cloud printing built-in with multiple 3D-printers


% print3r [<options>] <command> <file1> ...


  • print: print the part (and perform necessary conversions to achieve print)
  • slice: just slice the part to gcode with slic3r, slic3r-pe, cura, cura-legacy or prusa
  • preview: preview print as gcode
  • render: render image of print
  • gcode: send Gcode from command-line
  • gconsole: start Gcode console to interactively send commands
  • client: enable remote printing (start client mode)
  • log: query past logged prints

Print (Convert & Slice & Print)

% print3r print cube.scad
% print3r print cube.stl
% print3r print cube.gcode
% print3r --scad print "cube(20)"

Slice (Without Printing)

Just slice the part to Gcode:

% print3r --output=cube.gcode slice cube.scad
% print3r --output=cube.gcode slice cube.stl

Preview (Without Printing)

Preview the resulting Gcode:

% print3r preview cube.scad
% print3r preview cube.stl
% print3r preview cube.gcode
% print3r --scad preview "cube(20)"


Render the Gcode into an image:

% print3r --output=test.png render cube.scad
% print3r --output=test.png --scad render "cube(20)"
% print3r --output=test.png render cube.stl
% print3r --output=test.png render cube.gcode

Cloud Printing (Server/Client)

Create a printhub by starting print3r in client-mode:

% print3r --device=/dev/ttyUSB0 client &
% print3r --device=/dev/ttyUSB1 client &

On the another host you can address the printhub(s):

% print3r --device=tcp: print benchy.stl
% print3r --device=tcp: print calibrationCube.stl

Usage Overview

Print3r (print3r) 0.2.0 USAGE: [<options>] <cmd> <file1> [<...>]

      --verbose or -v or -vv  increase verbosity
      --quiet or -q           no output except fatal errors
      --baudrate=<n>          set baudrate, default: 115200
      --device=<d>            set device, default: /dev/ttyUSB0
      --slicer=<slicer>       set slicer, default: slic3r
                                 slic3r, slic3r-pe, cura-legacy, cura, prusa
      --printer=<name>        config of printer, default: default
      --version               display version and exit
      --output=<file>         define output file for 'slice' and 'render' command
      --scad                  consider all arguments as actual OpenSCAD code (not files)
      --scadlib=<files>       define OpenSCAD files separated by "," or ":"
      part preprocessing:
         --random-placement   place print randomly on the bed
         --auto-center        place print in the center
         --multiply-part=<n>  multiply part(s)
         --scale=<x>,<y>,<z>     scale part x,y,z (absolute if 'mm' is appended)
         --scale=<f>             scale part f,f,f
         --rotate=<x>,<y>,<z>    rotate x,y,z
         --translate=<x>,<y>,<z> translate x,y,z
         --mirror=<x>,<y>,<z>    mirror x,y,z (0=keep, 1=mirror)
      --<key>=<value>         include any valid slicer option (e.g. slic3r --help)

      print <file> [...]      print (convert & slice & print) part(s) (.scad, .stl, .obj, .gcode)
      slice <file> [...]      slice file(s) to gcode (.scad, .stl, .amf, .obj, .3mf)
      preview <file> [...]    slice & preview (.scad, .stl, .obj, .gcode)
      render <file> [...]     render an image (use '--output=sample.png' or so)
      gcode <code1> [...]     send gcode lines
      gconsole                start gcode console
      client                  map USB connected printer to network (per device)

      export PRINT3R "printer=my_printer" --OR-- setenv PRINT3R "printer=my_printer"
      print3r slice cube.stl
      print3r --layer-height=0.2 --output=test.gcode slice cube.stl
      print3r --printer=ender3 --device=/dev/ttyUSB1 print test.gcode
      print3r --printer=corexy --device=/dev/ttyUSB2 --layer-height=0.3 --fill-density=0 print cube.stl
      print3r --printer=ender3 --device=tcp: --layer-height=0.25 print cube.stl
      print3r print cube.scad
      print3r --scad print "cube(20)"
      print3r gcode 'G28 X Y' 'G1 X60' 'G28 Z'
      print3r gconsole
      == Print3r: Gcode Console (gconsole) - use CTRL-C or 'exit' or 'quit' to exit
         for valid Gcode see https://reprap.org/wiki/G-code
         conf: device /dev/ttyUSB0, connected
      > M115


Following slicers are supported via --slicer=<slicer>:

  • slic3r: Slic3r
  • slic3r-pe: Slic3r Prusa Edition
  • cura-legacy: CuraEngine 15.04 with old profiles
  • cura: CuraEngine 3.x or later
  • prusa: PrusaSlicer

/usr/share/print3r/slicer/<slicer>/base.ini contains the base settings for a particular slicer.


print command converts, slices and sends the resulting Gcode to the USB port of your choice.

% print3r print cube.scad
% print3r --scad print 'cube(20)'
% print3r print cube.stl pyramid.obj
% print3r print cube.gcode

Part Preprocessing

All part-preprocessing operations can be used in combination of printslicepreview and render command:


  • --random-placement place print randomly on the bed to evenly use the entire bed
  • --auto-center place print in the center (default)
% print3r print cube.scad
% print3r --auto-center print cube.scad
% print3r --random-placement print cube.stl

Multiply Part

--multiply-part=<n> multiply part(s)

% print3r --multiply-part=2 print cube.stl
% print3r --multiply-part=2 print cube.stl dodecahedron.stl
% print3r --multiply-part=2 preview cube.scad pyramid.stl

each part is multiplied, --multiply-part=1 is redundant.


  • --scale=<x>,<y>,<z> scale part x,y,z (absolute if ‘mm’ is appended)
  • --scale=<f> scale part f,f,f

whereas each value can be:

  • <float> = multiplier, special case 0 = scale proportionally
  • <float>% = multiplier in percent
  • <float>mm = force to x mm absolute length and scale all axis set to 0 proportionally
% print3r --scale=2 preview cube.scad
% print3r --scale=200% print cube.stl
% print3r --scale=2,1,0.5 print cube.stl
% print3r --scale=20mm,0,0 print box.stl
% print3r --scale=20mm,2,1 print box.stl
% print3r --scale=300mm,30%,1 print box.stl


--rotate=<x>,<y>,<z> rotate x,y,z where is each angle 0 .. 360 deg

% print3r --rotate=90,0,0 preview toy.scad
% print3r --rotate=90,0,0 print toy.stl


--translate=<x>,<y>,<z> translate x,y,z whereas each value in [mm], disables --auto-center and --random-placement.

% print3r --translate=-40,20,0 print cube.stl


--mirror=<x>,<y>,<z> mirror x,y,z (0=keep, 1=mirror), the same can be achieved with --scale= by using -1 (mirror) and 1 (keep):

% print3r --mirror=1,0,0 print toy.stl
% print3r --mirror=0,1,0 print mount.stl
% print3r --scale=1,-1,1 print mount.stl 


slice command converts and slices the model to Gcode file, best set --output=file.gcode to define the filename.

% print3r slice cube.scad
% print3r slice cube.stl
% print3r --output=cube.gcode cube.scad
% print3r --slicer=cura --output=cube.gcode cube.scad
% print3r --slicer=slic3r-pe --output=cube2.gcode cube.scad


preview command converts, slices and display the resulting Gcode with yagv Gcode viewer.

% print3r preview cube.scad
% print3r --slicer=cura preview cube.scad
% print3r --slicer=cura --printer=prusa-i3 preview cube.scad
% print3r --slicer=slic3r-pe --printer=ashtar-k-1 preview cube.stl pyramid.stl


render command converts, slices and renders the resulting Gcode into a PNG image, best set --output=test.png to define the filename.

% print3r render cube.scad
% print3r --slicer=cura render 3DBenchy.stl
% print3r --slicer=cura --printer=prusa-i3 render cube.scad
% print3r --slicer=slic3r-pe --printer=ashtar-k-1 --output=set.png render cube.stl pyramid.stl


gcode command allows to send Gcode in the command line directly:

% print3r gcode 'G28 X Y'
% print3r gcode 'G28 Z'

Gcode Console (gconsole)

gconsole command launches an interactive console to send Gcode and custom commands to USB connected printer:

== Print3r: Gcode Console (gconsole) - use CTRL-C or 'exit' or 'quit' to exit
   for valid Gcode see https://reprap.org/wiki/G-code
conf: device /dev/ttyUSB0, connected


  • any valid Gcode line
  • in gconsole/commands reside a few gcode script which simplify handling:
    • homehomexhomeyhomezhxhyhz: homing all or individual axis
    • left <n>right <n> move left or right (X-axis) relatively
    • up <n>down <n> move up or down (Z-axis) relatively
    • forward <n>back <n> move forward or back (Y-axis) relatively
    • x <n>y <n>z <n> move each axis absolutely
    • nozzle <temp> set nozzle temperature
    • bed <temp> set bed temperature
    • off turn everything off (motors, nozzle, bed)
> homex
send <G28 X>
X:0.00 Y:0.00 Z:5.00 E:0.00 Count X:0 Y:0 Z:16000
> right 10
send <G91>
X:0.00 Y:0.00 Z:5.00 E:0.00 Count X:0 Y:0 Z:16000
send <G1 X10>
> _

Download & Install

Visit https://github.com/Spiritdude/Print3r or choose the latest release.

More Information & Details