mirror of https://github.com/mriscoc/Ender3V2S1
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.5 KiB
Python
136 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Orca / Prusa / Super Slicer post-processor script for the Professional Firmware
|
|
# URL: https://github.com/mriscoc/Ender3V2S1
|
|
# Miguel A. Risco-Castillo
|
|
# version: 2.2
|
|
# date: 2023/12/10
|
|
#
|
|
# Contains code from the jpg re-encoder thumbnail post processor script:
|
|
# github.com/alexqzd/Marlin/blob/Gcode-preview/Display%20firmware/gcode_thumb_to_jpg.py
|
|
# ------------------------------------------------------------------------------
|
|
|
|
import sys
|
|
import re
|
|
import os
|
|
import base64
|
|
import io
|
|
import subprocess
|
|
|
|
try:
|
|
from PIL import Image
|
|
except ImportError:
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", "Pillow"])
|
|
from PIL import Image
|
|
|
|
def install(package):
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
|
|
|
|
# Get the g-code source file name
|
|
sourceFile = sys.argv[1]
|
|
|
|
# Read the ENTIRE g-code file into memory
|
|
with open(sourceFile, "r") as f:
|
|
lines = f.read()
|
|
|
|
thumb_expresion = '; thumbnail begin.*?\n((.|\n)*?); thumbnail end'
|
|
size_expresion = '; thumbnail begin [0-9]+x[0-9]+ [0-9]+'
|
|
size_expresion_group = '; thumbnail begin [0-9]+x[0-9]+ ([0-9]+)'
|
|
|
|
thumb_matches = re.findall(thumb_expresion, lines)
|
|
size_matches = re.findall(size_expresion, lines)
|
|
|
|
def encodedStringToGcodeComment(encodedString):
|
|
n = 78
|
|
return '; ' + '\n; '.join(encodedString[i:i+n] for i in range(0, len(encodedString), n)) + '\n'
|
|
|
|
|
|
for idx, match in enumerate(thumb_matches):
|
|
original = match[0]
|
|
encoded = original.replace("; ", "")
|
|
encoded = encoded.replace("\n", "")
|
|
encoded = encoded.replace("\r", "")
|
|
decoded = base64.b64decode(encoded)
|
|
img_png = Image.open(io.BytesIO(decoded))
|
|
img_png_rgb = img_png.convert('RGB')
|
|
img_byte_arr = io.BytesIO()
|
|
img_png_rgb.save(img_byte_arr, format='jpeg')
|
|
img_byte_arr = img_byte_arr.getvalue()
|
|
encodedjpg = base64.b64encode(img_byte_arr).decode("utf-8")
|
|
encodedjpg_gcode = encodedStringToGcodeComment(encodedjpg)
|
|
lines = lines.replace(original, encodedjpg_gcode)
|
|
|
|
size_match = size_matches[idx]
|
|
size = re.findall(size_expresion_group, size_match)
|
|
new_size = size_match.replace(size[0], str(len(encodedjpg)))
|
|
lines = lines.replace(size_match, new_size)
|
|
|
|
#If the thumbnail was already a JPG, reformat block start
|
|
lines = lines.replace("thumbnail_JPG", "thumbnail")
|
|
|
|
#Prepare header values
|
|
ph = re.search('; generated by (.*)\n', lines)
|
|
if ph is not None : lines = lines.replace(ph[0], "")
|
|
|
|
time = 0
|
|
match = re.search('; estimated printing time \(normal mode\) = (.*)\n', lines)
|
|
if match is not None :
|
|
h = re.search('(\d+)h',match[1])
|
|
h = int(h[1]) if h is not None else 0
|
|
m = re.search('(\d+)m',match[1])
|
|
m = int(m[1]) if m is not None else 0
|
|
s = re.search('(\d+)s',match[1])
|
|
s = int(s[1]) if s is not None else 0
|
|
time = h*3600+m*60+s
|
|
|
|
match = re.search('; filament used \[mm\] = ([0-9.]+)', lines)
|
|
filament = float(match[1])/1000 if match is not None else 0
|
|
|
|
match = os.getenv('SLIC3R_LAYER_HEIGHT')
|
|
layer = float(match) if match is not None else 0
|
|
|
|
match = re.search('; First layer print x min = ([0-9.]+)', lines)
|
|
minx = float(match[1]) if match is not None else 0
|
|
|
|
match = re.search('; First layer print y min = ([0-9.]+)', lines)
|
|
miny = float(match[1]) if match is not None else 0
|
|
|
|
match = re.search('; First layer print x max = ([0-9.]+)', lines)
|
|
maxx = float(match[1]) if match is not None else 0
|
|
|
|
match = re.search('; First layer print y max = ([0-9.]+)', lines)
|
|
maxy = float(match[1]) if match is not None else 0
|
|
|
|
match = re.search('; Total layer count = ([0-9.]+)', lines)
|
|
totlc = float(match[1]) if match is not None else 0
|
|
|
|
maxz = layer*totlc
|
|
minz = 0
|
|
|
|
#Generate output file
|
|
try:
|
|
with open(sourceFile, "w+") as of:
|
|
# Write header values
|
|
if ph is not None : of.write(ph[0])
|
|
of.write(';FLAVOR:Marlin\n')
|
|
of.write(';TIME:{:d}\n'.format(time))
|
|
of.write(';Filament used: {:.6f}\n'.format(filament))
|
|
of.write(';Layer height: {:.2f}\n'.format(layer))
|
|
of.write(';MINX:{:.3f}\n'.format(minx))
|
|
of.write(';MINY:{:.3f}\n'.format(miny))
|
|
of.write(';MINZ:{:.3f}\n'.format(minz))
|
|
of.write(';MAXX:{:.3f}\n'.format(maxx))
|
|
of.write(';MAXY:{:.3f}\n'.format(maxy))
|
|
of.write(';MAXZ:{:.3f}\n'.format(maxz))
|
|
of.write(';POSTPROCESSED\n')
|
|
of.write(';Header generated for the MRiscoC Professional Firmware\n')
|
|
of.write(';https://github.com/mriscoc/Ender3V2S1')
|
|
of.write(lines)
|
|
except:
|
|
print('Error writing output file')
|
|
input()
|
|
finally:
|
|
of.close()
|
|
f.close()
|