187 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/python3
 | |
| 
 | |
| # 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 = 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 heigth {}'.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')
 |