# Changelog
All notable changes to this project are documented in this file.
# 1.0.4 - 2026-09-29
# Changed
- Documentation only: the README's Documentation list links each page on the documentation site, so readers on GitHub and PyPI land there. The code is the same as 1.0.3.
# 1.0.3 - 2026-09-29
# Changed
- Documentation only: the README becomes a short entrance to the documentation
site at https://offerrall.github.io/pygrbl-build/, and
docs/overview.mdholds the introduction: the algorithms, speed, lazy output and pairing with pygrbl-streamer.docs/output.mdmerges into the overview, without the hand-kept list of public names. - New
docs/limitations.mdgathers what each algorithm does not do and the platforms with prebuilt wheels. The previous README said a C compiler was always required; it is needed only where no wheel exists. RELEASING.mdmoves todocs/releasing.md.- Every example imports what it needs; the Bounds and framing example was
missing
svg_gcodeandSvgProfile. The deadpygrbl-serverlink is gone. pyproject.toml:[project.urls]with the documentation site, repository, issues and changelog; a Python 3.14 classifier, matching the wheels; a shorter description.- The code is the same as 1.0.2.
# 1.0.2 - 2026-09-29
# Changed
- Metadata only: the distribution name is spelled
pygrbl-build, PyPI's canonical form, inpyproject.tomland the docs.pip install pygrbl-buildandimport pygrbl_buildare unchanged. The code is the same as 1.0.1, apart from the version in the G-code header (; pygrbl_build v1.0.2).
# 1.0.1 - 2026-09-29
# Changed
- Documentation only: the README keeps an overview and a short example, the
guides move to
docs/(raster, vector, bounds and framing, output), and the release notes for maintainers move toRELEASING.md. The README title no longer carries the version. The code is the same as 1.0.0.
# 1.0.0 - 2026-09-22
# Added
- Jarvis raster engraving (
jarvis_gcode+JarvisProfile): converts color or grayscale images to a 1-bit dot pattern using the Jarvis-Judice-Ninke error-diffusion kernel in C, then emits horizontal raster G-code through the existing native engine. Supports image paths, encoded bytes, bytearrays and Pillow images. - Jarvis settings for resolution, feed, laser power, grayscale formula and
channel weights, brightness, contrast, white clip, bidirectional scanning,
overscan and
M3/M4mode. - Regression tests for Jarvis diffusion at image edges, binary power, transparency, input formats and profile validation.
# Changed
- Publishing a GitHub release now publishes the built distributions to PyPI after the wheel and source distribution jobs pass. The publish job checks that the release tag matches the package version. Pushes and manual runs continue to produce build artifacts only.
# Fixed
- Profiles and framing G-code reject
NaNand infinite numeric values before those values can reach generated G-code.
Jarvis currently supports horizontal raster passes. Its diffusion kernel follows LaserGRBL's behavior, while image resizing uses Pillow, so complete byte-for-byte parity with LaserGRBL is not guaranteed.
# 0.4.1 - 2026-09-09
# Changed
- Line-to-Line raster output now uses GRBL's modal motion state: each scan row
emits one
G1after itsG0, then omits redundantG1words from the remaining linear moves. Motion, power, coordinates, lazy iteration and constant-memory behaviour are unchanged while the serial payload is smaller.
# 0.4.0 - 2026-09-04
# Added
- All image APIs (
l2l_gcode,img2vector_gcode, andimg2svg) now accept encoded imagebytes,bytearray, and loadedPIL.Image.Imageinstances in addition to file paths. svg_gcodenow accepts SVG XML asstr,bytes, orbytearrayin addition to file paths.- In-memory inputs receive the same traceability header as paths: encoded bytes are hashed directly, while Pillow images are hashed from their mode, size, and pixel content.
# Changed
- Exported
ImageSourceandSvgSourcetype aliases describing every accepted input.
# 0.3.0 - 2026-06-19
# Added
- G-code bounds & framing (
get_bounding_box+generate_framing_gcode): the gcode-bounds library folded in as a second C extension (_gcode_parser), same C parser as the original (fast_atof+ line scan, 500MB+ files in seconds).get_bounding_boxcomputes the(min_x, max_x, min_y, max_y)extent of some G-code;generate_framing_gcodetraces that box (the framing pass) so the operator can confirm placement before engraving. Rapid moves to the origin (G0withX0/Y0) are skipped so the library's own home moves don't expand the box. get_bounding_boxaccepts the G-code as a file path (str/Path, opened and streamed in C) or as raw content already in memory (bytes/bytearray, or a multi-linestr), so it no longer has to exist on disk. The Python wrapper decides which route to take; a new C entry point (get_bounding_box_buffer) parses the in-memory buffer with the same per-line logic as the file path.
# 0.2.0 - 2026-06-16
# Added
- Image to SVG algorithm (
img2svg+Img2SvgProfile): traces a raster image to a standard vector SVG, reusing the same Potrace core and image preprocessing asimg2vector_gcodebut skipping the biarc/G-code stages. The contours are written as a single filled<path>withfill-rule="evenodd", so inner contours become holes (the filled black silhouette potrace.exe produces).viewBoxis in pixels whilewidth/heightcarry the physical size in mm, and the bitmap is not Y-flipped, keeping the image's natural top-down orientation.Img2SvgProfilecarries only the tracing and binarization knobs (no feed/power/laser-mode fields). Pure Python, Pillow only.
# 0.1.0 - 2026-06-16
# Added
- Image vector algorithm (
img2vector_gcode+Img2VectorProfile): outline tracing from a raster image, a faithful Python port of LaserGRBL's "Vectorize!" mode. The image is reduced to black/white (resize, grayscale, white-clip, optional threshold), Potrace traces its outlines as closed contours, and each cubic Bezier is approximated by biarcs and emitted asG2/G3arcs (with aG1fallback). Pure Python, Pillow only. Outlines only — interior filling is not ported yet.