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) if xmatch is None or ymatch is None: return None, None xval = float(xmatch.group().strip("X")) yval = float(ymatch.group().strip("Y")) return xval, yval def rewrite_lines(inlines): # Home the board after bed is setup outlines = "G28\n" 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 and y is None: if prefix != "M2": 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"{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" outlines += lines # Raise pen as final control 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) return 0 if __name__ == "__main__": sys.exit(rewrite_gcode(sys.argv[1], sys.argv[2]))