def setMultiplier(self, remainingOrbitTime):
'Set the feed and flow rate multiplier.'
layerTimeActive = self.getLayerTimeActive()
- self.multiplier = min(1.0, layerTimeActive / (remainingOrbitTime + layerTimeActive))
-
-
+ if remainingOrbitTime + layerTimeActive > 0.00001:
+ self.multiplier = min(1.0, layerTimeActive / (remainingOrbitTime + layerTimeActive))
+ else:
+ self.multiplier = 1.0
def main():
'Display the cool dialog.'
fontSize = wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize()
fontName = wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL).GetFaceName()
self.SetStyleBits(5)
- self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%s,size:%d" % (fontName, fontSize))
- self.StyleSetSpec(1, "fore:#008000,face:%s,size:%d" % (fontName, fontSize))
+ self.StyleSetSpec(0, "face:%s,size:%d" % (fontName, fontSize))
+ self.StyleSetSpec(1, "fore:#008000,face:%s,size:%d" % (fontName, fontSize))
+ self.IndicatorSetStyle(0, wx.stc.STC_INDIC_TT)
+ self.IndicatorSetForeground(0, "#0000FF")
+ self.IndicatorSetStyle(1, wx.stc.STC_INDIC_SQUIGGLE)
+ self.IndicatorSetForeground(1, "#FF0000")
+
+ #GCodes and MCodes as supported by Marlin
+ #GCode 21 is not really supported by Marlin, but we still do not report it as error as it's often used.
+ self.supportedGCodes = [0,1,2,3,4,21,28,90,91,92]
+ self.supportedMCodes = [17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,42,80,81,82,83,84,85,92,104,105,106,107,109,114,115,117,119,140,190,201,202,203,204,205,206,220,221,240,301,302,303,400,500,501,502,503,999]
def OnStyle(self, e):
lineNr = self.LineFromPosition(self.GetEndStyled())
while self.PositionFromLine(lineNr) > -1:
line = self.GetLine(lineNr)
- self.StartStyling(self.PositionFromLine(lineNr), 31)
- self.SetStyling(self.LineLength(lineNr), wx.stc.STC_STYLE_DEFAULT)
+ start = self.PositionFromLine(lineNr)
+ length = self.LineLength(lineNr)
+ self.StartStyling(start, 255)
+ self.SetStyling(length, 0)
if ';' in line:
pos = line.index(';')
- self.StartStyling(self.PositionFromLine(lineNr) + pos, 31)
- self.SetStyling(self.LineLength(lineNr) - pos, 1)
+ self.StartStyling(start + pos, 31)
+ self.SetStyling(length - pos, 1)
+ length = pos
+
+ pos = 0
+ while pos < length:
+ if line[pos] in " \t\n\r":
+ while pos < length and line[pos] in " \t\n\r":
+ pos += 1
+ else:
+ end = pos
+ while end < length and not line[end] in " \t\n\r":
+ end += 1
+ if self.checkGCodePart(line[pos:end], start + pos):
+ self.StartStyling(start + pos, 0x20)
+ self.SetStyling(end - pos, 0x20)
+ pos = end
lineNr += 1
+ def checkGCodePart(self, part, pos):
+ if len(part) < 2:
+ self.StartStyling(pos, 0x40)
+ self.SetStyling(1, 0x40)
+ return True
+ if not part[0] in "GMXYZFESTBPIDCJ":
+ self.StartStyling(pos, 0x40)
+ self.SetStyling(1, 0x40)
+ return True
+ if part[1] == '{':
+ if part[-1] != '}':
+ return True
+ tag = part[2:-1]
+ if not profile.isProfileSetting(tag) and not profile.isPreference(tag):
+ self.StartStyling(pos + 2, 0x40)
+ self.SetStyling(len(tag), 0x40)
+ return True
+ elif part[0] in "GM":
+ try:
+ code = int(part[1:])
+ except (ValueError):
+ self.StartStyling(pos + 1, 0x40)
+ self.SetStyling(len(part) - 1, 0x40)
+ return True
+ if part[0] == 'G':
+ if not code in self.supportedGCodes:
+ return True
+ if part[0] == 'M':
+ if not code in self.supportedMCodes:
+ return True
+ else:
+ try:
+ float(part[1:])
+ except (ValueError):
+ self.StartStyling(pos + 1, 0x40)
+ self.SetStyling(len(part) - 1, 0x40)
+ return True
+ return False
+
def GetValue(self):
return self.GetText()
return (maxX - minX) + (maxY - minY)\r
\r
def OnSlice(self, e):\r
- oldProfile = profile.getGlobalProfileString()\r
- \r
- put = profile.putProfileSetting\r
+ put = profile.setTempOverride\r
\r
put('model_multiply_x', '1')\r
put('model_multiply_y', '1')\r
actionList.append(action)\r
\r
#Restore the old profile.\r
- profile.loadGlobalProfileFromString(oldProfile)\r
+ profile.resetTempOverride()\r
\r
dlg=wx.FileDialog(self, "Save project gcode file", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)\r
dlg.SetWildcard("GCode file (*.gcode)|*.gcode")\r
self.sizer.Add(self.statusText, (0,0), flag=wx.ALIGN_CENTER)\r
self.sizer.Add(self.progressGauge, (1, 0), flag=wx.EXPAND)\r
self.sizer.Add(self.progressGauge2, (2, 0), flag=wx.EXPAND)\r
+\r
self.sizer.Add(self.abortButton, (3,0), flag=wx.ALIGN_CENTER)\r
self.sizer.AddGrowableCol(0)\r
self.sizer.AddGrowableRow(0)\r
\r
def OnRun(self):\r
resultFile = open(self.resultFilename, "w")\r
- put = profile.putProfileSetting\r
+ put = profile.setTempOverride\r
for action in self.actionList:\r
p = subprocess.Popen(action.sliceCmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)\r
line = p.stdout.readline()\r
line = p.stdout.readline()\r
self.returnCode = p.wait()\r
\r
- oldProfile = profile.getGlobalProfileString()\r
put('machine_center_x', action.centerX - self.extruderOffset[action.extruder].x)\r
put('machine_center_y', action.centerY - self.extruderOffset[action.extruder].y)\r
put('clear_z', action.clearZ)\r
resultFile.write(';TYPE:CUSTOM\n')\r
resultFile.write(profile.getAlterationFileContents('nextobject.gcode'))\r
resultFile.write(';PRINTNR:%d\n' % self.actionList.index(action))\r
- profile.loadGlobalProfileFromString(oldProfile)\r
+ profile.resetTempOverride()\r
\r
f = open(action.filename[: action.filename.rfind('.')] + "_export.project_tmp", "r")\r
data = f.read(4096)\r
resultFile.close()\r
self.abort = True\r
sliceTime = time.time() - self.sliceStartTime\r
- wx.CallAfter(self.statusText.SetLabel, 'Slicing took: %d:%d' % (sliceTime / 60, sliceTime % 60))\r
+ wx.CallAfter(self.statusText.SetLabel, 'Slicing took: %02d:%02d' % (sliceTime / 60, sliceTime % 60))\r
wx.CallAfter(self.abortButton.SetLabel, 'Close')\r
\r
def main():\r
if profile.getPreference('save_profile') == 'True':
profile.saveGlobalProfile(self.filelist[0][: self.filelist[0].rfind('.')] + "_profile.ini")
cmdList = []
- oldProfile = profile.getGlobalProfileString()
for filename in self.filelist:
idx = self.filelist.index(filename)
print filename, idx
if idx > 0:
- profile.putProfileSetting('fan_enabled', 'False')
- profile.putProfileSetting('skirt_line_count', '0')
- profile.putProfileSetting('machine_center_x', profile.getProfileSettingFloat('machine_center_x') - profile.getPreferenceFloat('extruder_offset_x%d' % (idx)))
- profile.putProfileSetting('machine_center_y', profile.getProfileSettingFloat('machine_center_y') - profile.getPreferenceFloat('extruder_offset_y%d' % (idx)))
- profile.putProfileSetting('alternative_center', self.filelist[0])
+ profile.setTempOverride('fan_enabled', 'False')
+ profile.setTempOverride('skirt_line_count', '0')
+ profile.setTempOverride('machine_center_x', profile.getProfileSettingFloat('machine_center_x') - profile.getPreferenceFloat('extruder_offset_x%d' % (idx)))
+ profile.setTempOverride('machine_center_y', profile.getProfileSettingFloat('machine_center_y') - profile.getPreferenceFloat('extruder_offset_y%d' % (idx)))
+ profile.setTempOverride('alternative_center', self.filelist[0])
if len(self.filelist) > 1:
- profile.putProfileSetting('add_start_end_gcode', 'False')
- profile.putProfileSetting('gcode_extension', 'multi_extrude_tmp')
+ profile.setTempOverride('add_start_end_gcode', 'False')
+ profile.setTempOverride('gcode_extension', 'multi_extrude_tmp')
cmdList.append(sliceRun.getSliceCommand(filename))
- profile.loadGlobalProfileFromString(oldProfile)
+ profile.resetTempOverride()
self.thread = WorkerThread(self, filelist, cmdList)
def OnAbort(self, e):
resultFile.write(';TYPE:CUSTOM\n')
resultFile.write(profile.getAlterationFileContents('start.gcode'))
for filename in self.filelist:
- files.append(open(filename[:filename.rfind('.')]+'_export.multi_extrude_tmp', "r"))
+ if os.path.isfile(filename[:filename.rfind('.')]+'_export.multi_extrude_tmp'):
+ files.append(open(filename[:filename.rfind('.')]+'_export.multi_extrude_tmp', "r"))
+ else:
+ return
currentExtruder = 0
resultFile.write('T%d\n' % (currentExtruder))
\r
'add_start_end_gcode': 'True',\r
'gcode_extension': 'gcode',\r
+ 'alternative_center': '',\r
+ 'clear_z': '0.0',\r
+ 'extruder': '0',\r
}\r
alterationDefault = {\r
#######################################################################################\r
## Profile and preferences functions\r
#########################################################\r
\r
+## Profile functions\r
def getDefaultProfilePath():\r
return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../current_profile.ini"))\r
\r
\r
p = []\r
alt = []\r
+ tempDone = []\r
if globalProfileParser.has_section('profile'):\r
for key in globalProfileParser.options('profile'):\r
- p.append(key + "=" + globalProfileParser.get('profile', key))\r
+ if key in tempOverride:\r
+ p.append(key + "=" + unicode(tempOverride[key]))\r
+ tempDone.append(key)\r
+ else:\r
+ p.append(key + "=" + globalProfileParser.get('profile', key))\r
if globalProfileParser.has_section('alterations'):\r
for key in globalProfileParser.options('alterations'):\r
- alt.append(key + "=" + globalProfileParser.get('alterations', key))\r
+ if key in tempOverride:\r
+ p.append(key + "=" + tempOverride[key])\r
+ tempDone.append(key)\r
+ else:\r
+ alt.append(key + "=" + globalProfileParser.get('alterations', key))\r
+ for key in tempOverride:\r
+ if key not in tempDone:\r
+ p.append(key + "=" + unicode(tempOverride[key]))\r
ret = '\b'.join(p) + '\f' + '\b'.join(alt)\r
ret = base64.b64encode(zlib.compress(ret, 9))\r
return ret\r
\r
def getProfileSetting(name):\r
+ if name in tempOverride:\r
+ return unicode(tempOverride[name])\r
#Check if we have a configuration file loaded, else load the default.\r
if not globals().has_key('globalProfileParser'):\r
loadGlobalProfile(getDefaultProfilePath())\r
globalProfileParser.add_section('profile')\r
globalProfileParser.set('profile', name, str(value))\r
\r
+def isProfileSetting(name):\r
+ if name in profileDefaultSettings:\r
+ return True\r
+ return False\r
+\r
+## Preferences functions\r
global globalPreferenceParser\r
globalPreferenceParser = None\r
\r
def getPreferenceFloat(name):\r
try:\r
return float(eval(getPreference(name), {}, {}))\r
-\r
except (ValueError, SyntaxError):\r
return 0.0\r
\r
def getPreference(name):\r
+ if name in tempOverride:\r
+ return unicode(tempOverride[name])\r
global globalPreferenceParser\r
if globalPreferenceParser == None:\r
globalPreferenceParser = ConfigParser.ConfigParser()\r
globalPreferenceParser.set('preference', name, unicode(value).encode("utf-8"))\r
globalPreferenceParser.write(open(getPreferencePath(), 'w'))\r
\r
+def isPreference(name):\r
+ if name in preferencesDefaultSettings:\r
+ return True\r
+ return False\r
+\r
+## Temp overrides for multi-extruder slicing and the project planner.\r
+tempOverride = {}\r
+def setTempOverride(name, value):\r
+ tempOverride[name] = value\r
+def resetTempOverride():\r
+ tempOverride = {}\r
+\r
#########################################################\r
## Utility functions to calculate common profile values\r
#########################################################\r
tag = m.group(0)[1:-1]\r
if tag in ['print_speed', 'retraction_speed', 'travel_speed', 'max_z_speed', 'bottom_layer_speed', 'cool_min_feedrate']:\r
return str(getProfileSettingFloat(tag) * 60)\r
- return str(getProfileSettingFloat(tag))\r
+ if isProfileSetting(tag):\r
+ return str(getProfileSettingFloat(tag))\r
+ if isPreference(tag):\r
+ return str(getProfileSettingFloat(tag))\r
+ return tag\r
\r
### Get aleration raw contents. (Used internally in Cura)\r
def getAlterationFile(filename):\r