diff --git a/README.md b/README.md index d483e57..e1b1114 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,8 @@ The hacked together pipeline is as follows given an svg `$SVG`. You may use the 1. One way to ensure is by setting width & height on the root `` element 2. Covert the SVG to gcode via `cargo run --release -- $SVG -o $OUTFILE` 3. Rewrite the gcode to center where the print happens via `python rewritegcode.py $OUTFILE $UPDATEFILE` -4. (Optional) Verify the maximum x & y values fit on the board via `python parsegcode.py $UPDATEFILE` -5. Generate the final file by concatenating the header to the updated file via `cat ooza/config.g $UPDATEFILE > $FINALEFILE` -6. Upload `$FINALFILE` to Jobs in Duet and run it +4. Generate the final file by concatenating the header to the updated file via `cat ooza/config.g $UPDATEFILE > $FINALEFILE` +5. Upload `$FINALFILE` to Jobs in Duet and run it # svg2gcode diff --git a/parsegcode.py b/parsegcode.py deleted file mode 100644 index a81b903..0000000 --- a/parsegcode.py +++ /dev/null @@ -1,40 +0,0 @@ -import re -import sys - - -def get_xy(line): - xmatch = re.search(r"X(\d*)", line) - ymatch = re.search(r"Y(\d*)", line) - - if xmatch is None or ymatch is None: - return None, None - - xval = int(xmatch.group().strip("X")) - yval = int(ymatch.group().strip("Y")) - return xval, yval - - -def parse_file(fname): - with open(fname) as fp: - lines = fp.read().splitlines() - - minx = float('inf') - miny = float('inf') - maxx = float('-inf') - maxy = float('-inf') - - for line in lines: - x, y = get_xy(line) - - if x is None or y is None: - continue - - minx = min(x, minx) - maxx = max(x, maxx) - miny = min(y, miny) - maxy = max(y, maxy) - - print(f"MinX={minx}, MinY={miny}, MaxX={maxx}, MaxY={maxy}") - -if __name__ == '__main__': - parse_file(sys.argv[1]) diff --git a/rewritegcode.py b/rewritegcode.py index 8aa0c98..f2eaa8c 100644 --- a/rewritegcode.py +++ b/rewritegcode.py @@ -1,11 +1,31 @@ import re import sys +from dataclasses import dataclass XADD = 150 YADD = 300 ZDOWN = 62.4 ZUP = ZDOWN + 5 +ANSI = "\033[0;{}m" +OFF = ANSI.format(0) +RED = ANSI.format(31) +GREEN = ANSI.format(32) + +MINX = 100 +MAXX = 650 +MINY = 200 +MAXY = 1000 + + +@dataclass +class GCodeInfo: + minx: float + maxx: float + miny: float + maxy: float + + def get_xy(line): xmatch = re.search(r"X(\d*\.\d*)", line) ymatch = re.search(r"Y(\d*\.\d*)", line) @@ -18,37 +38,92 @@ def get_xy(line): return xval, yval -def rewrite_gcode(infile, outfile): - with open(infile) as fp: - lines = fp.read().splitlines() - - fp = open(outfile, 'w') - +def rewrite_lines(inlines): # Home the board after bed is setup - fp.write("G28\n") + outlines = "G28\n" - for line in lines: + minx = float('inf') + miny = float('inf') + maxx = float('-inf') + maxy = float('-inf') + + for line in inlines: x, y = get_xy(line) prefix = line[:2] - if x is None or y is None: + if x is None and y is None: if prefix != "M2": - fp.write(f"{line}\n") + outlines += f"{line}\n" continue + lines = prefix + + if x is not None: + x += XADD + lines += f" X{x}" + minx = min(x, minx) + maxx = max(x, maxx) + + if y is not None: + y += YADD + lines += f" Y{y}" + miny = min(y, miny) + maxy = max(y, maxy) + postfix = "" if prefix == "G0" else " F1500" - lines = f"{prefix} X{x+XADD} Y{y+YADD}{postfix}\n" + lines += f"{postfix}\n" # Raise and lower the pen before moving on fresh lines if prefix == "G0": lines = f"G0 Z{ZUP}\n{lines}G0 Z{ZDOWN}\n" - fp.write(lines) + outlines += lines # Raise pen as final control - fp.write(f"G0 Z{ZUP}\n") + outlines += f"G0 Z{ZUP}\n" + info = GCodeInfo( + minx=minx, + maxx=maxx, + miny=miny, + maxy=maxy, + ) + + return (outlines, info) + + +def check_okay(info): + if info.minx < MINX or info.miny < MINY or info.maxx > MAXX or info.maxy > MAXY: + return False + return True + + +def format_info_error(info): + output = f"{RED}Print is outside range of Ooza, please resize.{OFF}" + if info.minx < MINX: + output += f"\n Min X: {int(info.minx)} < {MINX}" + if info.maxx > MAXX: + output += f"\n Max X: {int(info.maxx)} > {MAXX}" + if info.miny < MINY: + output += f"\n Min Y: {int(info.miny)} < {MINY}" + if info.maxy > MAXY: + output += f"\n Max Y: {int(info.maxy)} > {MAXY}" + return output + + +def rewrite_gcode(infile, outfile): + with open(infile) as fp: + lines = fp.read().splitlines() + + lines, info = rewrite_lines(lines) + + if not check_okay(info): + print(format_info_error(info)) + return 1 + + with open(outfile, "w") as fp: + fp.write(lines) - fp.close() + return 0 if __name__ == '__main__': - rewrite_gcode(sys.argv[1], sys.argv[2]) + sys.exit(rewrite_gcode(sys.argv[1], sys.argv[2]))