-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPrintusEjectus.py
More file actions
186 lines (125 loc) · 6.41 KB
/
PrintusEjectus.py
File metadata and controls
186 lines (125 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# -------------------------------------------------------------------------------------------------
# This program reads all print files in the "inputs" folder
# and outputs a modified version with a push from the print head
# at the end of the print for automatic removal of the print.
# All outputs are saved in the "outputs" folder. (they can be overwritten !)
# This program currently only works for single part prints.
# Multi-part prints are currently considered as a single part and the
# toolhead might not push all of them off the bed.
# Made by ultimatech
# -------------------------------------------------------------------------------------------------
import os
import re
# -------------------------------------------------------------------------------------------------
# !!! WARNING: Make sure to change the following variables to match your printer's print format !!!
# -------------------------------------------------------------------------------------------------
# (The default values are for Qidi X-Plus 3 printers)
# ----- Input formatting -----
FILEEXTENSION = ".gcode" # File extension of the print files, change if needed
PRINTSTART = "PRINT_START\n" # This is the line that indicates the start of the print
PRINTEND = "; EXECUTABLE_BLOCK_END\n" # This is the line that indicates the end of the print
LAYERCHANGE = ";LAYER_CHANGE\n" # This is the line that indicates a new layer
IGNOREDLAYERS = 2 # Number of layers to ignore at the beginning of the print
# ----- Output formatting -----
PRINTOFFCOMMENT = "; PUSH PRINT OFF BED\n" # This is the comment that indicates the push off bed
FILESUFFIX = "_pushed" # Suffix added to the output file
STARTLINE = "G90; Use absolute coordinates\n" # First line of the pushing process
COOLINGTEMP = 30 # Temperature to wait for before pushing the print off the bed
COOLOFFNOZZLE = f"M109 S{COOLINGTEMP}; Waits for the nozzle to cool down\n" # This is the line that waits for the nozzle to cool down
HOMEXY = "G28 X Y; Homes the X and Y axis\n" # Homes the X and Y axis
GOTOBACK = "G1 X• Y260 F4000; Goes to the back of the printer\n" # Moves the print head to the back of printer without going down yet
GOTOBED = "G28 Z; Goes to the bed for print removal\n" # This is the line that moves the print head to the bed
PUSHCOORDINATES = "G1 Y20 F1000; Push print off bed\n" # This is the line that pushes the print off the bed
ENDLINE = "M84; Disables the stepper motors\n" # Last line of the pushing process
# WARNING: The "•" in some instructions will be replaced with the correct push location, make sure to keep it in the string !
DEBUG = True # Set to True to enable debug mode (prints additional information)
# -------------------------------------------------------------------------------------------------
def read_file(fileID):
'''
Open the first print file in the "inputs" folder
and read all the lines in the file
'''
with open('inputs/' + os.listdir('inputs')[fileID], 'r') as file:
lines = file.readlines()
return lines
def get_x_coordinates(lines):
'''
Get the X coordinates of the printer head
after the first few layers.
Ignores all the lines until PRINTSTART
and stops at PRINTEND
'''
x_coordinates = []
while lines[0] != PRINTSTART:
lines.pop(0)
currentLayer = 1
for line in lines:
if line == PRINTEND:
break
if line == LAYERCHANGE:
currentLayer += 1
# Modify this condition if you wish to acquire a different line
if line[0] == "G" and currentLayer > IGNOREDLAYERS:
x = re.search(r"X\d+\.\d+", line)
if x:
x_coordinates.append(float(x.group()[1:]))
return x_coordinates
def get_width(x_coordinates):
'''
Get the width of the object
based on the min and max X coordinates reached by the printer head
'''
return round(max(x_coordinates) - min(x_coordinates),2)
def get_mean(x_coordinates):
'''
Get the mean of the given X coordinates
'''
return round(sum(x_coordinates) / len(x_coordinates),2)
def create_output(lines, fileID):
'''
Create the output file with the same name as the input file
and write the new lines after the print end
'''
with open('outputs/' + os.listdir('inputs')[fileID][:-len(FILEEXTENSION)] + FILESUFFIX + FILEEXTENSION, 'w') as file:
x_coordinates = get_x_coordinates(lines)
printWidth = get_width(x_coordinates)
meanCoordinate = get_mean(x_coordinates)
# DEBUG ONLY
if DEBUG:
print("\tX range: [" + str(min(x_coordinates)) + " - " + str(max(x_coordinates)) + "]")
print("\tPrint width: ~" + str(printWidth) + "mm")
print("\tMean X coordinate: ~" + str(meanCoordinate) + "mm")
# Inserts the go to bed and push coordinates after the end of the print instruction
for line in lines:
if line == PRINTEND:
file.write(line)
file.write(STARTLINE)
file.write(PRINTOFFCOMMENT)
file.write(COOLOFFNOZZLE)
file.write(HOMEXY)
file.write(GOTOBACK.replace("•", str(meanCoordinate)))
file.write(GOTOBED)
file.write(PUSHCOORDINATES.replace("•", str(meanCoordinate)))
file.write(ENDLINE)
file.write(line)
# -------------------------------------------------------------------------------------------------
def main():
# Clears the console - DEBUG ONLY
if DEBUG:
os.system('cls' if os.name == 'nt' else 'clear')
# If the inputs or outputs folders do not exist, create them
if not os.path.exists('inputs'):
os.makedirs('inputs')
if not os.path.exists('outputs'):
os.makedirs('outputs')
totalCount = len(os.listdir('inputs'))
# For each print file in the "inputs" folder
for i in range(totalCount):
if os.listdir('inputs')[i][-len(FILEEXTENSION):] != FILEEXTENSION:
continue
currentCount = i + 1
print(f"\nProcessing file {currentCount}/{totalCount}: " + os.listdir('inputs')[i])
create_output(read_file(i), i)
if __name__ == '__main__':
os.chdir(os.path.dirname(os.path.abspath(__file__)))
main()