STL preparation toolkit for resin 3D printing: uniform scaling, bed packing, fill, autopack.
Project description
stlbench
STL preparation toolkit for resin 3D printing.
stlbench takes STL files and prepares them for SLA/DLP printers: automatic support-minimising orientation, uniform scaling to fit the build volume, packing parts onto rectangular print plates, filling the bed with copies, and a flexible job-file pipeline for mixing raw and pre-prepared models. Support generation and hollowing are not performed — use your slicer (Lychee, Chitubox, PrusaSlicer, Elegoo SatelLite, etc.) after export.
Installation
pip install stlbench
Development install
git clone https://github.com/NikitaDmitryuk/stlbench.git
cd stlbench
poetry install --with dev
Quick Start
Run stlbench --help for the command cheatsheet. The most common workflows:
# 1a. Generate a printer profile (edit width_mm / depth_mm / height_mm for your machine)
stlbench config init -o my_printer.toml
# 1b. Or generate a job-file template (includes [pipeline] and [[parts]] sections)
stlbench config job -o job.toml
# 2a. Full pipeline in one command: scale → orient → layout (recommended)
stlbench prepare -i ./parts -o ./plates -c my_printer.toml
# 2b. Mix raw and pre-prepared parts using a job file
stlbench job job.toml -o ./plates
# 3. Or run individual steps manually:
stlbench info -i ./parts -c my_printer.toml # inspect dimensions
stlbench orient -i ./parts -o ./oriented -c my_printer.toml # minimise supports
stlbench scale -i ./oriented -o ./scaled -c my_printer.toml # fit to build volume
stlbench layout -i ./scaled -o ./plates -c my_printer.toml # pack onto plates
# Scale + pack all on one plate (no separate scale/layout steps)
stlbench autopack -i ./parts -o ./packed -c my_printer.toml
# Fill the bed with copies of a single part
stlbench fill -i ./part.stl -o ./filled -c my_printer.toml --scale
No config file? Specify the build volume inline as three numbers (X, Y, Z) in mm:
stlbench prepare -i ./parts -o ./plates -p "153.36,77.76,165"
Commands
prepare — Full pipeline: scale → orient → layout
stlbench prepare -i ./parts -o ./plates -c my_printer.toml
Runs the three preparation steps in the optimal order for resin printing:
- Scale — finds the largest scale factor that fits every part inside the build volume (Z-axis rotation search by default), then applies a uniform scale to all parts.
- Orient — rotates each scaled part to minimise overhanging surface area, constrained so the part still fits the build volume.
- Layout — packs the oriented parts onto the minimum number of plates, distributed as evenly as possible.
Exports one plate_NN.3mf + plate_NN.json manifest per plate.
Key options: --overhang-angle (default 45°), --orient-candidates (default 200),
--gap-mm, --post-fit-scale, --dry-run, --recursive, --resume.
job — Per-part configurable pipeline from a job file
stlbench job job.toml -o ./plates
Runs a flexible pipeline where each part can have its own set of steps. Useful when some models are already oriented and supported (they only need packing) while others need the full scale → orient → layout treatment. All parts end up on the same plates.
Example job.toml:
[printer]
width_mm = 153.36
depth_mm = 77.76
height_mm = 165.0
[scaling]
post_fit_scale = 0.95
[packing]
gap_mm = 2.0
[pipeline]
default_steps = ["scale", "orient", "layout"] # default for parts without explicit steps
[[parts]]
path = "models/gandalf.stl" # uses default_steps
[[parts]]
path = "models/staff.stl"
steps = ["scale", "layout"] # scale but skip orient
[[parts]]
path = "supported/sword.stl"
steps = ["layout"] # already prepared — pack only
Valid step sequences (layout must always be last):
steps |
What happens |
|---|---|
["scale", "orient", "layout"] |
Z-rotation search → global scale → Tweaker-3 orient → pack |
["orient", "scale", "layout"] |
Tweaker-3 orient → scale from oriented AABB → pack |
["scale", "layout"] |
Z-rotation search → global scale → pack |
["orient", "layout"] |
Tweaker-3 orient → pack |
["layout"] |
Pack only (model already prepared) |
Global scale is computed once across all parts that include the scale step, so
they all receive exactly the same scale factor.
Key options: --candidates, --overhang-angle, --rotation-samples,
--grid-step, --dry-run, --verbose.
info — Inspect models (read-only)
stlbench info -i ./parts -c my_printer.toml
Displays a table with AABB dimensions, volume, vertex/face counts, whether each part
fits the bed, maximum scale factor, and how many copies would fit using fill.
No files are written.
scale — Uniform scaling
stlbench scale -i ./parts -o ./scaled -c my_printer.toml
Computes a single scale factor so that every part fits inside the printer build volume. The largest part determines the factor; all parts share the same scale.
By default the model is rotated around the Z axis only (any angle, ~4 096 samples)
— the original face stays on the bed, but the model is turned to find the best fit in
the XY plane. Use --any-rotation to allow full 3D reorientation:
| Flags | Behaviour |
|---|---|
| (default) | Z-axis rotation search — keeps the model face-down, optimises XY footprint |
--any-rotation |
Try all 6 canonical axis permutations; model may be placed on any face |
--any-rotation --maximize |
Full SO(3) random search (4 096 samples × 6 permutations) to maximise scale factor |
--scale N |
Apply an explicit factor N instead of fitting to the printer; printer config becomes optional |
Examples:
# Default: Z-rotation search (model stays face-down)
stlbench scale -i ./parts -o ./scaled -c my_printer.toml
# Allow any face down — useful when models have no pre-placed supports
stlbench scale -i ./parts -o ./scaled -c my_printer.toml --any-rotation
# Full rotation search — maximise scale by trying arbitrary orientations (slow)
stlbench scale -i ./parts -o ./scaled -c my_printer.toml --any-rotation --maximize
# Explicit factor: double every part's size, no printer required
stlbench scale -i ./parts -o ./scaled --scale 2.0
# Shrink to 80% of current size
stlbench scale -i ./parts -o ./scaled --scale 0.8
# Fit to printer, but cap at 1.0 and add a 5% safety margin
stlbench scale -i ./parts -o ./scaled -c my_printer.toml --no-upscale --post-fit-scale 0.95
Key options: --scale N, --any-rotation, --maximize, --no-upscale,
--post-fit-scale, --method sorted|conservative, --dry-run, --suffix, --recursive.
orient — Minimise support structures
stlbench orient -i ./parts -o ./oriented -c my_printer.toml
For each STL file, searches for the rotation that minimises overhanging surface area (faces whose downward angle exceeds the threshold). Uses a two-phase search: discrete evaluation of candidate orientations derived from the model's face normals, followed by Nelder-Mead local refinement. The result is written with the bottom at z = 0.
When --config or --printer is supplied, the search is constrained to orientations
that fit inside the build volume.
Key options: --overhang-angle (default 45°), --candidates (default 200),
--dry-run, --suffix, --recursive.
layout — Pack parts onto plates
stlbench layout -i ./scaled -o ./plates -c my_printer.toml
Arranges already-scaled STL files onto rectangular print plates. Exports
plate_NN.3mf + plate_NN.json with part positions. Multiple plates are created
if all parts do not fit on one.
Key options: --dry-run, --gap-mm, --algorithm, --any-rotation.
autopack — Scale + layout in one step
stlbench autopack -i ./parts -o ./packed -c my_printer.toml
Binary-searches for the maximum scale factor at which all parts fit onto a single
plate simultaneously. Combines scale and layout into one step with the goal of
keeping everything on one plate.
Key options: --orient/--no-orient, --overhang-angle, --any-rotation, --dry-run,
--gap-mm, --post-fit-scale.
fill — Maximum copies of one part
stlbench fill -i ./part.stl -o ./filled -c my_printer.toml
Packs as many copies of a single STL as possible onto one plate. Add --scale to
fit the part to the bed first, --orient to minimise supports before filling.
Key options: --scale/--no-scale, --orient/--no-orient, --overhang-angle,
--any-rotation, --dry-run, --gap-mm.
config init — Create a printer profile
stlbench config init -o my_printer.toml
Writes a printer profile TOML with [printer], [scaling], and [packing] sections.
Use --stdout to print without saving, or --force to overwrite.
config job — Create a job-file template
stlbench config job -o job.toml
Writes a job-file template with all sections pre-filled: [printer], [scaling],
[packing], [pipeline], and two commented-out [[parts]] examples. Edit the file,
fill in your STL paths, then run stlbench job job.toml -o ./plates.
Configuration
Printer profiles are TOML files. Generate a template with stlbench config init or
see configs/mars5_ultra.toml for a complete example
(ELEGOO Mars 5 Ultra).
| Section | Keys | Purpose |
|---|---|---|
[printer] |
name, width_mm, depth_mm, height_mm |
Build volume (required) |
[scaling] |
post_fit_scale (>0), any_rotation, maximize |
Scale behaviour (see scale command) |
[packing] |
gap_mm |
Surface-to-surface gap between parts |
[pipeline] |
default_steps |
Default step list for job command |
[[parts]] |
path, steps |
Per-part entries for job command |
Output Files
All commands that write files produce 3MF output (except scale and orient,
which write scaled/rotated STL files).
| Command | Output |
|---|---|
prepare |
plate_NN.3mf, plate_NN.json per plate |
job |
plate_NN.3mf, plate_NN.json per plate |
scale |
*.stl (one per input part, in-place scaled) |
orient |
*.stl (one per input part, rotated) |
layout |
plate_NN.3mf, plate_NN.json per plate |
autopack |
plate_NN.3mf, plate_NN.json per plate |
fill |
fill_plate.3mf, fill_plate.json |
info |
Console output only |
The 3MF files use only the core 3MF 2015/02 namespace and are compatible with Elegoo SatelLite, Chitubox, Lychee, and PrusaSlicer.
Examples
See examples/README.md for a step-by-step walkthrough
using the included Gandalf model (3 parts tracked via Git LFS).
Package Structure
| Module | Purpose |
|---|---|
stlbench.cli |
Typer CLI — all commands and argument parsing |
stlbench.config |
Pydantic schema (AppSettings, PartSpec) + TOML loader |
stlbench.core |
Scale factor computation, overhang analysis, orientation search |
stlbench.packing |
2D polygon packing onto plates (Shapely + custom grid) |
stlbench.export |
3MF and JSON manifest writers |
stlbench.pipeline |
Command runners (run_prepare, run_job, run_scale, etc.) |
Limitations
- Non-manifold meshes may produce incorrect AABB or scale results. Repair first with a tool such as Meshmixer or Microsoft 3D Builder.
- Supports and hollowing are not generated — open the exported 3MF in your slicer.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stlbench-1.1.6.tar.gz.
File metadata
- Download URL: stlbench-1.1.6.tar.gz
- Upload date:
- Size: 52.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11b9996707ae33bd01458d155253e99aae4bc7b88d1baa7b33a7ac3a229a6138
|
|
| MD5 |
9773b78eb1bc1e671311eefd1c7f94ee
|
|
| BLAKE2b-256 |
2dd17df275b2e6369d38c8262cdf6de570abe4258228fddd3100d630d84f50ac
|
Provenance
The following attestation bundles were made for stlbench-1.1.6.tar.gz:
Publisher:
publish.yml on NikitaDmitryuk/stlbench
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stlbench-1.1.6.tar.gz -
Subject digest:
11b9996707ae33bd01458d155253e99aae4bc7b88d1baa7b33a7ac3a229a6138 - Sigstore transparency entry: 1333056933
- Sigstore integration time:
-
Permalink:
NikitaDmitryuk/stlbench@8714ec733b7ed100e236458c7d6daf80a2dc34c3 -
Branch / Tag:
refs/tags/v1.1.6 - Owner: https://github.com/NikitaDmitryuk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8714ec733b7ed100e236458c7d6daf80a2dc34c3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file stlbench-1.1.6-py3-none-any.whl.
File metadata
- Download URL: stlbench-1.1.6-py3-none-any.whl
- Upload date:
- Size: 68.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e20905ff82599b89f60caf14efeb1b21dcad13294cddbdb8be8aedd3622ced27
|
|
| MD5 |
facbe3b0cddabaef9094f279ec403e97
|
|
| BLAKE2b-256 |
042c46431bd2b98aab7aa705d80d9dc877f68017bfec05de3a49e94bd6dd77ef
|
Provenance
The following attestation bundles were made for stlbench-1.1.6-py3-none-any.whl:
Publisher:
publish.yml on NikitaDmitryuk/stlbench
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stlbench-1.1.6-py3-none-any.whl -
Subject digest:
e20905ff82599b89f60caf14efeb1b21dcad13294cddbdb8be8aedd3622ced27 - Sigstore transparency entry: 1333056985
- Sigstore integration time:
-
Permalink:
NikitaDmitryuk/stlbench@8714ec733b7ed100e236458c7d6daf80a2dc34c3 -
Branch / Tag:
refs/tags/v1.1.6 - Owner: https://github.com/NikitaDmitryuk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8714ec733b7ed100e236458c7d6daf80a2dc34c3 -
Trigger Event:
push
-
Statement type: