Headless OrcaSlicer Setup for Snapmaker U1
Use OrcaSlicer from the command line to slice STL and 3MF files for a Snapmaker U1 with no GUI. This guide covers the correct upstream build, the three-profile load order, Linux and Windows setup, profile-inheritance pitfalls, orientation review, thumbnail injection, and G-code validation.
Headless slicing setup (no GUI / scripted)
Use this if you’re slicing from CLI in a container, CI pipeline, or agent workflow.
Use upstream OrcaSlicer, not the Snapmaker fork
Important: use upstream OrcaSlicer v2.4.0+, not Snapmaker’s fork. Snapmaker upstreamed the U1 vendor profile into upstream OrcaSlicer 2.4.0, so it has full U1 support — and its CLI is the better-supported headless path. The Snapmaker fork’s Windows CLI has been observed to segfault when slicing with these profiles (verified
snapmaker-orca v2.3.4Windows can exit code-1073741819on some models).
Install — Linux (extracted AppImage)
# Download upstream OrcaSlicer Linux AppImage
wget https://github.com/OrcaSlicer/OrcaSlicer/releases/download/v2.4.0/OrcaSlicer_Linux_AppImage_Ubuntu2404_V2.4.0.AppImage \
-O ~/orcaslicer.AppImage
chmod +x ~/orcaslicer.AppImage
# Extract instead of mounting (containers without FUSE)
mkdir -p ~/orcaslicer-install && cd ~/orcaslicer-install
~/orcaslicer.AppImage --appimage-extract
# Creates ./squashfs-root/
# Some minimal distros are missing GUI/runtime libs Orca expects.
# If you hit "libGL.so.1 not found" or similar:
mkdir local-libs && cd local-libs
apt-get download libgl1 libegl1 libxkbcommon0 libwayland-client0 libnss3 \
libasound2 libgtk-3-0 libdbus-1-3 libsecret-1-0
for d in *.deb; do dpkg-deb -x "$d" .; done
Install — Windows (portable zip, no installer needed)
# Download upstream OrcaSlicer Windows portable
Invoke-WebRequest -Uri https://github.com/OrcaSlicer/OrcaSlicer/releases/download/v2.4.0/OrcaSlicer_Windows_V2.4.0_portable.zip `
-OutFile $env:TEMP\OrcaSlicer.zip
Expand-Archive $env:TEMP\OrcaSlicer.zip -DestinationPath $env:TEMP\orca240
# The CLI binary lives at $env:TEMP\orca240\orca-slicer.exe
Slice a single STL — the 3-profile chain
Headless slicing needs three profiles in a specific load order:
- Machine — the printer definition (this repo bundles a flattened standalone copy)
- Process — layer height, walls, infill, supports
- Filament — material, temps, retraction
Pass each profile via its own
--load-settingsflag (not one flag with semicolon-separated paths). Both forms are documented in OrcaSlicer, but the dual-flag form is the one verified-working in our test runs (Hermes Windows) and avoids quoting foot-guns on PowerShell.
# Linux
ORCA=$HOME/orcaslicer-install
PROFILES=$(pwd)/profiles
LD_LIBRARY_PATH="$ORCA/local-libs/usr/lib/x86_64-linux-gnu:$ORCA/squashfs-root/usr/lib:$ORCA/squashfs-root/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH" \
$ORCA/squashfs-root/bin/orca-slicer \
--load-settings "$PROFILES/machine/snapmaker_u1_0_4_nozzle.json" \
--load-settings "$PROFILES/community_merged_016_optimal_u1_textured_pei.json" \
--load-filaments "$PROFILES/community_generic_petg_u1_textured_pei.json" \
--outputdir ./output \
--slice 0 \
my_model.stl
# Windows (PowerShell)
& "$env:TEMP\orca240\orca-slicer.exe" `
--load-settings "profiles\machine\snapmaker_u1_0_4_nozzle.json" `
--load-settings "profiles\community_merged_016_optimal_u1_textured_pei.json" `
--load-filaments "profiles\community_generic_petg_u1_textured_pei.json" `
--outputdir .\output `
--slice 0 `
my_model.stl
Sliced G-code lands in ./output/plate_1.gcode.
Why the bundled machine profile? Upstream Orca’s bundled U1 profile inherits from
fdm_U1→fdm_toolchanger→fdm_klipper. Loading the bundled vendor copy via CLI requires Orca to find every parent in its install resources, which is fragile across platforms. The repo’sprofiles/machine/snapmaker_u1_0_4_nozzle.jsonis fully flattened — every inherited field merged into one standalone file. Headless CLI sees one file, gets the complete machine definition, no resolution magic needed. Derived from upstream OrcaSlicer’sSnapmaker/machine/vendor profiles (AGPL-3.0, contributed by Snapmaker).
Headless profile-loading pitfall (READ THIS)
OrcaSlicer’s bundled Snapmaker process profiles do not always resolve inheritance correctly via CLI. Symptoms seen in testing:
filament_settings_idsays PETG butfilament_typebecomes PLA → wrong temps- Layer-height preset of 0.16 produces G-code with
layer_height = 0.2 - Bed/nozzle temps default to PLA-safe values regardless of selected filament
Workaround: use profiles whose inheritance chain CLI can resolve. Three good options today:
tools/extract_profiles_from_printer.pywrites flat process JSONs from your successful prints (no inheritance) — physics-validated AND CLI-safe by construction. Best default.tools/fetch_snapmaker_profiles.pypulls Snapmaker’s upstream stock — CLI resolves these against the bundled OrcaSlicer install when the install matches the stock branch.examples/profiles/community_merged_*(inexamples/) is the legacy flat-profile shape; if you’re handwriting your own, follow that pattern. The_overridevariants only work in the GUI where Orca resolves the official base profile. The same flatness logic applies to the bundled machine profile above.
Pre-print orientation review
Before you slice, ask the question every operator forgets: is this the right orientation, and where will it need supports? The orientation renderer gives you a 4-panel image showing isometric / front / side / top views with all downward-facing triangles highlighted in orange — those are the faces a slicer will warn about.
pip install Pillow numpy # one-time (same deps as the thumbnail tool)
python3 tools/render_stl_orientation.py model.stl \
--out orientation.png \
--title "Orbital sander vacuum attachment"
Output is a single PNG with header text (bounding-box dims, Z range, count
of overhang triangles) and the 4 views. Tunable via --overhang-threshold
if your slicer/material is more or less paranoid than the default (-0.3 ≈
17° below horizontal).
Add a Snapmaker-app preview thumbnail
OrcaSlicer’s CLI path doesn’t render thumbnails (GUI-only — verified with --debug 5, no GL/xvfb workaround helps). Without them, the Snapmaker app shows a generic icon for every print. Use the included tool to splice PrusaSlicer/Orca-format thumbnail blocks into the G-code post-slice:
pip install Pillow numpy # one-time
python3 tools/gcode_inject_thumbnail.py \
--stl my_model.stl --gcode output/plate_1.gcode \
--sizes 48x48,300x300 --in-place
Runs an isometric projection of the STL through PIL (Lambertian-shaded triangles, painter’s algorithm), base64-encodes the PNGs, and splices ; thumbnail begin … ; thumbnail end blocks into the G-code header. Idempotent — re-running replaces existing blocks, not stacks them. Moonraker + Snapmaker app parse them as standard previews.
Validate G-code before upload
grep -E '^; (filament_type|layer_height|first_layer_temperature|bed_temperature) ' output/plate_1.gcode
Expected output for the merged 0.16 Optimal PETG profile:
; filament_type = PETG
; layer_height = 0.16
; first_layer_temperature = 255
; bed_temperature = 80
If any of those are wrong, the CLI didn’t load your profiles correctly — fix before uploading.