v023 printdata update

Firmware-Binaries MARLIN-E3S1PROFORK-BYTT-v023
ThomasToka 6 months ago committed by GitHub
parent 15ba5dbcb4
commit 37fbd98670
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,254 @@
#------------------------------------------------------------------------------
# Cura 5.4 JPEG Thumbnail creator
#
# This script has been changed for E3S1PROFORKBYTT by Thomas Toka.
#
# Intruduced with v008 into E3S1PROFORKBYTT.
#
# It is based on the modification of:
#
# Professional firmware for Ender3v2
# Miguel A. Risco-Castillo
# version: 1.4
# date: 2022-05-18
#
# Contains code from:
# https://github.com/Ultimaker/Cura/blob/master/plugins/PostProcessingPlugin/scripts/CreateThumbnail.py
#------------------------------------------------------------------------------
import base64
import math
import re
from UM.Logger import Logger
from cura.Snapshot import Snapshot
from cura.CuraVersion import CuraVersion
from ..Script import Script
class E3S1PROFORKBYTT_Thumbnail(Script):
def __init__(self):
super().__init__()
def getSettingDataString(self):
return """{
"name": "E3S1PROFORKBYTT Thumbnail",
"key": "E3S1PROFORKBYTT_Thumbnail",
"metadata": {},
"version": 2,
"settings": {
"width": {
"label": "Width",
"description": "Width of the generated thumbnail",
"unit": "px",
"type": "int",
"default_value": 250,
"minimum_value": "250",
"maximum_value_warning": "250"
},
"height": {
"label": "Height",
"description": "Height of the generated thumbnail",
"unit": "px",
"type": "int",
"default_value": 250,
"minimum_value": "250",
"maximum_value_warning": "250"
},
"Diameter": {
"label": "Filament Diameter",
"description": "Diameter of the Used Filament",
"unit": "mm",
"type": "float",
"default_value": 1.75,
"minimum_value": "1.75",
"maximum_value_warning": "3.00"
},
"Density": {
"label": "Filament Density",
"description": "PLA/PETG=1.25, ABS/ASA=1.10",
"unit": "g/cm³",
"type": "float",
"default_value": 1.25,
"minimum_value": "1.10",
"maximum_value_warning": "2.00"
}
}
}"""
def _createSnapshot(self, width, height):
Logger.log("d", "Creating thumbnail image...")
try:
return Snapshot.snapshot(width, height)
except Exception as e:
Logger.logException("w", "Failed to create snapshot image. Error: {}".format(str(e)))
def _encodeSnapshot(self, snapshot):
Major, Minor = 0, 0
try:
Major = int(CuraVersion.split(".")[0])
Minor = int(CuraVersion.split(".")[1])
except:
pass
if Major < 5:
from PyQt5.QtCore import QByteArray, QBuffer
else:
from PyQt6.QtCore import QByteArray, QBuffer
Logger.log("d", "Encoding thumbnail image...")
try:
thumbnail_buffer = QBuffer()
if Major < 5:
thumbnail_buffer.open(QBuffer.ReadWrite)
else:
thumbnail_buffer.open(QBuffer.OpenModeFlag.ReadWrite)
snapshot.save(thumbnail_buffer, "JPG")
base64_bytes = base64.b64encode(thumbnail_buffer.data())
base64_message = base64_bytes.decode('ascii')
thumbnail_buffer.close()
return base64_message
except Exception as e:
Logger.logException("w", "Failed to encode snapshot image. Error: {}".format(str(e)))
def _convertSnapshotToGcode(self, encoded_snapshot, width, height, chunk_size=58):
gcode = ["; jpg begin {}x{} {}".format(width, height, len(encoded_snapshot))]
chunks = ["; {}".format(encoded_snapshot[i:i + chunk_size]) for i in range(0, len(encoded_snapshot), chunk_size)]
gcode.extend(chunks)
gcode.append("; jpg end")
gcode.append(";")
return gcode
# Get the time value from a line as a float.
def getTimeValue(self, line):
list_split = re.split(":", line)
return float(list_split[1])
def execute(self, data):
try:
width = self.getSettingValueByKey("width")
height = self.getSettingValueByKey("height")
diameter = self.getSettingValueByKey("Diameter")
diameter_cm = diameter / 10 # Convert mm to cm
density = self.getSettingValueByKey("Density")
snapshot = self._createSnapshot(width, height)
if snapshot:
encoded_snapshot = self._encodeSnapshot(snapshot)
snapshot_gcode = self._convertSnapshotToGcode(encoded_snapshot, width, height)
layer_height_value = 0.0
filament_used_g = 0.0
filament_used_m = 0.0
layers = 0
total_time = -1
for layer_index, layer_data in enumerate(data):
lines = layer_data.split("\n")
for line_index, line in enumerate(lines):
if line.startswith(";LAYER:"):
layer_number = int(line.split(":")[1]) + 1
elif line.startswith(";Filament used:"):
filament_used_m = float(line.split(":")[1].split('m')[0].strip())
filament_used_cm = filament_used_m * 100
filament_used_m = math.ceil(filament_used_m) if filament_used_m > 0 else 0
volume_cm3 = math.pi * (diameter_cm / 2) ** 2 * filament_used_cm
filament_used_g = math.ceil(volume_cm3 * density) if volume_cm3 * density > 0 else 0
elif line.startswith(";Layer height:"):
layer_height_value = round(float(line.split(":")[1].strip()), 2)
elif line.startswith(";MAXZ:"):
maxz_value = round(float(line.split(":")[1].strip()), 2)
layers = int(maxz_value / layer_height_value)
elif line.startswith(";TIME:") and total_time == -1:
total_time = self.getTimeValue(line)
data[layer_index] = "\n".join(lines)
# Insert the snapshot thumbnail G-code
flavor_line_index = None
for layer_index, layer_data in enumerate(data):
lines = layer_data.split("\n")
for line_index, line in enumerate(lines):
if line.startswith(";FLAVOR:Marlin"):
flavor_line_index = line_index
break
if flavor_line_index is not None:
break
if flavor_line_index is not None:
lines_to_insert = snapshot_gcode + [""]
lines = lines[:flavor_line_index] + lines_to_insert + lines[flavor_line_index:]
modified_layer_data = "\n".join(lines)
data[layer_index] = modified_layer_data
# Calculate total lines so far for the snapshot
total_lines_so_far = 0
for index, layer in enumerate(data):
lines = layer.split('\n')
for line_index, line in enumerate(lines):
if line.startswith("; jpg begin"):
start_line_number = total_lines_so_far + line_index + 1
if line.startswith("; jpg end"):
end_line_number = total_lines_so_far + line_index + 1
total_lines_so_far += len(lines)
# Update the snapshot G-code with total lines and other information
for index, layer in enumerate(data):
lines = layer.split('\n')
for line_index, line in enumerate(lines):
if line.startswith("; jpg begin"):
updated_line = "; jpg begin {}x{} {} {} {} {} {} {} {} {} {}".format(
width, height, len(encoded_snapshot), start_line_number, end_line_number,
filament_used_m, filament_used_g, layer_height_value, diameter, density, layers)
lines[line_index] = updated_line
data[index] = "\n".join(lines)
# Additional time and percentage calculations
if total_time != -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_1 = False # Flag to check if M117 and M73 commands were added for Layer 0
#m117_added_all = False
for layer_index, layer_data in enumerate(data):
lines = layer_data.split("\n")
for line_index, line in enumerate(lines):
if line.startswith(";LAYER:"):
layer_number = int(line.split(":")[1]) + 1
remaining_filament_m -= filament_used_m_per_layer
remaining_filament_g -= filament_used_g_per_layer
# Check if this is Layer 1 and M117/M73 commands have not been added yet
if layer_number == 1 and not m117_added_1:
# Find the first G0 move with Z0.28 for Layer 0 and add M117 and M73 commands after it
for sub_line_index, sub_line in enumerate(lines[line_index:], start=line_index):
if sub_line.startswith("G0 ") and f"Z{layer_height_value}" in sub_line:
m117_line = "M117 L{} M{} G{}".format(layer_number, math.ceil(remaining_filament_m), math.ceil(remaining_filament_g))
m73_line = "M73 P{} R{}".format(0, total_time)
lines.insert(sub_line_index + 1, m117_line)
lines.insert(sub_line_index + 2, m73_line)
m117_added_1 = True # Set the flag to True after adding M117 and M73 commands for Layer 0
break
# For all other layers, including Layer 1 if M117/M73 commands have not been added
if layer_number != 1 and not line.startswith("M117") and not line.startswith("M73"):
m117_line = "M117 L{} M{} G{}".format(layer_number, math.ceil(remaining_filament_m), math.ceil(remaining_filament_g))
m73_line = "M73 P{} R{}".format(int((layer_number / layers) * 100), int(total_time * (1 - layer_number / layers) / 60))
lines.insert(line_index, m117_line)
lines.insert(line_index + 1, m73_line)
#m117_added_all = True
break # Add the commands once and then break out of the loop
data[layer_index] = "\n".join(lines)
if not m117_added:
Logger.log("w", "No M117 and M73 commands were added for Layer 0. Check the G-code for ';LAYER:' markers.")
else:
Logger.log("d", "Added M117 and M73 commands for Layer 0 and subsequent layers.")
else:
Logger.log("w", "Snapshot not created. Skipping M117 command insertion.")
except Exception as e:
Logger.logException("e", "Error in script execution: {}".format(str(e)))
return data

