Skip to content

Instantly share code, notes, and snippets.

@quantumfrost
Last active June 15, 2023 22:53
Show Gist options
  • Save quantumfrost/bf45a516f707212c9e0fd64d2c7e0293 to your computer and use it in GitHub Desktop.
Save quantumfrost/bf45a516f707212c9e0fd64d2c7e0293 to your computer and use it in GitHub Desktop.
OrcaSlicer M106 bug workaround
## License: GPLv2
## Author: quantumfrost
## This is a post-processing speed to workaround the OrcaSlicer but that causes unnecessary fan speed changes
## See here for more info: https://github.com/SoftFever/OrcaSlicer/issues/1330
## Add this at the bottom of the "Others" tab under "Process" like so:
## "path/to/python" "path/to/script"
import re
import sys, os
m106_pattern = re.compile('[Mm]106\s+[Ss]([0-9]{1,3})')
m107_pattern = re.compile('[Mm]107')
def sanitize(line: str) -> str:
return line.split(';')[0].strip()
def is_command(sanitized_line: str) -> bool:
return sanitized_line and not sanitized_line.startswith(';')
def is_fan_command(sanitized_line: str) -> bool:
s = sanitized_line.lower()
return s.startswith('m106') or s.startswith('m107')
def get_fan_speed(fan_command: str) -> int:
m106 = m106_pattern.fullmatch(fan_command)
m107 = m107_pattern.fullmatch(fan_command)
if m106:
assert m107 is None
return int(m106.group(1))
if m107:
return 0
assert False, 'unexpected fan speed syntax: {0}'.format(fan_command)
def cleanup_fan_speeds(input_file, output_file):
with open(input_file, 'r') as inp, open(output_file, 'w') as out:
last_fan_speed = -1
it = iter(inp)
num_removed = 0
for original_line in it:
s = sanitize(original_line)
# If it's not a fan command, write it as-is
if not is_fan_command(s):
out.write(original_line)
continue
# Look for back-to-back fan speed changes in adjacent lines
while True:
if s is None: # EOF
break
if is_fan_command(s): # update values
speed = get_fan_speed(s)
cmd = original_line
num_removed += 1
elif is_command(s): # non-fan command
break
else: # non-command statement, whitespace or comment
out.write(original_line) # write it but continue looking for more fan cmds
original_line = next(it, None)
s = sanitize(original_line)
# Write the last encountered fan command, if it would change the speed
if speed != last_fan_speed:
out.write(cmd)
last_fan_speed = speed
# Write the line that made us break out of the loop
if original_line:
out.write(original_line)
out.write('; {0} unnecessary fan speed commands removed by cleanup_m106.py\n'.format(num_removed))
def main():
input_file = sys.argv[1]
output_file = input_file + '.temp'
cleanup_fan_speeds(input_file, output_file)
os.replace(output_file, input_file)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment