Skip to content

Latest commit

Β 

History

30 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GCode Translator

A powerful Python-based tool for reading, interpreting, and converting standard and binary G-code (.bgcode) files.
It can optionally integrate a native C++ binary (bgcode) β€” shipped as an opt-in, platform-specific companion package (see Installation) β€” and uses web scraping (3) to retrieve command documentation from Marlin firmware resources or a local (1) / package (2) marlin_mapping.json file.

Using this order (1) > (2) > (3) in default use() / CLI mode!


πŸš€ Features

  • βœ… Translate raw G-code lines into human-readable explanations
  • βœ… Supports .gcode, .bgcode, and .gx formats
  • βœ… Integrates with native C++ converter (bgcode) for decoding binary formats
  • βœ… Able to automatically scrapes G/M-code documentation from Marlin's official site or use a local one
  • βœ… Supports embedded thumbnails (base64 or binary)
  • βœ… CLI access via gcode-translator command

πŸ§ͺ Installation

πŸ›  For local development:

git clone https://github.com/herrdivad/GCode_Translator
cd GCode_Translator/
pip install -e .                          # base package only (binary-free)

pip install -e . installs only the binary-free base package β€” no bgcode companion. To also work on .bgcode conversion locally, add the companion in one of two ways:

# a) via the extra β€” resolves the companion from the git URL in pyproject.toml (needs the
#    branch pushed to GitHub); the base package stays editable, the companion does not:
pip install -e ".[linux]"

# b) fully local & editable β€” install the companion straight from its folder, so edits to
#    the companion package take effect without a push (recommended while developing it):
pip install -e ./companion/bgcode-linux

πŸ“¦ Install directly via pip:

The base package is binary-free (MIT only) and handles .gcode and .gx files:

pip install git+https://github.com/herrdivad/GCode_Translator

To also convert Prusa .bgcode files, install the platform's bgcode companion binary via an extra. The companion is AGPL-3.0 and is only pulled in when you ask for it:

# Linux (available):
pip install "gcode-translator[linux] @ git+https://github.com/herrdivad/GCode_Translator.git"

# Windows (available) β€” self-contained /MT build, needs no VC++ Redistributable:
pip install "gcode-translator[windows] @ git+https://github.com/herrdivad/GCode_Translator.git"

# macOS: planned β€” the [macos] extra is reserved for when its companion binary
# is added under companion/.

Each extra is guarded by a platform marker, so requesting the "wrong" one for your OS is a harmless no-op. Without a companion installed, .bgcode conversion fails with a clear message telling you which extra to install; .gcode / .gx handling is unaffected.

Platform Support

Platform Extra Status Install (pinned to the current release)
Linux [linux] βœ… available pip install "gcode-translator[linux] @ git+https://github.com/herrdivad/GCode_Translator.git@v1.2.0"
Windows [windows] βœ… available pip install "gcode-translator[windows] @ git+https://github.com/herrdivad/GCode_Translator.git@v1.2.0"
macOS [macos] 🚧 planned not yet available β€” install the base package only: pip install "git+https://github.com/herrdivad/GCode_Translator.git@v1.2.0"
any (none) βœ… always base package, binary-free, .gcode / .gx only

The [macos] extra already exists in pyproject.toml but points at a companion directory that has not been added yet, so requesting it on macOS fails at install time. Until the macOS binary ships, use the base package there; everything except .bgcode decoding works.

Dropping the @v1.2.0 ref installs whatever is currently on master β€” convenient for "give me the latest", but not reproducible. For anything you want to be able to rebuild later, keep the tag. See RELEASING.md for the release workflow and CHANGELOG.md for what changed between versions.


βœ… Tests

pip install -e ".[dev]"      # installs pytest
pytest                       # full suite (~10s)
pytest -m "not slow"         # skip the large-file integration test (~7s)

The suite (tests/) covers command translation, metadata extraction, dict aggregation, thumbnail/.gx image handling, and the use() library API. Unit tests use inline G-code snippets; integration tests run real files from exFiles/ end-to-end (PrusaSlicer and AnycubicSlicer), so the metadata/command behaviour is checked against actual slicer output.


πŸ–₯️ CLI Usage

After installation, use the command:

gcode-translator path/to/your/file.gcode

It processes the G-code file and outputs interpreted descriptions line by line into a file named output.txt (overwrite!).


πŸ“¦ Dependencies

Required:

  • platformdirs (MIT license)
    • locates the per-user cache directory. The G/M-code mapping ships read-only inside the package; a freshly scraped mapping is cached under platformdirs.user_cache_dir("gcode-translator") (e.g. ~/.cache/gcode-translator/ on Linux) instead of being written into the installed package.

