From d74c8d57b423ba92d9b6c6c642bf5941038a12d0 Mon Sep 17 00:00:00 2001 From: kolkman Date: Wed, 4 Nov 2026 16:18:29 +0100 Subject: [PATCH] minore converter improvements --- .gitignore | 6 ++++++ Makefile | 15 +++++++++++++++ README.md | 19 ++++++++++++++++++- config.py | 8 ++++---- svg2gcode.py | 7 +++---- 5 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 .gitignore create mode 100644 Makefile diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd91fc3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__pycache__/config.cpython-313.pyc + +__pycache__/*.pyc +artwork/*.svg +gcode/*.gcode + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e4ec9ce --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +PYTHON ?= python3 +ARTWORK_DIR ?= artwork +GCODE_DIR ?= gcode + +SVG_FILES := $(wildcard $(ARTWORK_DIR)/*.svg) +GCODE_FILES := $(patsubst $(ARTWORK_DIR)/%.svg,$(GCODE_DIR)/%.gcode,$(SVG_FILES)) + +.PHONY: all +all: $(GCODE_FILES) + +$(GCODE_DIR)/%.gcode: $(ARTWORK_DIR)/%.svg config.py svg2gcode.py | $(GCODE_DIR) + $(PYTHON) convert.py "$<" "$@" + +$(GCODE_DIR): + mkdir -p "$@" diff --git a/README.md b/README.md index 79b2da7..a186369 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,31 @@ So I modified this to generate gcode for GRBL based pen plotter copy 's2g' to your path and run from anywhere >s2g source.svg target.gcode +**Convert all SVG files in `artwork/`** + +Run `make` from the repository root. Each `artwork/name.svg` is converted to +`gcode/name.gcode`. Only files that are newer than their corresponding output +are converted; changes to `config.py` or `svg2gcode.py` also rebuild all generated G-code. The +directories and Python command can be overridden, for example: +`make ARTWORK_DIR=my-art GCODE_DIR=out PYTHON=python3`. + **There is a brute force path optimisator algorithm. Very slow for large files, can be disabled in config.py** +Conversion raises Python's recursion limit to at least 100,000 as a temporary +workaround for long SVG paths. Larger paths may still exceed this limit, and +deep recursion can exhaust the stack on some Python versions and platforms. + **Illustrator exports in points, not mm** regardless of your document settings. If units are set to points in the config file, we convert to mm on the fly. There are various settings you can change in config.py. Most notably, you must set an upper and lower position for the z axis. +The `preamble` is emitted after the header and before the feed rate and drawing +moves. It currently homes with `$H`, selects millimeters, absolute positioning +and G54, then resets only the G54 Z offset to zero. X/Y offsets are preserved. +The controller or sender must support `$H` within a job. Regenerate existing +G-code with `make` and upload the new files to apply this startup sequence. + * zTravel is the height it will move to before traveling to the next stroke * zDraw should be the height at which the pen will make contact with the paper * zDraw should be the height at which the pen will make contact with the paper - diff --git a/config.py b/config.py index 56caf4d..581ebd4 100644 --- a/config.py +++ b/config.py @@ -1,5 +1,5 @@ """G-code emitted at the start of processing the SVG file""" -preamble = "G90" +preamble = "$H\nG21 G90 G54\nG10 L2 P1 Z0" """G-code emitted at the end of processing the SVG file""" @@ -28,7 +28,7 @@ value is greater than 0.1 smoothness = 0.02 """ height that the z axis will use to travel between strokes """ -zTravel = 4 +zTravel = 2 """ height that the z axis will use to draw """ zDraw = 0 @@ -50,5 +50,5 @@ optimise = True illustrator exports svg's in points, not mm set to "mm" if you don't want to convert to mm """ -units = "points" -#units = "mm" \ No newline at end of file +#units = "points" +units = "mm" diff --git a/svg2gcode.py b/svg2gcode.py index 18a043b..fdb543a 100755 --- a/svg2gcode.py +++ b/svg2gcode.py @@ -133,7 +133,7 @@ def shapes_2_gcode(shapes): with open("header.txt") as h: header = h.read() - commands = [f"{header}", f'F{feed_rate}'] + commands = [f"{header}", preamble, f'F{feed_rate}'] for i in shapes: commands += ['', shape_preamble, ""] @@ -149,7 +149,7 @@ def shapes_2_gcode(shapes): commands += [" ",postamble, ""] - commands += ["(home)", f"G0 {zTravel}", f"G0 X0 Y0"] + commands += ["(home)", f"G0 Z{zTravel}", f"G0 X0 Y0"] timer(t1, "shapes_2_gcode ") @@ -165,6 +165,7 @@ def write_file(output, commands): def main(file_path, output): + sys.setrecursionlimit(max(sys.getrecursionlimit(), 100000)) shapes = get_shapes(file_path, auto_scale) @@ -207,5 +208,3 @@ if __name__ == "__main__": output = "./gcode_optimised/1.gcode" main(file_path, output) - -