Turn build123d models into OrcaSlicer project (.3mf) files with per-object settings
Project description
orca123d
Project to help when working with build123d models in OrcaSlicer. Generate .3mf files with geometry plus per-object and per-part slicer settings and painted regions — directly from Python.
from build123d import Box, Cylinder, Pos
from orca123d import Project, PrintSettings
# Project is just a convenient wrapper around the 3MF structure: objects, parts, settings, and painted regions.
proj = Project()
# A single-solid object with a per-object override.
proj.add_object(Box(20, 20, 10), name="Base",
settings=PrintSettings(wall_loops=4, sparse_infill_density="20%"))
# A two-part object: body + pin, each on its own extruder. Relative layout in
# build123d coords is preserved on save.
tag = proj.add_object(name="Two Color Tag")
tag.add_part(Pos(0, 30, 0) * Box(30, 12, 3), name="Body", extruder=1)
tag.add_part(Pos(10, 30, 1.5) * Cylinder(3, 4), name="Pin", extruder=2,
settings=PrintSettings(sparse_infill_density="100%"))
proj.save("basic.3mf") # open in OrcaSlicer
What it does
orca123d writes model-only projects: geometry and per-object/per-part settings in Metadata/model_settings.config, with no project_settings.config. OrcaSlicer opens these using whatever printer / filament / print presets you currently have active, and overlays the settings shipped in the file. So you keep choosing the machine and filament in OrcaSlicer, while the model brings its own structure and overrides.
Features
- Objects and parts — a
Projectholds objects; each object is one or more parts ("volumes" in OrcaSlicer). Parts carry an extruder assignment and asubtype(NORMAL,NEGATIVEto carve material away,MODIFIERto apply settings to an overlapping region,SUPPORT_ENFORCER,SUPPORT_BLOCKER).add_object(shape, subtype=…)sets it for a single-part object;add_part(shape, subtype=…)for each volume. - Typed print settings —
PrintSettingsis a pydantic model generated from OrcaSlicer's own definitions, covering the slicer's Print tab. Every field is optional, so an instance is a sparse set of overrides; values are validated/coerced to OrcaSlicer's string form, and unknown keys pass through. Attach settings per object or per part. - Print layout vs. assembly view — objects keep their build123d coordinates as the assembled arrangement (OrcaSlicer's Assembly View); an optional per-object
print_locationlays them out differently for printing. OrcaSlicer auto-centers the whole group on a single plate, so this sets the relative print layout, not absolute bed coordinates (model-only files import onto one plate — they can't split objects across plates). - Seam painting —
part.paint_seam(region, ...)biases (or blocks) the seam using build123d geometry as the selector: a whole face, a 2D sketch on a face, an edge/wire (paint within N mm), or a solid (paint where the surface lies inside it). - Fuzzy-skin painting —
part.paint_fuzzy_skin(region, ...)enables/disables fuzzy skin over the same kinds of regions. - Project info —
Project(info=ProjectInfo(...))attaches design metadata (title,designer,description,copyright,license) written as<model>metadata, which OrcaSlicer surfaces in its Project / Auxiliaries panels.licensetakes aLicensemember (the CC options) or a raw string; any other 3MF metadata key can be passed as an extra keyword and is written verbatim. - Preview —
project.to_compound()builds a build123dCompoundmirroring the project tree (objects → parts). Passlayout="print"to preview the bed layout (print locations applied, group bed-centered) instead of the default"assembly"view. Hand it toocp_vscode.show()to preview in the OCP CAD Viewer VS Code extension, or to build123d's exporters.
Install
Requires Python ≥ 3.13. Using uv:
uv sync # core
uv sync --extra dev # + pytest and type stubs
uv sync --extra preview # + ocp_vscode for previewing Project.to_compound()
Usage by feature
Multi-part objects and per-part settings
from orca123d import PartSubtype, PrintSettings
obj = proj.add_object(name="Bracket")
obj.add_part(body, name="Body")
obj.add_part(rib, name="Rib")
obj.add_part(core, name="Dense core", subtype=PartSubtype.MODIFIER,
settings=PrintSettings(sparse_infill_density="100%")) # 100% infill where it overlaps
obj.add_part(cut, name="Pocket", subtype=PartSubtype.NEGATIVE) # carves material away
Project info
from orca123d import License, Project, ProjectInfo
proj = Project(info=ProjectInfo(
title="Two Color Tag",
designer="Jas",
description="A two-part name tag.",
license=License.CC_BY_SA, # or a raw string
Origin="MakerWorld", # any other 3MF metadata key, written verbatim
))
Print layout vs. assembly view
from build123d import Box, Pos
# Base prints where it's designed; the lid is moved aside for printing, but the
# Assembly View still shows it seated on the base.
proj.add_object(Box(40, 40, 10), name="Base")
proj.add_object(Pos(0, 0, 6.5) * Box(40, 40, 3), name="Lid",
print_location=Pos(50, 0, 0))
proj.to_compound(layout="assembly") # preview the assembled product
proj.to_compound(layout="print") # preview the print bed (spread, centered)
Model-only files always import onto a single, auto-centered plate, so
print_locationcontrols the relative bed layout (not absolute coordinates), and objects can't be split across multiple plates from a model-only file.
Seam / fuzzy-skin painting
from build123d import Axis, Box
from orca123d import EnforcerBlockerType
box = Box(20, 20, 10)
part = proj.add_object(box, name="Box").parts[0]
# Pin the seam to a vertical corner edge (paint within 1.5 mm of it).
corner = box.edges().filter_by(Axis.Z).sort_by(Axis.X)[-1]
part.paint_seam(corner, mode=EnforcerBlockerType.ENFORCER, within=1.5)
Examples
Runnable scripts live in examples/; each writes a .3mf to open in OrcaSlicer:
| Example | Shows |
|---|---|
examples/basic.py |
objects, multi-part volumes, per-object/part settings |
examples/print_layout.py |
assembled layout vs. print-bed layout (print_location) |
examples/seam_paint.py |
every seam-paint region type (face / sketch / edge / solid) |
examples/fuzzy_skin_paint.py |
fuzzy-skin painting region types |
uv run python examples/basic.py
Development
uv run pytest # tests live in tests/
uv run ruff check # lint (2-space indent)
PrintSettings and its enums are generated from src/orca123d/_proto/print.proto. Regenerate with:
uv run python -m orca123d._proto.codegen
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 orca123d-0.1.1.tar.gz.
File metadata
- Download URL: orca123d-0.1.1.tar.gz
- Upload date:
- Size: 92.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8f39cbd424d76524d22684cff3e93a265e787cdfd34f8584679ec241783f447
|
|
| MD5 |
db08814dc38077adc10bb2f92de26387
|
|
| BLAKE2b-256 |
3fcc551cb91af9bb037431600a18508cee8cefb5771ce1e17fc1107e7a8ab9fa
|
Provenance
The following attestation bundles were made for orca123d-0.1.1.tar.gz:
Publisher:
publish.yml on jsmnbom/orca123d
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
orca123d-0.1.1.tar.gz -
Subject digest:
f8f39cbd424d76524d22684cff3e93a265e787cdfd34f8584679ec241783f447 - Sigstore transparency entry: 2088948200
- Sigstore integration time:
-
Permalink:
jsmnbom/orca123d@a79c4706049d4d0d1afb6f00d23f82eac62ed70c -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/jsmnbom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a79c4706049d4d0d1afb6f00d23f82eac62ed70c -
Trigger Event:
release
-
Statement type:
File details
Details for the file orca123d-0.1.1-py3-none-any.whl.
File metadata
- Download URL: orca123d-0.1.1-py3-none-any.whl
- Upload date:
- Size: 99.4 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 |
a64b9cbcdfea63a1f8b88074b91a418c4ef438eab892bbfd3ad3255efc6c36c8
|
|
| MD5 |
86d82d2333356a832ac7dd315dcb4796
|
|
| BLAKE2b-256 |
107fa6177407e7ab76ff0732fff3f553562c8cabc84291287a2f475b7391be54
|
Provenance
The following attestation bundles were made for orca123d-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on jsmnbom/orca123d
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
orca123d-0.1.1-py3-none-any.whl -
Subject digest:
a64b9cbcdfea63a1f8b88074b91a418c4ef438eab892bbfd3ad3255efc6c36c8 - Sigstore transparency entry: 2088948460
- Sigstore integration time:
-
Permalink:
jsmnbom/orca123d@a79c4706049d4d0d1afb6f00d23f82eac62ed70c -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/jsmnbom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a79c4706049d4d0d1afb6f00d23f82eac62ed70c -
Trigger Event:
release
-
Statement type: