123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- #!/usr/bin/env python
- # This file is for preprocessing G-code and the new G29 Auto bed leveling from Marlin
- # It will analyze the first 2 layers and return the maximum size for this part
- # Then it will be replaced with g29_keyword = ';MarlinG29Script' with the new G29 LRFB.
- # The new file will be created in the same folder.
- from __future__ import print_function
- # Your G-code 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 = 100000000
- # g29 keyword
- g29_keyword = 'g29'
- g29_keyword = g29_keyword.upper()
- # output filename
- output_file = folder + 'g29_' + my_file
- # input filename
- input_file = folder + my_file
- # minimum scan size
- min_size = 40
- 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 = []
- # return only g1-lines
- def has_g1(line):
- return line[:2].upper() == "G1"
- # find position in g1 (x,y,z)
- def find_axis(line, axis):
- found = False
- number = ""
- for char in line:
- if found:
- if char == ".":
- number += char
- elif 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
- # save the min or max-values for each axis
- 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
- # find z in the code and return it
- 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)
- temp_line = i - last_i -1
- line_between_z.append(i - last_i - 1)
- # last_z = z
- last_i = i
- if 0 < end_at_line <= i or temp_line >= min_g1:
- # print('break at line {} at height {}'.format(i, z))
- break
- line_between_z = line_between_z[1:]
- return all_z, line_between_z, z_at_line
- # get the lines which should be the first layer
- 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:
- # print('layer: {}:{}'.format(z_at_line[i-1], z_at_line[i]))
- return z_at_line[i - 1], z_at_line[i]
- with open(input_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])
- print('x_min:{} x_max:{}\ny_min:{} y_max:{}'.format(min_x, max_x, min_y, max_y))
- # resize min/max - values for minimum scan
- if max_x - min_x < min_size:
- offset_x = int((min_size - (max_x - min_x)) / 2 + 0.5) # int round up
- # print('min_x! with {}'.format(int(max_x - min_x)))
- min_x = int(min_x) - offset_x
- max_x = int(max_x) + offset_x
- if max_y - min_y < min_size:
- offset_y = int((min_size - (max_y - min_y)) / 2 + 0.5) # int round up
- # print('min_y! with {}'.format(int(max_y - min_y)))
- 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')
- in_file = open(input_file, 'r')
- for line in in_file:
- if line[:len(g29_keyword)].upper() == g29_keyword:
- out_file.write(new_command)
- print('write G29')
- else:
- out_file.write(line)
- file.close()
- out_file.close()
- print('auto G29 finished')
|