Optional β€” only for re-scraping the Marlin mapping (pip install gcode-translator[scrape]):

The translator works fully offline using the bundled mapping; the [scrape] extras are only needed when you explicitly fetch a fresh mapping from marlinfw.org. Without them, the scraping path raises a clear error telling you to install the extra.

bgcode binary β€” licensing & source

The bgcode binaries are not part of the MIT base package. They ship as separate, opt-in, platform-specific companion packages, installed only via the matching extra (see Installation):

Once installed, the binary is used automatically to convert Prusa .bgcode files. It is a separately compiled build of the Prusa3D libbgcode project, which is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). The binaries are therefore not covered by this project's MIT license; when using or redistributing them you must comply with the AGPL-3.0. Each companion ships the full AGPL-3.0 license text plus its own Corresponding Source record (commit, build environment, and β€” for Windows β€” the build-script patch), e.g. companion/bgcode-linux/LICENSE.AGPL-3.0.txt. The Linux build is a clean upstream checkout; the Windows build uses the unmodified libbgcode source with two documented patches to the dependency build scripts only (static /MT runtime + a CMake policy floor), recorded in the Windows companion's CORRESPONDING_SOURCE.md.

bgcode is invoked only as a separate subprocess (arm's-length communication via command-line arguments and files). Under the FSF's GPL FAQ on mere aggregation this does not create a combined work, so the MIT-licensed Python code keeps its MIT license. Distributing the AGPL binary, however, carries the AGPL's own obligations (see below).

Corresponding Source (AGPL-3.0 Β§6). The shipped binary corresponds exactly to this public revision (verified by hash):

Field Value
Binary SHA-256 15c6fe4d54defc4d375524452f433ff3f4e7a10e3b23f89c14096cd5484c1f4b
Repository https://github.com/prusa3d/libbgcode
Version libbgcode 0.2.0
Commit 5041c093b33e2748e76d6b326f2251310823f3df (branch main, 2025-02-20)
Local modifications none (clean upstream checkout)

Build environment used to produce the shipped binary:

Field Value
Target ELF 64-bit x86-64, dynamically linked, GNU/Linux
Toolchain GNU g++ 11.4.0
Build system CMake 3.22.1
Configure/build CMake preset default β†’ CMAKE_BUILD_TYPE=Release, deps preset default

Reproduce from a clean checkout:

git clone https://github.com/prusa3d/libbgcode
cd libbgcode
git checkout 5041c093b33e2748e76d6b326f2251310823f3df
cmake --preset default        # configures deps + project (Release)
cmake --build --preset default
# resulting tool: build-default/src/LibBGCode/cmd/bgcode

Written Offer. The Corresponding Source for the exact version above is publicly available at the commit link. In addition, for at least three (3) years from the date of distribution, the author will provide, on request, a copy of the complete Corresponding Source of this binary. Contact: david.herrmann@kit.edu

The full AGPL-3.0 compliance statement is also recorded in LICENSE.


🧠 Python API Usage

You can also use it programmatically. use() returns the aggregated result ([g_dict, m_dict, other_dict]) and, when called as a library, is side-effect free (no files written, no stdout output):

from gcode_translator.GCode_Translator import use

# Library mode: returns data, writes nothing.
g_codes, m_codes, other = use("your_file.gcode")

# Opt in to file output explicitly if you want it:
result = use("your_file.gcode", output_txt_path="output.txt", preview_path="preview.png")

# Get the embedded thumbnail(s) as raw bytes, without writing any file:
dicts, previews = use("your_file.gcode", return_preview=True)
for img in previews:          # a file may contain several thumbnails
    ...                       # e.g. hand the bytes to a converter / PIL.Image

The result is [g_dict, m_dict, other_dict]: G-commands, M-commands, and everything else. Slicer metadata written as ; key = value or ; key: value comments (e.g. temperature, filament_type, nozzle_diameter) is collected into other_dict, so the converter can read print settings that have no direct G/M-command equivalent.

Aggregation modes

A command (or setting) usually appears many times. The aggregation argument of use() controls how those repeated values are reduced. Given, for example:

M104 S210
M104 S210
M104 S230
G1 X10 Y5
G1 X20 Y2
Mode M104 value G1 (movement) value Notes
"compact" (default) ["S210", "S230"] {"X": [10.0, 20.0], "Y": [2.0, 5.0]} Unique values; movement commands (G0–G3) become per-axis [min, max] ranges. A single unique value is returned as a scalar ("S210").
"count" {"S210": 2, "S230": 1} {"X10 Y5": 1, "X20 Y2": 1} {value: occurrences} for every command, movement included.
"full" ["S210", "S210", "S230"] ["X10 Y5", "X20 Y2"] Every occurrence, in order, duplicates kept (the original behaviour).
result = use("your_file.gcode", aggregation="count")   # "compact" | "count" | "full"

Why this matters: a high-frequency command can otherwise explode the result β€” in one real file SET_VELOCITY_LIMIT occurred 59,825 times with only 2 distinct values, so "compact"/"count" reduce that single entry from 59,825 items to 2. "compact" is the default because it is the most readable; "count" keeps frequencies; "full" keeps raw data. An unknown mode raises ValueError.

The CLI (gcode-translator <file>) keeps the old behavior and writes output.txt and preview.png into the current directory.

Intended use in other projects


πŸ“ Project Structure

.
β”œβ”€β”€ gcode_translator/                # the installable base package (MIT, binary-free)
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ GCode_Translator.py          # CLI entry point, use() API and translation logic
β”‚   β”œβ”€β”€ Binary_GCode_Translator.py   # binary decoding (.bgcode via companion binary, .gx preview)
β”‚   β”œβ”€β”€ GCode_Mapping.py             # G/M code mapping via web scraping (Marlin)
β”‚   β”œβ”€β”€ helper.py                    # parser and helper functions
β”‚   └── marlin_mapping.json          # bundled mapping for offline use (no Internet needed)
β”œβ”€β”€ companion/                       # opt-in, platform-specific binary packages (installed via extras)
β”‚   β”œβ”€β”€ bgcode-linux/                # AGPL-3.0 Linux bgcode binary + its own pyproject/README/license
β”‚   β”‚   β”œβ”€β”€ pyproject.toml           # package "gcode-translator-bgcode-linux"
β”‚   β”‚   β”œβ”€β”€ README.md                # AGPL-3.0 Corresponding Source record
β”‚   β”‚   β”œβ”€β”€ LICENSE.AGPL-3.0.txt     # full AGPL-3.0 text, shipped with the binary
β”‚   β”‚   └── gcode_translator_bgcode_linux/
β”‚   β”‚       β”œβ”€β”€ __init__.py          # exposes binary_path()
β”‚   β”‚       └── bgcode               # native C++ executable (AGPL-3.0, unmodified)
β”‚   └── bgcode-windows/              # AGPL-3.0 Windows bgcode.exe (static /MT, no VC++ redist needed)
β”‚       β”œβ”€β”€ pyproject.toml           # package "gcode-translator-bgcode-windows"
β”‚       β”œβ”€β”€ README.md                # AGPL-3.0 overview + build/patch summary
β”‚       β”œβ”€β”€ LICENSE.AGPL-3.0.txt     # full AGPL-3.0 text, shipped with the binary
β”‚       └── gcode_translator_bgcode_windows/
β”‚           β”œβ”€β”€ __init__.py          # exposes binary_path()
β”‚           β”œβ”€β”€ bgcode.exe           # native build (AGPL-3.0; source unmodified, build scripts patched)
β”‚           β”œβ”€β”€ CORRESPONDING_SOURCE.md  # AGPL-3.0 Β§6 record (shipped in the wheel)
β”‚           └── *.patch              # dependency build-script patch (part of Corresponding Source)
β”œβ”€β”€ tests/                           # pytest suite (run: pytest)
β”‚   β”œβ”€β”€ conftest.py                  # shared fixtures / sample-file paths
β”‚   β”œβ”€β”€ test_use.py                  # end-to-end use() API tests
β”‚   β”œβ”€β”€ test_binary.py               # .bgcode / .gx binary handling
β”‚   β”œβ”€β”€ test_mapping.py              # mapping / scraper tests
β”‚   β”œβ”€β”€ test_aggregation.py          # value-aggregation modes
β”‚   β”œβ”€β”€ test_explain_line.py         # single-line explanation
β”‚   β”œβ”€β”€ test_helper.py               # helper-function tests
β”‚   └── test_integration.py          # full real-file integration tests (slicers)
β”œβ”€β”€ exFiles/                         # real-world sample G-code files used by the tests (empty on GitHub due to rights issues)
β”œβ”€β”€ LICENSE                          # project MIT license + bgcode AGPL-3.0 compliance notice
β”œβ”€β”€ README.md
└── pyproject.toml                   # build config, dependencies, package data

🀝 Contributing

Contributions, suggestions, and bug reports are welcome.
Please open an issue or a pull request.


πŸͺͺ License

MIT License – see LICENSE.


πŸ‘€ Author

David Herrmann
david.herrmann@kit.edu

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages