# This file is for preprocessing gcode and the new G29 Autobedleveling from Marlin # It will analyse the first 2 Layer and return the maximum size for this part # After this it will replace with g29_keyword = ';MarlinG29Script' with the new G29 LRFB # the new file will be created in the same folder. # your gcode-file/folder folder = './' my_file = 'test.gcode' # this is the minimum of G1 instructions which should be between 2 different heights min_g1 = 3 # maximum number of lines to parse, I don't want to parse the complete file # only the first plane is we are interested in max_g1 = 1000 # g29 keyword g29_keyword = ';MarlinG29Script' # output filename output_file = folder + 'g29_' + my_file # offset makes the plane a little bit bigger offset_x = 10 offset_y = 10 probing_points = 3 # points x points # other stuff min_x = 500 min_y = min_x max_x = -500 max_y = max_x last_z = 0.001 layer = 0 lines_of_g1 = 0 gcode = [] def has_g1(line): return line[:2].upper() == "G1" def find_axis(line, axis): found = False number = "" for char in line: if found: if char == ".": number += char else: try: int(char) number += char except ValueError: break else: found = char.upper() == axis.upper() try: return float(number) except ValueError: return None def set_mima(line): global min_x, max_x, min_y, max_y, last_z current_x = find_axis(line, 'x') current_y = find_axis(line, 'y') if current_x is not None: min_x = min(current_x, min_x) max_x = max(current_x, max_x) if current_y is not None: min_y = min(current_y, min_y) max_y = max(current_y, max_y) return min_x, max_x, min_y, max_y def find_z(gcode, start_at_line=0): for i in range(start_at_line, len(gcode)): my_z = find_axis(gcode[i], 'Z') if my_z is not None: return my_z, i def z_parse(gcode, start_at_line=0, end_at_line=0): i = start_at_line all_z = [] line_between_z = [] z_at_line = [] # last_z = 0 last_i = -1 while len(gcode) > i: try: z, i = find_z(gcode, i + 1) except TypeError: break all_z.append(z) z_at_line.append(i) line_between_z.append(i - last_i - 1) # last_z = z last_i = i if 0 < end_at_line <= i: break # print('{}:{}'.format(last_z, last_i)) line_between_z = line_between_z[1:] return all_z, line_between_z, z_at_line def get_lines(gcode, minimum): i = 0 all_z, line_between_z, z_at_line = z_parse(gcode, end_at_line=max_g1) for count in line_between_z: i += 1 if count > minimum: return z_at_line[i - 1], z_at_line[i] with open(folder+my_file, 'r') as file: lines = 0 for line in file: lines += 1 if lines > 1000: break if has_g1(line): gcode.append(line) file.close() start, end = get_lines(gcode, min_g1) for i in range(start, end): set_mima(gcode[i]) min_x = int(min_x) - offset_x max_x = int(max_x) + offset_x min_y = int(min_y) - offset_y max_y = int(max_y) + offset_y new_command = 'G29 L{0} R{1} F{2} B{3} P{4}\n'.format(min_x, max_x, min_y, max_y, probing_points) out_file = open(output_file, 'w') print('out_file open') input_file = open(my_file, 'r') print('input_file open') for line in input_file: if line[:len(g29_keyword)] == g29_keyword: out_file.write(new_command) print('write new_command') else: out_file.write(line) file.close() out_file.close()