Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

3mfctl

3mfctl makes a Bambu Studio project 3MF reproducible from Git-managed sources.

A .3mf file is convenient for Bambu Studio, but it is a poor source of truth for a software-style workflow: model geometry, print settings, object placement, filament assignments, and other metadata are bundled into one archive that is difficult to review in Git.

3mfctl splits that project into editable inputs and can build the 3MF again later:

existing project.3mf
        |
        | 3mfctl probe
        v
project.3mf.yaml + assets/*.stl   <-- commit these to Git
        |
        | edit settings / update STL
        | 3mfctl build
        v
project.3mf                       <-- generated artifact

The intended workflow is therefore:

  1. Create the initial print setup in Bambu Studio.
  2. Run 3mfctl probe once to import the existing 3MF.
  3. Treat the generated manifest and referenced STL files as the source of truth.
  4. Review changes to print settings as YAML diffs in Git.
  5. Regenerate the .3mf with 3mfctl build whenever it is needed for slicing or printing.

The generated 3MF no longer needs to be the authoritative file in the repository. It can be treated like any other build artifact.

Quick start: move an existing 3MF into Git

Install 3mfctl:

go install github.com/tingtt/3mfctl@latest

Suppose original.3mf is an existing Bambu Studio project whose print settings you want to preserve.

Import it into a manifest and external STL assets:

mkdir -p print
3mfctl probe \
  -o print/model.3mf.yaml \
  --assets-dir assets \
  original.3mf

Because --assets-dir is relative to the manifest, the result looks roughly like this:

print/
├── model.3mf.yaml
└── assets/
    ├── ... .stl
    └── ... .stl

model.3mf.yaml contains the project topology, object placement, filament assignments, Bambu Studio metadata, and typed project/preset configuration. The STL files contain the mesh geometry referenced by the manifest.

Commit those files:

git add print/model.3mf.yaml print/assets
git commit -m 'Add printable project sources'

At this point, the Git-managed manifest and STL files are the source of truth.

Build a Bambu Studio project from them whenever needed:

mkdir -p dist
3mfctl build -o dist/model.3mf print/model.3mf.yaml

dist/model.3mf is generated from the manifest and STL assets. With the Go toolchain pinned by go.mod, identical manifest and STL bytes produce a byte-identical 3MF. Different Go versions are not covered by the ZIP compression byte guarantee.

Day-to-day workflow

Change model geometry

Update or regenerate the STL file referenced by the manifest, then build again:

3mfctl build -o dist/model.3mf print/model.3mf.yaml

By default, build recalculates STL hashes and atomically refreshes stale hash values in the manifest. This makes an intentional STL update part of the normal Git diff together with any print-setting changes.

If you want CI or another verification step to reject unexpected geometry changes instead, lock the hashes:

3mfctl build \
  -lock-stl-hash \
  -o dist/model.3mf \
  print/model.3mf.yaml

Change print settings

The YAML manifest is the canonical editable representation used by build, so print configuration can be changed and reviewed as text instead of replacing an opaque .3mf file.

For settings that are easier to adjust in Bambu Studio, you can also edit a generated 3MF there and run probe again, then review the resulting manifest diff before committing it. When probe selects an STL filename that already exists, it verifies the geometry and reuses the file; a geometry mismatch is an error and never silently overwrites the existing asset.

Keep generated 3MF files out of the source of truth

A typical project can separate printable sources from build output:

project/
├── model/                 # CAD / OpenSCAD / other model sources
├── print/
│   ├── model.3mf.yaml     # canonical print project
│   └── assets/            # STL inputs consumed by 3mfctl
└── dist/
    └── model.3mf          # generated for Bambu Studio / printing

If STL files are generated reproducibly by the project, they can be produced by the same build workflow before 3mfctl build; the important part is that the manifest references explicit external STL paths rather than hiding geometry inside the authoritative 3MF.

Use as a repository-scoped Go tool

For a project that wants to pin 3mfctl in go.mod instead of relying on a globally installed binary:

go get -tool github.com/tingtt/3mfctl@latest

Then run it through the Go toolchain:

go tool 3mfctl probe -o print/model.3mf.yaml --assets-dir assets original.3mf
go tool 3mfctl build -o dist/model.3mf print/model.3mf.yaml

This works well from go generate, Taskfile, Make, or CI workflows that generate STL files and then assemble the printable 3MF.

Commands

probe

3mfctl probe -o MANIFEST --assets-dir DIR INPUT.3mf

probe handles exactly one input archive. Asset paths in the generated manifest are relative to the manifest. A relative --assets-dir is also interpreted relative to the manifest.

If a selected STL filename already exists, probe verifies its geometry and reuses it. If it does not exist, probe extracts a deterministic binary STL. A geometry mismatch is an error and never overwrites the existing asset.

build

3mfctl build -o OUTPUT.3mf [-lock-stl-hash] MANIFEST

build handles exactly one manifest and requires -o. It strictly decodes and validates the complete manifest and every STL asset before creating the archive.

By default, stale STL hashes are updated in the manifest. -lock-stl-hash instead makes a geometry or triangle-order hash mismatch fail without changing the manifest or output. The output and any updated manifest are written through temporary files.

See docs/manifest.md for the manifest v1 contract, supported archive entries, normalization rules, and geometry matching behavior.

Current limitations

  • ❌ Manual support setting (face-level support painting) is not supported. Ordinary support configuration is preserved, but fine-grained face selection in paint_supports is not.
  • ❌ Painted fuzzy-skin regions and generic per-face properties are not supported (paint_fuzzy_skin and face_property).
  • ❌ 3MF material/property assignments and required extensions other than the Production extension (p) are not supported.
  • ❌ 3MF topologies outside Bambu Studio's component-based project layout are not supported, including inline root meshes and nested components.
  • ❌ Preview images and thumbnails are not round-tripped; probe intentionally omits them.

Unsupported required data causes probe or build to fail instead of silently discarding it.

Development

go test ./...
go vet ./...
go run . probe --help
go run . build --help

About

Make Bambu Studio 3MF projects reproducible and Git-friendly with editable manifests and external STL assets.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages