Skip to content

Instantly share code, notes, and snippets.

@Nathan22211
Last active June 6, 2023 13:58
Show Gist options
  • Save Nathan22211/3ac8c4db6cee76f916060ea90cc5d863 to your computer and use it in GitHub Desktop.
Save Nathan22211/3ac8c4db6cee76f916060ea90cc5d863 to your computer and use it in GitHub Desktop.
import re
import math
hop = 0.6
minLength = 2
version = "trad"
regexpX = "/X-?[0-9\.]+/"
regexpY = "/Y-?[0-9\.]+/"
regexpZ = "/Z-?[0-9\.]+/"
regexpF = "F[0-9\.]+/"
def process_gcode(gcode_file):
# Open the G-code file for reading
with open(gcode_file, 'r') as file:
gcode = file.readlines()
# Modify the G-code as needed
modified_gcode = []
for line in gcode:
if(line.startswith("G0") or line.startswith("G1")): # Check if G0/G1 present
if("Z" in line): # Search for change of Z height / layer change
oldZ = float(re.findall(regexpZ, line)[0][1:]) # Store current Z height
elif("X" in line and "Y" in line): # Both X and Y positions present - travel or print move
if("E" in line): # Search for E = extrusion move
startedExtrusion = True # Mark that actual printing has started
oldX = float(re.findall(regexpX, line)[0][1:]) # Store current X position
oldY = float(re.findall(regexpY, line)[0][1:]) # Store current Y position
else: # No extrusion - travel move
if(startedExtrusion): # Only progress if printing has actually started
gType = line[:2] # Capture either 'G0' or 'G1' to reuse
nextX = float(re.findall(regexpX, line)[0][1:]) # Store X coordinate for end of travel move
nextY = float(re.findall(regexpY, line)[0][1:]) # Store Y coordinate for end of travel move
travelLength = float(math.sqrt((nextX-oldX)**2 + (nextY-oldY)**2)) # Calculate length of travel move using Pythagoras' theorem
if(travelLength > minLength): # Check if travel meets length requirement, create diagonal Z hop if it does
if("F" in line): # Store feedrate for travel move if it is present
oldF = float(re.findall(regexpF, line)[0][1:]).toFixed(4)
else:
oldF = -1 # If no F parameter, mark as -1
if(version == "trad"):
halfX = (oldX + nextX) / 2 # Calculate half way point for X travel
halfY = (oldY + nextY) / 2 # Calculate half way point for Y travel
oldX = float(re.findall(regexpX, line)[0][1:]) # Store X position in case of multiple travel moves in a row
oldY = float(re.findall(regexpY, line)[0][1:]) # Store Y position in case of multiple travel moves in a row
halfZ = float(oldZ + hop).toFixed(4) # Calculate temporary z height for peak of diagonal travel
if(version == "trad"): # Create movements for a diagonal Z hop halfway between points
newLine = gType+" X"+float(halfX).toFixed(4)+" Y"+float(halfY).toFixed(4)+" Z"+halfZ # Create new G0/G1 travel move to the halfway point
if(oldF != -1): # Check if a feedrate was stored or bogus -1 value
newLine += " F"+oldF # Add F feedrate to the line if possible
newLine += " ; Diagonal Z hop part 1\n" # Add comment
line = newLine+gcode[line]+" Z"+oldZ+" ; Diagonal Z hop part 2" # Add new travel move plus old travel together, adding Z height to the end of the old travel move.
else: # Create movements for a diagonal Z hop above the destination, then lower down
line += " Z"+halfZ+" ; Diagonal Z hop part 1\n"
line += gType+" Z"+oldZ+" ; Diagonal Z hop part 2"
else: # If the travel length was too short, add comment only
line += " ; Travel move of "+str(travelLength)+" below user threshold of "+str(minLength)+" mm"
# Example modification: Add a comment before each layer change
if line.startswith(';LAYER:'):
layer_num = line.split(':')[1].strip()
modified_gcode.append(f'; Custom comment for Layer {layer_num}\n')
# Add more custom modifications here...
modified_gcode.append(line)
# Write the modified G-code to a new file
modified_file = gcode_file.replace('.gcode', '_modified.gcode')
with open(modified_file, 'w') as file:
file.writelines(modified_gcode)
print(f'Post-processing completed. Modified G-code saved as {modified_file}')
# Usage example
gcode_file_path = 'test.gcode'
process_gcode(gcode_file_path)
def procces(gcode):
gcodeArray = gcode.split("\n") # Split gcode line by line into an array
for item in range(len(gcodeArray)): # For each line..
if(gcodeArray[item].startswith("G0") or gcodeArray[item].startswith("G1")): # Check if G0/G1 present
if("Z" in gcodeArray[item]): # Search for change of Z height / layer change
oldZ = float(re.findall(regexpZ, gcodeArray[item])[0][1:]) # Store current Z height
elif("X" in gcodeArray[item] and "Y" in gcodeArray[item]): # Both X and Y positions present - travel or print move
if("E" in gcodeArray[item]): # Search for E = extrusion move
startedExtrusion = True # Mark that actual printing has started
oldX = float(re.findall(regexpX, gcodeArray[item])[0][1:]) # Store current X position
oldY = float(re.findall(regexpY, gcodeArray[item])[0][1:]) # Store current Y position
else: # No extrusion - travel move
if(startedExtrusion): # Only progress if printing has actually started
gType = gcodeArray[item][:2] # Capture either 'G0' or 'G1' to reuse
nextX = float(re.findall(regexpX, gcodeArray[item])[0][1:]) # Store X coordinate for end of travel move
nextY = float(re.findall(regexpY, gcodeArray[item])[0][1:]) # Store Y coordinate for end of travel move
travelLength = float(math.sqrt((nextX-oldX)**2 + (nextY-oldY)**2)) # Calculate length of travel move using Pythagoras' theorem
if(travelLength > minLength): # Check if travel meets length requirement, create diagonal Z hop if it does
if("F" in gcodeArray[item]): # Store feedrate for travel move if it is present
oldF = float(re.findall(regexpF, gcodeArray[item])[0][1:]).toFixed(4)
else:
oldF = -1 # If no F parameter, mark as -1
if(version == "trad"):
halfX = (oldX + nextX) / 2 # Calculate half way point for X travel
halfY = (oldY + nextY) / 2 # Calculate half way point for Y travel
oldX = float(re.findall(regexpX, gcodeArray[item])[0][1:]) # Store X position in case of multiple travel moves in a row
oldY = float(re.findall(regexpY, gcodeArray[item])[0][1:]) # Store Y position in case of multiple travel moves in a row
halfZ = float(oldZ + hop).toFixed(4) # Calculate temporary z height for peak of diagonal travel
if(version == "trad"): # Create movements for a diagonal Z hop halfway between points
newLine = gType+" X"+float(halfX).toFixed(4)+" Y"+float(halfY).toFixed(4)+" Z"+halfZ # Create new G0/G1 travel move to the halfway point
if(oldF != -1): # Check if a feedrate was stored or bogus -1 value
newLine += " F"+oldF # Add F feedrate to the line if possible
newLine += " ; Diagonal Z hop part 1\n" # Add comment
gcodeArray[item] = newLine+gcodeArray[item]+" Z"+oldZ+" ; Diagonal Z hop part 2" # Add new travel move plus old travel together, adding Z height to the end of the old travel move.
else: # Create movements for a diagonal Z hop above the destination, then lower down
gcodeArray[item] += " Z"+halfZ+" ; Diagonal Z hop part 1\n"
gcodeArray[item] += gType+" Z"+oldZ+" ; Diagonal Z hop part 2"
else: # If the travel length was too short, add comment only
gcodeArray[item] += " ; Travel move of "+str(travelLength)+" below user threshold of "+str(minLength)+" mm"
gcode = "\n".join(gcodeArray)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment