Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
executable file 265 lines (251 sloc) 9.65 KB
#!/usr/bin/env python3
import zipfile
import json
import sys
import tempfile
import copy
import math
import re
import traceback
def generateMetajson(temp, vardict):
meta = """
{{
"toolhead_0_temperature": {0},
"toolhead_1_temperature": {1},
"printer_settings": {{
"platform_temperature": {2},
"extruder_temperatures": [
{0},
{1}
],
"heat_platform": {3},
"extruder": "0"
}},
"duration_s": {4},
"total_commands": {5}
}}
"""
meta = meta.format(vardict['tool0temp'], vardict['tool1temp'],
vardict['bedtemp'],
'true' if vardict['heatbed'] else 'false',
int(math.ceil(vardict['time'])),
vardict['toolpathfilelength'])
with open('{}/meta.json'.format(temp), 'w') as metafile:
metafile.write(meta)
return
def generateCommand(function, metadata, parameters, tags):
return copy.deepcopy([
{'command': {
'function': function,
'parameters': parameters,
'metadata': metadata,
'tags': tags
}
}
])
def computeTime(prev, current):
if [current['x'], current['y'], current['z']] == [prev['x'], prev['y'], prev['z']] and current['a'] != prev['a']:
# retraction takes time as well, add it in
# time = sqrt((e2-e1)^2)/feedrate
distance = math.dist([current['a']], [prev['a']])
else:
# get time traveled by the equasion
# time = sqrt((x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2)/feedrate
distance = math.dist([current['x'], current['y'], current['z']],
[prev['x'], prev['y'], prev['z']])
return distance/current['feedrate']
def createToolpath(filename, temp):
corpus = open(filename).readlines()
processed = []
progresslen = len(corpus)
linenum = 0
printline = '{0:>' + str(len(str(progresslen))) + '}/{1} {2:>3.0f}%'
axis = \
{
'a': 0.0,
'feedrate': 0.0,
'x': 0.0,
'y': 0.0,
'z': 0.0
}
tempmetadata = \
{
'index': -1,
'temperature': 0
}
fanstatus = \
{
'index': 0,
'value': False
}
fanduty = \
{
'index': 0,
'value': 0.0
}
printersettings = \
{
'tool0temp': 0,
'tool1temp': 0,
'bedtemp': 0,
'heatbed': False,
'time': 0.0,
'toolpathfilelength': 0
}
printeroffset = \
{
'a': 0.0,
'x': 0.0,
'y': 0.0,
'z': 0.0
}
print('lines processed:')
print(printline.format(0, progresslen, 0.0), end='')
"""
Quick reference:
G0/G1 is move
M104 is set_toolhead_temperature
M140 sets bed temp
M106 is fan_duty (sets fan)
M107 is toggle_fan (off)
M141 sets chamber temperature
G90 toggles absolute positioning
G91 toggles relative positioning
"""
for line in corpus:
if line.find(';') > -1:
line = line[:line.find(';')]
line = [part for part in line.split(' ') if part != '']
if len(line) == 0: # Most likely a blank line
print(''.join(['\b'] * len(
printline.format(linenum,
progresslen,
linenum/progresslen * 100.0))), end='')
linenum += 1
print(printline.format(
linenum, progresslen, linenum/progresslen * 100.0), end='')
continue
if line[0] in ['G0', 'G1']:
if len(line) == 2 and line[1][0] == 'F':
axis['feedrate'] = float(line[1][1:]) / 60.0
else: # Normal move
prev = copy.copy(axis) # copy previous pos for timing
for ax in line[1:]:
if ax[0] == 'E':
axis['a'] = printeroffset['a'] + float(ax[1:])
elif ax[0] == 'X':
axis['x'] = printeroffset['x'] + float(ax[1:])
elif ax[0] == 'Y':
axis['y'] = printeroffset['y'] + float(ax[1:])
elif ax[0] == 'Z':
axis['z'] = printeroffset['z'] + float(ax[1:])
elif ax[0] == 'F':
axis['feedrate'] = float(ax[1:]) / 60.0
processed += generateCommand('move',
{'a': False,
'x': False,
'y': False,
'z': False},
axis,
[])
printersettings['time'] += computeTime(prev, axis)
elif line[0] == 'G92':
for ax in line[1:]:
if ax[0] == 'E':
printeroffset['a'] = axis['a'] + float(ax[1:])
elif ax[0] == 'X':
printeroffset['x'] = axis['x'] + float(ax[1:])
elif ax[0] == 'Y':
printeroffset['y'] = axis['y'] + float(ax[1:])
elif ax[0] == 'Z':
printeroffset['z'] = axis['z'] + float(ax[1:])
elif line[0] == 'M104':
for ax in line[1:]:
if ax[0] == 'T':
tempmetadata['index'] = int(ax[1:])
elif ax[0] == 'S':
tempmetadata['temperature'] = int(ax[1:])
if tempmetadata['index'] != -1:
processed += generateCommand('set_toolhead_temperature',
{},
tempmetadata,
[])
if printersettings['tool{}temp'.format(tempmetadata['index'])] == 0:
printersettings['tool{}temp'.format(tempmetadata['index'])] = tempmetadata['temperature']
else: # there is only one extruder
processed += generateCommand('set_toolhead_temperature',
{},
{'temperature': tempmetadata['temperature']},
[])
printersettings['tool0temp'] = tempmetadata['temperature']
elif line[0] == 'M106':
for ax in line[1:]:
if ax[0] == 'P':
fanduty['index'] = int(ax[1:])
fanstatus['index'] = int(ax[1:])
elif ax[0] == 'S':
fanduty['value'] = float(ax[1:]) / 255
if not fanstatus['value']:
fanstatus['value'] = True
processed += generateCommand('toggle_fan',
{},
fanstatus,
[])
processed += generateCommand('fan_duty',
{},
fanduty,
[])
elif line[0] == 'M107':
fanstatus['value'] = False
processed += generateCommand('toggle_fan',
{},
fanstatus,
[])
elif line[0] == 'M140':
printersettings['bedtemp'] = int(line[1][1:])
printersettings['heatbed'] = True
print(''.join(['\b'] * len(
printline.format(linenum, progresslen, linenum/progresslen * 100.0))), end='')
linenum += 1
print(printline.format(linenum, progresslen, linenum/progresslen * 100.0), end='')
print() # flush all the crap
print('writing toolpath')
compiledtoolpath = json.dumps(processed, sort_keys=False, indent=4)
with open('{}/print.jsontoolpath'.format(temp), 'w') as toolpathfile:
toolpathfile.write(compiledtoolpath)
printersettings['toolpathfilelength'] = len(re.findall('\n',compiledtoolpath))
return printersettings
def packageMBotFile(filename, temp):
with zipfile.ZipFile(filename, 'w', compression=zipfile.ZIP_DEFLATED) as mbotfile:
mbotfile.write('{}/meta.json'.format(temp), arcname='meta.json')
mbotfile.write('{}/print.jsontoolpath'.format(temp), arcname='print.jsontoolpath')
return
def main(argv):
try:
for gcode in argv[1:]:
temp = tempfile.mkdtemp()
output = gcode.replace('.gcode', '.makerbot')
print('Generating toolpath for', output)
vardict = createToolpath(gcode, temp)
print('Generating metadata for', output)
generateMetajson(temp, vardict)
print('Packaging', output)
packageMBotFile(output, temp)
print(output, 'done!')
except Exception as e:
print()
print('An error occurred.')
print('Please report this, as this may be a bug.')
print('Go to https://github.com/sckunkle/mbotmake/issues and add a new issue.')
print('Also, add the contents of {} to a zip file and add it to the issue, if there is any.'.format(temp))
traceback.print_exc()
input()
if __name__ == '__main__':
if len(sys.argv) < 2:
print('Instructions:')
print('Drag and drop your generated gcode file onto this executable.')
print('It will then output a makerbot file in the dir that the original gcode is placed in.')
print('Press enter to continue.')
input()
sys.exit()
main(sys.argv)