@ -0,0 +1,141 @@
#!/usr/bin/env python3
#
# Orca Slicer as of v18beta2 remove headers before jpg and convert PNG to JPG.
#
# This script has been developed for E3S1PROFORKBYTT by Thomas Toka.
#
# ------------------------------------------------------------------------------
import sys
import math
import base64
from PIL import Image
from io import BytesIO
import re
def main(source_file):
# Read the entire G-code file into memory
with open(source_file, "r") as f:
lines = f.readlines()
# Extract additional information
filament_used_m, filament_used_g, filament_diameter, filament_density, layer_height, layers = "0", "0", "0", "0", "0", "0"
for line in lines:
if line.startswith("; filament used [mm] ="):
filament_used_mm = float(line.split("=")[1].strip())
filament_used_m = round(filament_used_mm / 1000, 2)
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 = float(line.split("=")[1].strip())
filament_used_g = round(filament_used_g, 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 = float(line.split("=")[1].strip())
elif line.startswith("; filament_density ="):
filament_density = float(line.split("=")[1].strip())
elif line.startswith("; layer_height ="):
layer_height = line.split("=")[1].strip()
layer_height = "{:.2f}".format(round(float(layer_height), 2))
elif line.startswith("; total layers count ="):
layers = line.split("=")[1].strip()
layers = int(layers)
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
# Convert the thumbnail from PNG to JPEG
thumbnail_start = None
for i, line in enumerate(lines):
if '; thumbnail begin' in line:
thumbnail_start = i
break
if thumbnail_start is not None:
# Find the thumbnail end line
thumbnail_end = next((i for i, line in enumerate(lines[thumbnail_start:], start=thumbnail_start) if '; thumbnail end' in line), None)
if 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)]
# Remove everything before the '; thumbnail_JPG begin' line
lines = lines[thumbnail_start:]
# Replace the old PNG lines with the new JPEG lines
lines[1:thumbnail_end - thumbnail_start] = [line + "\n" for line in injected_jpg_data]
# Update start and end line numbers
start_line_number = 1 # The line immediately after '; thumbnail_JPG begin'
end_line_number = start_line_number + len(injected_jpg_data) + 1
# Update the '; thumbnail_JPG begin' line
lines[0] = 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} {layers}\n'
# Find the ';LAYER_CHANGE' line and add 'M117' after the next 'G1 Z' line with the corresponding 'Z' value
layer_number = 0
layer_change_found = False
for i in range(len(lines)):
if lines[i].strip() == ";LAYER_CHANGE":
layer_number += 1
layer_change_found = True
elif layer_change_found:
match = re.search(r";Z:([\d.]+)", lines[i])
if match:
z_value = match.group(1) # Extract the Z value
next_g1_z_index = i + 1
while next_g1_z_index < len(lines):
if float(z_value) >= 1:
g1_z_regex = fr"G1 Z{z_value}(?=\s|$)"
else:
# Adjust regex for Z values less than 1
simplified_z_value = z_value.lstrip('0').rstrip('0').rstrip('.')
if '.' in z_value and not simplified_z_value.startswith('.'):
simplified_z_value = '.' + simplified_z_value
g1_z_regex = fr"G1 Z{simplified_z_value}(?=\s|$)"
if re.search(g1_z_regex, lines[next_g1_z_index]):
m117_line = "M117 L{} M{} G{}".format(layer_number, math.ceil(remaining_filament_m), math.ceil(remaining_filament_g))
lines.insert(next_g1_z_index + 1, m117_line + '\n')
remaining_filament_m -= filament_used_m_per_layer
remaining_filament_g -= filament_used_g_per_layer
m117_added += 1
break
next_g1_z_index += 1
# Write the modified content back to the original file
with open(source_file, "w") as f:
f.writelines(lines)
print(f"Added {m117_added} M117 commands.")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 script.py <gcode-file>")
sys.exit(1)
main(sys.argv[1])

@ -0,0 +1,130 @@
#!/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
def main(source_file):
# Read the entire G-code file into memory
with open(source_file, "r") 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 = float(line.split("=")[1].strip())
filament_used_m = round(filament_used_mm / 1000, 2)
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 = float(line.split("=")[1].strip())
filament_used_g = round(filament_used_g, 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 = float(line.split("=")[1].strip())
elif line.startswith("; filament_density ="):
filament_density = float(line.split("=")[1].strip())
elif line.startswith("; layer_height ="):
layer_height = line.split("=")[1].strip()
layer_height = round(float(layer_height), 2)
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 = 1
i = 0
while i < len(lines):
if lines[i].startswith(';AFTER_LAYER_CHANGE'):
m117_line = "M117 L{} M{} G{}".format(layer_number, 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("No M117 commands were added. Check the G-code for ';AFTER_LAYER_CHANGE' markers.")
else:
print("Added {} M117 commands.".format(m117_added))
# 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") as f:
f.writelines(lines)
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 script.py <gcode-file>")
sys.exit(1)
main(sys.argv[1])
Loading…
Cancel
Save