Last active
January 25, 2022 14:23
-
-
Save GluTbl/3af06b63f7922b4904abbbcd1047640a to your computer and use it in GitHub Desktop.
[3D printer resumer gcode generator] #python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
""" | |
You need to know the "Z_axis" value of the last saved value | |
You can save it using the serial data transmited by the 3D printer | |
For me i use qprompt and pass some data and extract the z axis | |
""" | |
import os.path | |
import re | |
import sys | |
from os import remove | |
from os.path import isfile, isdir, isabs | |
from typing import Dict | |
import qprompt | |
from tqdm import tqdm | |
###### | |
import argparse | |
parser = argparse.ArgumentParser() | |
parser.add_argument( | |
"-f", | |
"--file", | |
help="Path to the gcode file", | |
required=True | |
) | |
args_value=parser.parse_args() | |
file_name=args_value.file | |
if not isabs(file_name): | |
file_name=os.path.abspath(file_name) | |
#check file exist | |
if not isfile(file_name): | |
raise Exception(f"File \"{file_name}\" doesnot exist.") | |
############ | |
gcode_file = file_name | |
output = os.path.join("./", f"new_{os.path.basename(gcode_file)}") | |
# Grab data from last run location | |
# 1637120761 <02><X:135.40 Y:91.93 Z:24.00 E:84.32 Count X:10832 Y:7354 Z:9600> | |
axis_match = re.compile( | |
r"(?P<time_milli>\d+)\s+<02><X:(?P<x_axis>[0-9\.]+)\s+Y:(?P<y_axis>[0-9\.]+)\s+Z:(?P<z_axis>[0-9\.]+)\s+E:(?P<e_axis>[0-9\.]+)\s+Count.*?", | |
re.UNICODE) | |
# G1 F2700 E389.12504 | |
extruder_match = re.compile(r"G(?P<g_value>[0-9\.]+)\s+F(?P<f_value>[0-9\.]+)\sE(?P<e_value>[\-0-9\.]+)", re.UNICODE) | |
# M140 S50 | |
m_command_match = re.compile(r"M(?P<m_value>[0-9\.]+)\s+S(?P<s_value>[0-9\.]+)", re.UNICODE) | |
m_command_only_mmatch = re.compile(r"M(?P<m_value>[0-9\.]+)", re.UNICODE) | |
# Z9.12 | |
z_axis_match = re.compile(r"[^\;]*?\sZ(?P<z_value>[0-9\.]+)\D", re.UNICODE) | |
# MCommand Manager | |
class MCommandManager: | |
def __init__(self): | |
self.commands = {} | |
self.execution_order = [] | |
pass | |
def add_command(self, data: Dict): | |
m_value = data["m_value"] | |
self.execution_order.append(m_value) | |
s_value = data["s_value"] | |
if m_value not in self.commands: | |
self.commands[m_value] = [s_value] | |
else: | |
self.commands[m_value].append(s_value) | |
pass | |
def add_command_m_only(self, data: Dict): | |
m_value = data["m_value"] | |
self.execution_order.append(m_value) | |
if m_value not in self.commands: | |
self.commands[m_value] = [None] | |
else: | |
self.commands[m_value].append(None) | |
pass | |
def get_last_done_mcommands(self): | |
command_dict = {} | |
for m, s_values in self.commands.items(): | |
cmd = "" | |
if s_values[-1] is not None: | |
cmd += f"M{m} S{s_values[-1]} ; __Extra__\n" | |
else: | |
cmd += f"M{m} ; __Extra__\n" | |
command_dict[m] = cmd | |
already_executed = [] | |
string_cmd = "" | |
self.execution_order.reverse() | |
for exec_m in self.execution_order: | |
if exec_m in already_executed: | |
continue | |
already_executed.append(exec_m) | |
string_cmd = command_dict[exec_m] + string_cmd | |
return string_cmd | |
# | |
while 1: | |
last_location=qprompt.ask_str("Last location of failed print") | |
# last_location = "1637120761 <02><X:135.40 Y:91.93 Z:24.00 E:84.32 Count X:10832 Y:7354 Z:9600>" | |
matched = axis_match.match(last_location) | |
if matched is None: | |
print("The input line is not valid.") | |
break | |
break | |
######################### | |
z_axis = float(matched.groupdict()["z_axis"]) | |
if isfile(output): | |
remove(output) | |
if isfile(output) or isdir(output): | |
raise Exception("Cannot delete file") | |
with open(output, "a") as writer: | |
flag_print_cmd_start = False | |
flag_home_all = False | |
flag_extruder_reset = False | |
flag_extra_extruded = False | |
last_extruder_location = None | |
flag_resume_z_axis_found = False | |
m_command_manager = MCommandManager() | |
# num_lines = sum(1 for line in open(gcode_file, 'r')) | |
print("Counting line number of gcode file...") | |
num_lines = 0 | |
with open(gcode_file) as reader: | |
# for line in reader: | |
for line in reader: | |
num_lines += 1 | |
with open(gcode_file) as reader: | |
# for line in reader: | |
for line in tqdm(reader, total=num_lines): | |
original_line = line | |
flag_write = False | |
if not flag_print_cmd_start: | |
flag_write = True | |
if not flag_home_all: | |
flag_write = True | |
if "Reset Extruder" in line: | |
flag_extruder_reset = True | |
if "Home all axes" in line: | |
if not flag_extruder_reset: | |
raise Exception("Did not reset extruder") | |
# extrude some | |
flag_home_all = True | |
##No mater how atch lets not writwoff if home has reached | |
elif flag_home_all and not flag_resume_z_axis_found: | |
flag_write = False | |
extuder_matched_value = extruder_match.match(line) | |
if extuder_matched_value is not None: | |
# dict_data=extuder_matched_value.groupdict() | |
last_extruder_location = extuder_matched_value.groupdict()["e_value"] | |
# match for M commands | |
m_command_match_value = m_command_match.match(line) | |
if m_command_match_value is not None: | |
m_command_manager.add_command(m_command_match_value.groupdict()) | |
else: | |
m_command_only_mmatch_value = m_command_only_mmatch.match(line) | |
if m_command_only_mmatch_value is not None: | |
m_command_manager.add_command_m_only(m_command_only_mmatch_value.groupdict()) | |
# check if the z axis found | |
z_axis_match_value = z_axis_match.match(line) | |
if z_axis_match_value is not None: | |
cur_z_value = float(z_axis_match_value.groupdict()["z_value"]) | |
if z_axis == cur_z_value: | |
print("Found Z axis") | |
cmd_last_extruder_location = f"G92 E{last_extruder_location} ; Set Extruder to last location __Extra__\n" # set the last extruder location | |
cmd_move_z_axis_only = f"G1 Z{cur_z_value} F3000 ; Move Z Axis up to avoid printed object collision __EXTRA__\n" | |
cmd_extrude = "G92 E0 ; Reset Extruder __Extra__\nG1 E10 F800 ; extrude 10mm of filament __Extra__\nG92 E0 ; Reset Extruder __Extra__\n" | |
line = m_command_manager.get_last_done_mcommands() + cmd_move_z_axis_only + cmd_extrude + cmd_last_extruder_location + line | |
flag_resume_z_axis_found = True | |
if flag_resume_z_axis_found: | |
flag_write = True | |
# Write if there is write flag | |
if flag_write: | |
writer.write(line) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment