mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-05 19:36:07 +08:00
Add alteration files to profile ini. (Note, this broke Slic3r support)
This commit is contained in:
parent
13c8bc4583
commit
cfadc75e9c
@ -1,6 +0,0 @@
|
|||||||
M104 S0 ;extruder heat off
|
|
||||||
G91 ;relative positioning
|
|
||||||
G1 Z+10 E-5 F{max_z_speed} ;move Z up a bit and retract filament by 5mm
|
|
||||||
G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way
|
|
||||||
M84 ;steppers off
|
|
||||||
G90 ;absolute positioning
|
|
@ -1,9 +0,0 @@
|
|||||||
;Move to next object on the platform. clear_z is the minimal z height we need to make sure we do not hit any objects.
|
|
||||||
G92 E0
|
|
||||||
G1 Z{clear_z} E-5 F{max_z_speed}
|
|
||||||
G92 E0
|
|
||||||
G1 X{machine_center_x} Y{machine_center_y} F{travel_speed}
|
|
||||||
G1 F200 E5.5
|
|
||||||
G92 E0
|
|
||||||
G1 Z0 F{max_z_speed}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
G21 ;metric values
|
|
||||||
G90 ;absolute positioning
|
|
||||||
|
|
||||||
G28 X0 Y0 ;move X/Y to min endstops
|
|
||||||
G28 Z0 ;move Z to min endstops
|
|
||||||
|
|
||||||
; if your prints start too high, try changing the Z0.0 below
|
|
||||||
; to Z1.0 - the number after the Z is the actual, physical
|
|
||||||
; height of the nozzle in mm. This can take some messing around
|
|
||||||
; with to get just right...
|
|
||||||
G92 X0 Y0 Z0 E0 ;reset software position to front/left/z=0.0
|
|
||||||
G1 Z15.0 F{max_z_speed} ;move the platform down 15mm
|
|
||||||
G92 E0 ;zero the extruded length
|
|
||||||
|
|
||||||
G1 F200 E5 ;extrude 5mm of feed stock
|
|
||||||
G1 F200 E3.5 ;reverse feed stock by 1.5mm
|
|
||||||
G92 E0 ;zero the extruded length again
|
|
||||||
|
|
||||||
;go to the middle of the platform, and move to Z=0 before starting the print.
|
|
||||||
G1 X{machine_center_x} Y{machine_center_y} F{travel_speed}
|
|
||||||
G1 Z0.0 F{max_z_speed}
|
|
@ -32,11 +32,9 @@ class alterationPanel(wx.Panel):
|
|||||||
self.currentFile = self.list.GetSelection()
|
self.currentFile = self.list.GetSelection()
|
||||||
|
|
||||||
def loadFile(self, filename):
|
def loadFile(self, filename):
|
||||||
self.textArea.SetValue(unicode(profile.getAlterationFileContents(filename, False), "utf-8"))
|
self.textArea.SetValue(profile.getAlterationFile(filename))
|
||||||
|
|
||||||
def OnFocusLost(self, e):
|
def OnFocusLost(self, e):
|
||||||
if self.currentFile == self.list.GetSelection():
|
if self.currentFile == self.list.GetSelection():
|
||||||
filename = profile.getAlterationFilePath(self.alterationFileList[self.list.GetSelection()])
|
profile.setAlterationFile(self.alterationFileList[self.list.GetSelection()], self.textArea.GetValue())
|
||||||
f = open(filename, "wb")
|
|
||||||
f.write(self.textArea.GetValue().encode("utf-8"))
|
|
||||||
f.close()
|
|
||||||
|
@ -3,10 +3,10 @@ from __future__ import division
|
|||||||
#Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
|
#Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
|
||||||
import __init__
|
import __init__
|
||||||
|
|
||||||
import ConfigParser, os, traceback, math, re
|
import ConfigParser, os, traceback, math, re, zlib, base64
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
## Profile and preferences functions
|
## Default settings when none are found.
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|
||||||
#Single place to store the defaults, so we have a consistent set of default settings.
|
#Single place to store the defaults, so we have a consistent set of default settings.
|
||||||
@ -53,6 +53,7 @@ profileDefaultSettings = {
|
|||||||
'fill_overlap': '15',
|
'fill_overlap': '15',
|
||||||
'support_rate': '50',
|
'support_rate': '50',
|
||||||
'support_distance': '0.5',
|
'support_distance': '0.5',
|
||||||
|
'support_margin': '3.0',
|
||||||
'joris': 'False',
|
'joris': 'False',
|
||||||
'enable_skin': 'False',
|
'enable_skin': 'False',
|
||||||
'enable_raft': 'False',
|
'enable_raft': 'False',
|
||||||
@ -66,6 +67,58 @@ profileDefaultSettings = {
|
|||||||
'add_start_end_gcode': 'True',
|
'add_start_end_gcode': 'True',
|
||||||
'gcode_extension': 'gcode',
|
'gcode_extension': 'gcode',
|
||||||
}
|
}
|
||||||
|
alterationDefault = {
|
||||||
|
#######################################################################################
|
||||||
|
'start.gcode': """;Start GCode
|
||||||
|
G21 ;metric values
|
||||||
|
G90 ;absolute positioning
|
||||||
|
|
||||||
|
G28 X0 Y0 ;move X/Y to min endstops
|
||||||
|
G28 Z0 ;move Z to min endstops
|
||||||
|
|
||||||
|
; if your prints start too high, try changing the Z0.0 below
|
||||||
|
; to Z1.0 - the number after the Z is the actual, physical
|
||||||
|
; height of the nozzle in mm. This can take some messing around
|
||||||
|
; with to get just right...
|
||||||
|
G92 X0 Y0 Z0 E0 ;reset software position to front/left/z=0.0
|
||||||
|
G1 Z15.0 F{max_z_speed} ;move the platform down 15mm
|
||||||
|
G92 E0 ;zero the extruded length
|
||||||
|
|
||||||
|
G1 F200 E5 ;extrude 5mm of feed stock
|
||||||
|
G1 F200 E3.5 ;reverse feed stock by 1.5mm
|
||||||
|
G92 E0 ;zero the extruded length again
|
||||||
|
|
||||||
|
;go to the middle of the platform, and move to Z=0 before starting the print.
|
||||||
|
G1 X{machine_center_x} Y{machine_center_y} F{travel_speed}
|
||||||
|
G1 Z0.0 F{max_z_speed}
|
||||||
|
""",
|
||||||
|
#######################################################################################
|
||||||
|
'end.gcode': """;End GCode
|
||||||
|
M104 S0 ;extruder heat off
|
||||||
|
G91 ;relative positioning
|
||||||
|
G1 Z+10 E-5 F{max_z_speed} ;move Z up a bit and retract filament by 5mm
|
||||||
|
G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way
|
||||||
|
M84 ;steppers off
|
||||||
|
G90 ;absolute positioning
|
||||||
|
""",
|
||||||
|
#######################################################################################
|
||||||
|
'support_start.gcode': '',
|
||||||
|
'support_end.gcode': '',
|
||||||
|
'cool_start.gcode': '',
|
||||||
|
'cool_end.gcode': '',
|
||||||
|
'replace.csv': '',
|
||||||
|
#######################################################################################
|
||||||
|
'nextobject.gcode': """;Move to next object on the platform. clear_z is the minimal z height we need to make sure we do not hit any objects.
|
||||||
|
G92 E0
|
||||||
|
G1 Z{clear_z} E-5 F{max_z_speed}
|
||||||
|
G92 E0
|
||||||
|
G1 X{machine_center_x} Y{machine_center_y} F{travel_speed}
|
||||||
|
G1 F200 E5.5
|
||||||
|
G92 E0
|
||||||
|
G1 Z0 F{max_z_speed}
|
||||||
|
""",
|
||||||
|
#######################################################################################
|
||||||
|
}
|
||||||
preferencesDefaultSettings = {
|
preferencesDefaultSettings = {
|
||||||
'wizardDone': 'False',
|
'wizardDone': 'False',
|
||||||
'startMode': 'Simple',
|
'startMode': 'Simple',
|
||||||
@ -83,6 +136,10 @@ preferencesDefaultSettings = {
|
|||||||
'filament_cost_meter': '0',
|
'filament_cost_meter': '0',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#########################################################
|
||||||
|
## Profile and preferences functions
|
||||||
|
#########################################################
|
||||||
|
|
||||||
def getDefaultProfilePath():
|
def getDefaultProfilePath():
|
||||||
return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../current_profile.ini"))
|
return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../current_profile.ini"))
|
||||||
|
|
||||||
@ -100,19 +157,31 @@ def loadGlobalProfileFromString(options):
|
|||||||
global globalProfileParser
|
global globalProfileParser
|
||||||
globalProfileParser = ConfigParser.ConfigParser()
|
globalProfileParser = ConfigParser.ConfigParser()
|
||||||
globalProfileParser.add_section('profile')
|
globalProfileParser.add_section('profile')
|
||||||
for option in options.split('#'):
|
globalProfileParser.add_section('alterations')
|
||||||
|
options = base64.b64decode(options)
|
||||||
|
options = zlib.decompress(options)
|
||||||
|
(profileOpts, alt) = options.split('\f', 1)
|
||||||
|
for option in profileOpts.split('\b'):
|
||||||
(key, value) = option.split('=', 1)
|
(key, value) = option.split('=', 1)
|
||||||
globalProfileParser.set('profile', key, value)
|
globalProfileParser.set('profile', key, value)
|
||||||
|
for option in alt.split('\b'):
|
||||||
|
(key, value) = option.split('=', 1)
|
||||||
|
globalProfileParser.set('alterations', key, value)
|
||||||
|
|
||||||
def getGlobalProfileString():
|
def getGlobalProfileString():
|
||||||
global globalProfileParser
|
global globalProfileParser
|
||||||
if not globals().has_key('globalProfileParser'):
|
if not globals().has_key('globalProfileParser'):
|
||||||
loadGlobalProfile(getDefaultProfilePath())
|
loadGlobalProfile(getDefaultProfilePath())
|
||||||
|
|
||||||
ret = []
|
p = []
|
||||||
|
alt = []
|
||||||
for key in globalProfileParser.options('profile'):
|
for key in globalProfileParser.options('profile'):
|
||||||
ret.append(key + "=" + globalProfileParser.get('profile', key))
|
p.append(key + "=" + globalProfileParser.get('profile', key))
|
||||||
return '#'.join(ret)
|
for key in globalProfileParser.options('alterations'):
|
||||||
|
alt.append(key + "=" + globalProfileParser.get('alterations', key))
|
||||||
|
ret = '\b'.join(p) + '\f' + '\b'.join(alt)
|
||||||
|
ret = base64.b64encode(zlib.compress(ret, 9))
|
||||||
|
return ret
|
||||||
|
|
||||||
def getProfileSetting(name):
|
def getProfileSetting(name):
|
||||||
#Check if we have a configuration file loaded, else load the default.
|
#Check if we have a configuration file loaded, else load the default.
|
||||||
@ -221,40 +290,55 @@ def calculateSolidLayerCount():
|
|||||||
#########################################################
|
#########################################################
|
||||||
## Alteration file functions
|
## Alteration file functions
|
||||||
#########################################################
|
#########################################################
|
||||||
def getCuraBasePath():
|
|
||||||
return os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
|
|
||||||
|
|
||||||
def getAlterationFilePath(filename):
|
|
||||||
return os.path.join(getCuraBasePath(), "alterations", filename)
|
|
||||||
|
|
||||||
def replaceTagMatch(m):
|
def replaceTagMatch(m):
|
||||||
tag = m.group(0)[1:-1]
|
tag = m.group(0)[1:-1]
|
||||||
if tag in ['print_speed', 'retraction_speed', 'travel_speed', 'max_z_speed', 'bottom_layer_speed', 'cool_min_feedrate']:
|
if tag in ['print_speed', 'retraction_speed', 'travel_speed', 'max_z_speed', 'bottom_layer_speed', 'cool_min_feedrate']:
|
||||||
return str(getProfileSettingFloat(tag) * 60)
|
return str(getProfileSettingFloat(tag) * 60)
|
||||||
return str(getProfileSettingFloat(tag))
|
return str(getProfileSettingFloat(tag))
|
||||||
|
|
||||||
def getAlterationFileContents(filename, modifyForOutput = True):
|
### Get aleration raw contents. (Used internally in Cura)
|
||||||
"Get the file from the fileName or the lowercase fileName in the alterations directories."
|
def getAlterationFile(filename):
|
||||||
prefix = ''
|
#Check if we have a configuration file loaded, else load the default.
|
||||||
if modifyForOutput:
|
if not globals().has_key('globalProfileParser'):
|
||||||
if filename == 'start.gcode':
|
loadGlobalProfile(getDefaultProfilePath())
|
||||||
#For the start code, hack the temperature and the steps per E value into it. So the temperature is reached before the start code extrusion.
|
|
||||||
#We also set our steps per E here, if configured.
|
if not globalProfileParser.has_option('alterations', filename):
|
||||||
eSteps = float(getPreference('steps_per_e'))
|
if filename in alterationDefault:
|
||||||
if eSteps > 0:
|
default = alterationDefault[filename]
|
||||||
prefix += 'M92 E'+str(eSteps)+'\n'
|
else:
|
||||||
temp = getProfileSettingFloat('print_temperature')
|
print "Missing default alteration for: '" + filename + "'"
|
||||||
if temp > 0:
|
alterationDefault[filename] = ''
|
||||||
prefix += 'M109 S'+str(temp)+'\n'
|
default = ''
|
||||||
elif filename == 'replace.csv':
|
if not globalProfileParser.has_section('alterations'):
|
||||||
prefix = 'M101\nM103\n'
|
globalProfileParser.add_section('alterations')
|
||||||
fullFilename = getAlterationFilePath(filename)
|
#print "Using default for: %s" % (filename)
|
||||||
if os.path.isfile(fullFilename):
|
globalProfileParser.set('alterations', filename, default)
|
||||||
file = open(fullFilename, "r")
|
return unicode(globalProfileParser.get('alterations', filename), "utf-8")
|
||||||
fileText = file.read()
|
|
||||||
file.close()
|
def setAlterationFile(filename, value):
|
||||||
if modifyForOutput:
|
#Check if we have a configuration file loaded, else load the default.
|
||||||
fileText = re.sub("\{[^\}]*\}", replaceTagMatch, fileText)
|
if not globals().has_key('globalProfileParser'):
|
||||||
return prefix + fileText
|
loadGlobalProfile(getDefaultProfilePath())
|
||||||
return prefix
|
if not globalProfileParser.has_section('alterations'):
|
||||||
|
globalProfileParser.add_section('alterations')
|
||||||
|
globalProfileParser.set('alterations', filename, value.encode("utf-8"))
|
||||||
|
saveGlobalProfile(profile.getDefaultProfilePath())
|
||||||
|
|
||||||
|
### Get the alteration file for output. (Used by Skeinforge)
|
||||||
|
def getAlterationFileContents(filename):
|
||||||
|
prefix = ''
|
||||||
|
if filename == 'start.gcode':
|
||||||
|
#For the start code, hack the temperature and the steps per E value into it. So the temperature is reached before the start code extrusion.
|
||||||
|
#We also set our steps per E here, if configured.
|
||||||
|
eSteps = float(getPreference('steps_per_e'))
|
||||||
|
if eSteps > 0:
|
||||||
|
prefix += 'M92 E%f\n' % (eSteps)
|
||||||
|
temp = getProfileSettingFloat('print_temperature')
|
||||||
|
if temp > 0:
|
||||||
|
prefix += 'M109 S%f\n' % (temp)
|
||||||
|
elif filename == 'replace.csv':
|
||||||
|
#Always remove the extruder on/off M codes. These are no longer needed in 5D printing.
|
||||||
|
prefix = 'M101\nM103\n'
|
||||||
|
|
||||||
|
return prefix + re.sub("\{[^\}]*\}", replaceTagMatch, getAlterationFile(filename))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user