-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
E3S1PROFORKBYTT_printdata_prusaslicer_v27_thumbnail.py
154 lines (133 loc) · 6.79 KB
/
E3S1PROFORKBYTT_printdata_prusaslicer_v27_thumbnail.py
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
#!/usr/bin/env python3
#
# Prusa Slicer as of v2.7 remove headers before jpg and convert PNG to JPG.
#
# This script has been developed for E3S1PROFORKBYTT by Thomas Toka.
#
# ------------------------------------------------------------------------------
import sys
import base64
import math
from PIL import Image
from io import BytesIO
import os
import platform
if platform.system() == "Darwin":
print("Running on macOS")
script_directory = os.path.dirname(os.path.abspath(__file__))
source_file = sys.argv[1]
source_file = os.path.join(script_directory, source_file)
if not os.path.exists(source_file):
print(f"The file '{source_file}' does not exist.")
sys.exit(1)
else:
print(f"The file '{source_file}' exists.")
else:
print("Not running on macOS")
def main(source_file):
# Read the entire G-code file into memory
with open(source_file, "r", encoding='utf-8') as f:
lines = f.readlines()
# Remove any empty lines and lines that are just a semicolon
lines = [line for line in lines if line.strip() and not line == ';\n']
# Extract additional information
filament_used_m, filament_used_g, filament_diameter, filament_density, layer_height = "0", "0", "0", "0", "0"
layers = 0
for line in lines:
if line.startswith("; filament used [mm] ="):
filament_used_mm_values = [float(value.strip()) for value in line.split("=")[1].strip().split(',')]
filament_used_m = round(sum(filament_used_mm_values) / 1000, 2) # Convert mm to meters
if filament_used_m > 0:
filament_used_m = math.ceil(filament_used_m)
else:
filament_used_m = 0
elif line.startswith("; filament used [g] ="):
filament_used_g_values = [float(value.strip()) for value in line.split("=")[1].strip().split(',')]
filament_used_g = round(sum(filament_used_g_values), 2)
if filament_used_g > 0:
filament_used_g = math.ceil(filament_used_g)
else:
filament_used_g = 0
elif line.startswith("; filament_diameter ="):
filament_diameter_values = [float(value.strip()) for value in line.split("=")[1].strip().split(',')]
filament_diameter = round(sum(filament_diameter_values) / len(filament_diameter_values), 2)
filament_diameter = "{:.2f}".format(filament_diameter)
elif line.startswith("; filament_density ="):
filament_density_values = [float(value.strip()) for value in line.split("=")[1].strip().split(',')]
filament_density = round(sum(filament_density_values) / len(filament_density_values), 2) # Calculate the median
filament_density = "{:.2f}".format(filament_density)
elif line.startswith("; layer_height ="):
layer_height_values = [float(value.strip()) for value in line.split("=")[1].strip().split(',')]
layer_height = round(sum(layer_height_values) / len(layer_height_values), 2) # Calculate the median
layer_height = "{:.2f}".format(layer_height)
elif line.startswith(";AFTER_LAYER_CHANGE"):
layers += 1
filament_used_m_per_layer = filament_used_m / max(layers, 1) # Avoid division by zero
remaining_filament_m = filament_used_m
filament_used_g_per_layer = filament_used_g / max(layers, 1) # Avoid division by zero
remaining_filament_g = filament_used_g
m117_added = 0 # Counter for added M117 commands
# Counting AFTER_LAYER_CHANGE occurrences
after_layer_change_count = sum(';AFTER_LAYER_CHANGE' in line for line in lines) - 1
# Find the thumbnail start and end lines
thumbnail_start, thumbnail_end = None, None
for i, line in enumerate(lines):
if '; thumbnail begin' in line:
thumbnail_start = i
elif '; thumbnail end' in line:
thumbnail_end = i
break
if thumbnail_start is not None and thumbnail_end is not None:
# Extract and decode the PNG data
original_png_data = "".join(lines[thumbnail_start + 1:thumbnail_end]).replace("; ", "")
png_data_bytes = base64.b64decode(original_png_data)
image = Image.open(BytesIO(png_data_bytes))
image = image.convert("RGB")
# Encode the image as JPEG
buffer = BytesIO()
image.save(buffer, format="JPEG")
image_jpg_data = buffer.getvalue()
# Base64 encode the JPEG data
image_jpg_base64 = base64.b64encode(image_jpg_data).decode('utf-8')
# Split the base64 string into formatted lines
max_line_length = 79 - len("; ")
injected_jpg_data = ["; " + image_jpg_base64[i:i + max_line_length] for i in range(0, len(image_jpg_base64), max_line_length)]
# Replace the old PNG lines with the new JPEG lines
lines[thumbnail_start + 1:thumbnail_end] = [line + "\n" for line in injected_jpg_data]
# Update the '; thumbnail_JPG begin' line using 'after_layer_change_count'
start_line_number = 1
end_line_number = start_line_number + len(injected_jpg_data) + 1
lines[thumbnail_start] = f'; thumbnail_JPG begin 250x250 {len(image_jpg_data)} {start_line_number} {end_line_number} {filament_used_m} {filament_used_g} {layer_height} {filament_diameter} {filament_density} {after_layer_change_count}\n'
# Insert 'M117 Pxxx Qxxx' before each ';AFTER_LAYER_CHANGE'
layer_number = 0
i = 0
while i < len(lines):
if lines[i].startswith(';AFTER_LAYER_CHANGE'):
if layer_number == 0:
m117_line = "M117 L1 M{} G{} Z{} Q{}".format(math.ceil(remaining_filament_m), math.ceil(remaining_filament_g), layers, layer_height)
else:
m117_line = "M117 L{} M{} G{}".format(layer_number + 1, math.ceil(remaining_filament_m), math.ceil(remaining_filament_g))
lines.insert(i, m117_line + '\n')
remaining_filament_m -= filament_used_m_per_layer
remaining_filament_g -= filament_used_g_per_layer
m117_added += 1 # Increment counter
layer_number += 1
i += 1
i += 1
if m117_added > 0:
print("Added {} M117 commands.".format(m117_added))
else:
print("No M117 commands were added. Check the G-code for ';AFTER_LAYER_CHANGE' markers.")
# Remove the '; generated by PrusaSlicer' line and any leading semicolons or empty lines
lines = [line for line in lines if line.strip() and not line.startswith('; generated by PrusaSlicer')]
# Write the modified content back to the original file
with open(source_file, "w", encoding='utf-8') as f:
f.writelines(lines)
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 script.py <gcode-file>")
sys.exit(1)
if platform.system() == "Darwin":
main(source_file)
else:
main(sys.argv[1])