I have a large gcode/text file. I want to search the file and if a line contains the word 'layer' like:
; layer 1, Z = 0.500
Then I want to add this below it once every x amount of layers:
;Clean Nozzle
G0 X30 Y-47 F10000
G0 X70 Y-47
G0 X30 Y-47
This will tell the nozzle of a 3D printer to pass over a fixed wire brush to clean the nozzle. I don't want it to do this every layer, just once every X amount of layers.
My Python Script so far looks very confusing and doesn't work, so I think I should re-start from scratch. My plan was:
Code so far:
#!/usr/bin/env python3
import mmap
LayerCount = 1 #Start layer counter at 1, this will get increased every time a line includes the word 'layer' (later in this script)
index = 0
#open gcode file
with open('C:\\Users\\Adam.Widdowson\\Desktop\\gcode\\TestSmall.gcode', 'rb', 0) as file, \
mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as s: #weird mmap stuff is aparently better for large files
contents = file.readlines() #Makes a list called 'contents' containing each value in the gcode
print('List:')
print(contents) #Prints to terminal for sense checking
#Create new gcode file containing the info.
with open(r'C:\\Users\\Adam.Widdowson\\Desktop\\gcode\\New.gcode', 'w') as fp:
for item in contents: #I think this takes each item in the list 'contents' and makes 'item' = it
itemSTR=str(item, 'utf-8') #Convert item into a utf-8 string
print('----------------------------------------')
print('index of item:')
print(index)
print('Item in list:')
print(itemSTR)
print('Layer:')
print(LayerCount)
index = index + 1
if 'layer' in itemSTR:
print('Layer Change')
contents.insert(index,'Clean Nozzle')
LayerCount = LayerCount + 1
fp.write("%s\n" % item) # write each item on a new line
print('done') #Prints done to terminalDone'
Thanks
I think you should be okay reading a 78MB file. I don't usually think about "good for handling large" until I'm sure I'm going over 2GB. (I'm a data scientist and over 2GB is a daily thing for me.) My suggestion would be to use the modulus operator, %
, to determine whether to insert text. Modulus returns the remainder of division, so if x % 10 == 0
is true, you are on an iteration divisible by ten.
# LayerCount = 1
index = 0
acc_lines = '' # short for accumulated lines.
frequency = 10
path = 'C:\\Users\\Adam.Widdowson\\Desktop\\gcode\\TestSmall.gcode'
new_path = r'C:\\Users\\Adam.Widdowson\\Desktop\\gcode\\New.gcode'
# use triple " for handy preformatted text.
clean_cmd = """ ;Clean Nozzle
G0 X30 Y-47 F10000
G0 X70 Y-47
G0 X30 Y-47
"""
#open gcode file
with open(path, 'rb') as file:
for line in file.readlines():
acc_lines = acc_lines + line
if line.contains('layer'):
index += 1
if index % frequency == 0:
acc_lines = acc_lines + clean_cmd
# you are reading bytes but writing plain text in your code above.
# Not sure why that is. No cause for alarm, but it something is amiss
# when reading the new_path file later, check on this.
with open(new_path, 'w') as file:
file.write(acc_lines)