From 92c42d1afa7f8a7c2aa05b6a1b62fa7f1c554faf Mon Sep 17 00:00:00 2001 From: daid Date: Wed, 2 May 2012 14:14:41 +0200 Subject: [PATCH 1/6] Only show gcode buttons when GCode is loaded. Only show layer selection in GCode and mixed view. Fixed #87 --- Cura/gui/preview3d.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Cura/gui/preview3d.py b/Cura/gui/preview3d.py index ec525096..ee1ed79e 100644 --- a/Cura/gui/preview3d.py +++ b/Cura/gui/preview3d.py @@ -63,7 +63,6 @@ class previewPanel(wx.Panel): self.xrayViewButton = toolbarUtil.RadioButton(self.toolbar, group, 'view-xray-on.png', 'view-xray-off.png', 'X-Ray view', callback=self.OnViewChange) self.gcodeViewButton = toolbarUtil.RadioButton(self.toolbar, group, 'view-gcode-on.png', 'view-gcode-off.png', 'GCode view', callback=self.OnViewChange) self.mixedViewButton = toolbarUtil.RadioButton(self.toolbar, group, 'view-mixed-on.png', 'view-mixed-off.png', 'Mixed model/GCode view', callback=self.OnViewChange) - self.OnViewChange() self.toolbar.AddSeparator() self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS) @@ -107,7 +106,7 @@ class previewPanel(wx.Panel): self.toolbar2.AddControl(self.rotate) self.toolbar2.Realize() - self.updateToolbar() + self.OnViewChange() sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.toolbar, 0, flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, border=1) @@ -272,7 +271,9 @@ class previewPanel(wx.Panel): pass def updateToolbar(self): - self.layerSpin.Show(self.gcode != None) + self.gcodeViewButton.Show(self.gcode != None) + self.mixedViewButton.Show(self.gcode != None) + self.layerSpin.Show(self.glCanvas.viewMode == "GCode" or self.glCanvas.viewMode == "Mixed") if self.gcode != None: self.layerSpin.SetRange(1, len(self.gcode.layerList)) self.toolbar.Realize() @@ -288,6 +289,7 @@ class previewPanel(wx.Panel): self.glCanvas.viewMode = "GCode" elif self.mixedViewButton.GetValue(): self.glCanvas.viewMode = "Mixed" + self.updateToolbar() self.glCanvas.Refresh() def updateModelTransform(self, f=0): From 5e8a0c92c088711b1e84a503f838d185f8c5518c Mon Sep 17 00:00:00 2001 From: daid Date: Wed, 2 May 2012 14:21:21 +0200 Subject: [PATCH 2/6] Add loaded filename into title bar. --- Cura/gui/mainWindow.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cura/gui/mainWindow.py b/Cura/gui/mainWindow.py index 3cd22ab2..34d2f965 100644 --- a/Cura/gui/mainWindow.py +++ b/Cura/gui/mainWindow.py @@ -86,6 +86,7 @@ class mainWindow(configBase.configWindowBase): if profile.getPreference('lastFile') != '': self.filelist = profile.getPreference('lastFile').split(';') + self.SetTitle(self.filelist[-1] + ' - Cura - ' + version.getVersion()) else: self.filelist = [] self.progressPanelList = [] @@ -299,6 +300,7 @@ class mainWindow(configBase.configWindowBase): filelist.append(self._showOpenDialog("Open file to print")) if filelist[-1] == False: return + self.SetTitle(filelist[-1] + ' - Cura - ' + version.getVersion()) self.filelist = filelist profile.putPreference('lastFile', ';'.join(self.filelist)) self.preview3d.loadModelFiles(self.filelist) From a5237fea44184511903c4d88b7ee0621b62e1d1e Mon Sep 17 00:00:00 2001 From: daid Date: Wed, 2 May 2012 17:15:55 +0200 Subject: [PATCH 3/6] Very basic syntax highlight for comments in the GCode editor for start/end code. --- Cura/gui/alterationPanel.py | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Cura/gui/alterationPanel.py b/Cura/gui/alterationPanel.py index c102f19b..2fa320c4 100644 --- a/Cura/gui/alterationPanel.py +++ b/Cura/gui/alterationPanel.py @@ -1,4 +1,4 @@ -import wx +import wx, wx.stc import sys,math,threading,os from util import profile @@ -10,12 +10,21 @@ class alterationPanel(wx.Panel): self.alterationFileList = ['start.gcode', 'end.gcode', 'support_start.gcode', 'support_end.gcode', 'nextobject.gcode', 'replace.csv'] self.currentFile = None - self.textArea = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_DONTWRAP|wx.TE_PROCESS_TAB) - self.textArea.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)) + #self.textArea = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_DONTWRAP|wx.TE_PROCESS_TAB) + #self.textArea.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)) + self.textArea = wx.stc.StyledTextCtrl(self) + self.textArea.SetLexer(wx.stc.STC_LEX_CONTAINER) self.list = wx.ListBox(self, choices=self.alterationFileList, style=wx.LB_SINGLE) self.list.SetSelection(0) self.Bind(wx.EVT_LISTBOX, self.OnSelect, self.list) self.textArea.Bind(wx.EVT_KILL_FOCUS, self.OnFocusLost, self.textArea) + self.textArea.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyle) + + 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.textArea.SetStyleBits(5) + self.textArea.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%s,size:%d" % (fontName, fontSize)) + self.textArea.StyleSetSpec(1, "fore:#008000,face:%s,size:%d" % (fontName, fontSize)) sizer = wx.GridBagSizer() sizer.Add(self.list, (0,0), span=(1,1), flag=wx.EXPAND) @@ -32,9 +41,24 @@ class alterationPanel(wx.Panel): self.currentFile = self.list.GetSelection() def loadFile(self, filename): - self.textArea.SetValue(profile.getAlterationFile(filename)) + #self.textArea.SetValue(profile.getAlterationFile(filename)) + self.textArea.SetText(profile.getAlterationFile(filename)) def OnFocusLost(self, e): if self.currentFile == self.list.GetSelection(): - profile.setAlterationFile(self.alterationFileList[self.list.GetSelection()], self.textArea.GetValue()) + #profile.setAlterationFile(self.alterationFileList[self.list.GetSelection()], self.textArea.GetValue()) + profile.setAlterationFile(self.alterationFileList[self.list.GetSelection()], self.textArea.GetText()) + + def OnStyle(self, e): + #for lineNr in xrange(0, + lineNr = self.textArea.LineFromPosition(self.textArea.GetEndStyled()) + while self.textArea.PositionFromLine(lineNr) > -1: + line = self.textArea.GetLine(lineNr) + self.textArea.StartStyling(self.textArea.PositionFromLine(lineNr), 31) + self.textArea.SetStyling(self.textArea.LineLength(lineNr), wx.stc.STC_STYLE_DEFAULT) + if ';' in line: + pos = line.index(';') + self.textArea.StartStyling(self.textArea.PositionFromLine(lineNr) + pos, 31) + self.textArea.SetStyling(self.textArea.LineLength(lineNr) - pos, 1) + lineNr += 1 From 9385aa8c2513d5891ad47a72e94ccb0ac794b592 Mon Sep 17 00:00:00 2001 From: daid Date: Wed, 2 May 2012 17:54:29 +0200 Subject: [PATCH 4/6] Move gcode formated text to own file. --- Cura/gui/alterationPanel.py | 32 +++++--------------------------- Cura/gui/gcodeTextArea.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 Cura/gui/gcodeTextArea.py diff --git a/Cura/gui/alterationPanel.py b/Cura/gui/alterationPanel.py index 2fa320c4..5f5098d6 100644 --- a/Cura/gui/alterationPanel.py +++ b/Cura/gui/alterationPanel.py @@ -1,6 +1,7 @@ -import wx, wx.stc +import wx import sys,math,threading,os +from gui import gcodeTextArea from util import profile class alterationPanel(wx.Panel): @@ -12,19 +13,11 @@ class alterationPanel(wx.Panel): #self.textArea = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_DONTWRAP|wx.TE_PROCESS_TAB) #self.textArea.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)) - self.textArea = wx.stc.StyledTextCtrl(self) - self.textArea.SetLexer(wx.stc.STC_LEX_CONTAINER) + self.textArea = gcodeTextArea.GcodeTextArea(self) self.list = wx.ListBox(self, choices=self.alterationFileList, style=wx.LB_SINGLE) self.list.SetSelection(0) self.Bind(wx.EVT_LISTBOX, self.OnSelect, self.list) self.textArea.Bind(wx.EVT_KILL_FOCUS, self.OnFocusLost, self.textArea) - self.textArea.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyle) - - 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.textArea.SetStyleBits(5) - self.textArea.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%s,size:%d" % (fontName, fontSize)) - self.textArea.StyleSetSpec(1, "fore:#008000,face:%s,size:%d" % (fontName, fontSize)) sizer = wx.GridBagSizer() sizer.Add(self.list, (0,0), span=(1,1), flag=wx.EXPAND) @@ -41,24 +34,9 @@ class alterationPanel(wx.Panel): self.currentFile = self.list.GetSelection() def loadFile(self, filename): - #self.textArea.SetValue(profile.getAlterationFile(filename)) - self.textArea.SetText(profile.getAlterationFile(filename)) + self.textArea.SetValue(profile.getAlterationFile(filename)) def OnFocusLost(self, e): if self.currentFile == self.list.GetSelection(): - #profile.setAlterationFile(self.alterationFileList[self.list.GetSelection()], self.textArea.GetValue()) - profile.setAlterationFile(self.alterationFileList[self.list.GetSelection()], self.textArea.GetText()) - - def OnStyle(self, e): - #for lineNr in xrange(0, - lineNr = self.textArea.LineFromPosition(self.textArea.GetEndStyled()) - while self.textArea.PositionFromLine(lineNr) > -1: - line = self.textArea.GetLine(lineNr) - self.textArea.StartStyling(self.textArea.PositionFromLine(lineNr), 31) - self.textArea.SetStyling(self.textArea.LineLength(lineNr), wx.stc.STC_STYLE_DEFAULT) - if ';' in line: - pos = line.index(';') - self.textArea.StartStyling(self.textArea.PositionFromLine(lineNr) + pos, 31) - self.textArea.SetStyling(self.textArea.LineLength(lineNr) - pos, 1) - lineNr += 1 + profile.setAlterationFile(self.alterationFileList[self.list.GetSelection()], self.textArea.GetValue()) diff --git a/Cura/gui/gcodeTextArea.py b/Cura/gui/gcodeTextArea.py new file mode 100644 index 00000000..e6d85655 --- /dev/null +++ b/Cura/gui/gcodeTextArea.py @@ -0,0 +1,36 @@ +import wx, wx.stc +import sys,math,os + +from util import profile + +class GcodeTextArea(wx.stc.StyledTextCtrl): + def __init__(self, parent): + super(GcodeTextArea, self).__init__(parent) + + self.SetLexer(wx.stc.STC_LEX_CONTAINER) + self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyle) + + 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)) + + 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) + if ';' in line: + pos = line.index(';') + self.StartStyling(self.PositionFromLine(lineNr) + pos, 31) + self.SetStyling(self.LineLength(lineNr) - pos, 1) + lineNr += 1 + + def GetValue(self): + return self.GetText() + + def SetValue(self, s): + self.SetText(s) + From e29261a992d85b599af3f21357d93d6504903079 Mon Sep 17 00:00:00 2001 From: daid Date: Thu, 3 May 2012 12:29:55 +0200 Subject: [PATCH 5/6] Added more GCode validation to GCode editor. Made temp changes to profile really temp so they are never stored in the ini file. Fixed crash bug in skeinforge where there is no layer code. --- .../skeinforge_plugins/craft_plugins/cool.py | 7 +- Cura/gui/gcodeTextArea.py | 77 +++++++++++++++++-- Cura/gui/projectPlanner.py | 14 ++-- Cura/gui/sliceProgessPanel.py | 22 +++--- Cura/util/profile.py | 49 +++++++++++- 5 files changed, 138 insertions(+), 31 deletions(-) diff --git a/Cura/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py b/Cura/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py index f018e0c6..eb363a8c 100644 --- a/Cura/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py +++ b/Cura/cura_sf/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py @@ -406,9 +406,10 @@ class CoolSkein: 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.' diff --git a/Cura/gui/gcodeTextArea.py b/Cura/gui/gcodeTextArea.py index e6d85655..6cb108a1 100644 --- a/Cura/gui/gcodeTextArea.py +++ b/Cura/gui/gcodeTextArea.py @@ -13,21 +13,86 @@ class GcodeTextArea(wx.stc.StyledTextCtrl): 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() diff --git a/Cura/gui/projectPlanner.py b/Cura/gui/projectPlanner.py index 9b664ce5..a198a76d 100644 --- a/Cura/gui/projectPlanner.py +++ b/Cura/gui/projectPlanner.py @@ -285,9 +285,7 @@ class projectPlanner(wx.Frame): return (maxX - minX) + (maxY - minY) def OnSlice(self, e): - oldProfile = profile.getGlobalProfileString() - - put = profile.putProfileSetting + put = profile.setTempOverride put('model_multiply_x', '1') put('model_multiply_y', '1') @@ -319,7 +317,7 @@ class projectPlanner(wx.Frame): actionList.append(action) #Restore the old profile. - profile.loadGlobalProfileFromString(oldProfile) + profile.resetTempOverride() dlg=wx.FileDialog(self, "Save project gcode file", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE) dlg.SetWildcard("GCode file (*.gcode)|*.gcode") @@ -670,6 +668,7 @@ class ProjectSliceProgressWindow(wx.Frame): self.sizer.Add(self.statusText, (0,0), flag=wx.ALIGN_CENTER) self.sizer.Add(self.progressGauge, (1, 0), flag=wx.EXPAND) self.sizer.Add(self.progressGauge2, (2, 0), flag=wx.EXPAND) + self.sizer.Add(self.abortButton, (3,0), flag=wx.ALIGN_CENTER) self.sizer.AddGrowableCol(0) self.sizer.AddGrowableRow(0) @@ -702,7 +701,7 @@ class ProjectSliceProgressWindow(wx.Frame): def OnRun(self): resultFile = open(self.resultFilename, "w") - put = profile.putProfileSetting + put = profile.setTempOverride for action in self.actionList: p = subprocess.Popen(action.sliceCmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) line = p.stdout.readline() @@ -727,7 +726,6 @@ class ProjectSliceProgressWindow(wx.Frame): line = p.stdout.readline() self.returnCode = p.wait() - oldProfile = profile.getGlobalProfileString() put('machine_center_x', action.centerX - self.extruderOffset[action.extruder].x) put('machine_center_y', action.centerY - self.extruderOffset[action.extruder].y) put('clear_z', action.clearZ) @@ -743,7 +741,7 @@ class ProjectSliceProgressWindow(wx.Frame): resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('nextobject.gcode')) resultFile.write(';PRINTNR:%d\n' % self.actionList.index(action)) - profile.loadGlobalProfileFromString(oldProfile) + profile.resetTempOverride() f = open(action.filename[: action.filename.rfind('.')] + "_export.project_tmp", "r") data = f.read(4096) @@ -762,7 +760,7 @@ class ProjectSliceProgressWindow(wx.Frame): resultFile.close() self.abort = True sliceTime = time.time() - self.sliceStartTime - wx.CallAfter(self.statusText.SetLabel, 'Slicing took: %d:%d' % (sliceTime / 60, sliceTime % 60)) + wx.CallAfter(self.statusText.SetLabel, 'Slicing took: %02d:%02d' % (sliceTime / 60, sliceTime % 60)) wx.CallAfter(self.abortButton.SetLabel, 'Close') def main(): diff --git a/Cura/gui/sliceProgessPanel.py b/Cura/gui/sliceProgessPanel.py index 17fc7857..3fd0ad02 100644 --- a/Cura/gui/sliceProgessPanel.py +++ b/Cura/gui/sliceProgessPanel.py @@ -59,21 +59,20 @@ class sliceProgessPanel(wx.Panel): 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): @@ -188,7 +187,10 @@ class WorkerThread(threading.Thread): 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)) diff --git a/Cura/util/profile.py b/Cura/util/profile.py index 96e1eb35..686a8d8b 100644 --- a/Cura/util/profile.py +++ b/Cura/util/profile.py @@ -67,6 +67,9 @@ profileDefaultSettings = { 'add_start_end_gcode': 'True', 'gcode_extension': 'gcode', + 'alternative_center': '', + 'clear_z': '0.0', + 'extruder': '0', } alterationDefault = { ####################################################################################### @@ -153,6 +156,7 @@ preferencesDefaultSettings = { ## Profile and preferences functions ######################################################### +## Profile functions def getDefaultProfilePath(): return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../current_profile.ini")) @@ -188,17 +192,31 @@ def getGlobalProfileString(): p = [] alt = [] + tempDone = [] if globalProfileParser.has_section('profile'): for key in globalProfileParser.options('profile'): - p.append(key + "=" + globalProfileParser.get('profile', key)) + if key in tempOverride: + p.append(key + "=" + unicode(tempOverride[key])) + tempDone.append(key) + else: + p.append(key + "=" + globalProfileParser.get('profile', key)) if globalProfileParser.has_section('alterations'): for key in globalProfileParser.options('alterations'): - alt.append(key + "=" + globalProfileParser.get('alterations', key)) + if key in tempOverride: + p.append(key + "=" + tempOverride[key]) + tempDone.append(key) + else: + alt.append(key + "=" + globalProfileParser.get('alterations', key)) + for key in tempOverride: + if key not in tempDone: + p.append(key + "=" + unicode(tempOverride[key])) ret = '\b'.join(p) + '\f' + '\b'.join(alt) ret = base64.b64encode(zlib.compress(ret, 9)) return ret def getProfileSetting(name): + if name in tempOverride: + return unicode(tempOverride[name]) #Check if we have a configuration file loaded, else load the default. if not globals().has_key('globalProfileParser'): loadGlobalProfile(getDefaultProfilePath()) @@ -230,6 +248,12 @@ def putProfileSetting(name, value): globalProfileParser.add_section('profile') globalProfileParser.set('profile', name, str(value)) +def isProfileSetting(name): + if name in profileDefaultSettings: + return True + return False + +## Preferences functions global globalPreferenceParser globalPreferenceParser = None @@ -239,11 +263,12 @@ def getPreferencePath(): def getPreferenceFloat(name): try: return float(eval(getPreference(name), {}, {})) - except (ValueError, SyntaxError): return 0.0 def getPreference(name): + if name in tempOverride: + return unicode(tempOverride[name]) global globalPreferenceParser if globalPreferenceParser == None: globalPreferenceParser = ConfigParser.ConfigParser() @@ -273,6 +298,18 @@ def putPreference(name, value): globalPreferenceParser.set('preference', name, unicode(value).encode("utf-8")) globalPreferenceParser.write(open(getPreferencePath(), 'w')) +def isPreference(name): + if name in preferencesDefaultSettings: + return True + return False + +## Temp overrides for multi-extruder slicing and the project planner. +tempOverride = {} +def setTempOverride(name, value): + tempOverride[name] = value +def resetTempOverride(): + tempOverride = {} + ######################################################### ## Utility functions to calculate common profile values ######################################################### @@ -316,7 +353,11 @@ def replaceTagMatch(m): tag = m.group(0)[1:-1] 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)) + if isProfileSetting(tag): + return str(getProfileSettingFloat(tag)) + if isPreference(tag): + return str(getProfileSettingFloat(tag)) + return tag ### Get aleration raw contents. (Used internally in Cura) def getAlterationFile(filename): From 32d1ea11c2cea843ff3290c1b28060a63aef265e Mon Sep 17 00:00:00 2001 From: daid Date: Thu, 3 May 2012 18:41:58 +0200 Subject: [PATCH 6/6] Changed GCode preview code to be faster on layer switching. --- Cura/gui/preview3d.py | 58 +++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/Cura/gui/preview3d.py b/Cura/gui/preview3d.py index ee1ed79e..a2949c91 100644 --- a/Cura/gui/preview3d.py +++ b/Cura/gui/preview3d.py @@ -1,11 +1,6 @@ from __future__ import division -import sys -import math -import threading -import re -import time -import os +import sys, math, threading, re, time, os from wx import glcanvas import wx @@ -102,7 +97,7 @@ class previewPanel(wx.Panel): self.rotateReset = toolbarUtil.NormalButton(self.toolbar2, self.OnRotateReset, 'object-rotate.png', 'Reset model rotation') self.rotate = wx.SpinCtrl(self.toolbar2, -1, profile.getProfileSetting('model_rotate_base'), size=(21*3,21), style=wx.SP_WRAP|wx.SP_ARROW_KEYS) self.rotate.SetRange(0, 360) - self.Bind(wx.EVT_TEXT, self.OnRotate) + self.rotate.Bind(wx.EVT_TEXT, self.OnRotate) self.toolbar2.AddControl(self.rotate) self.toolbar2.Realize() @@ -179,7 +174,6 @@ class previewPanel(wx.Panel): self.glCanvas.Refresh() def OnLayerNrChange(self, e): - self.gcodeDirty = True self.glCanvas.Refresh() def updateCenterX(self): @@ -378,6 +372,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas): self.offsetY = 0 self.view3D = True self.gcodeDisplayList = None + self.gcodeDisplayListCount = 0 self.objColor = [[1.0, 0.8, 0.6, 1.0], [0.2, 1.0, 0.1, 1.0], [1.0, 0.2, 0.1, 1.0], [0.1, 0.2, 1.0, 1.0]] def OnMouseMotion(self,e): @@ -441,33 +436,37 @@ class PreviewGLCanvas(glcanvas.GLCanvas): opengl.DrawMachine(machineSize) if self.parent.gcode != None: - if self.gcodeDisplayList == None: - self.gcodeDisplayList = glGenLists(1); if self.parent.gcodeDirty: + if self.gcodeDisplayListCount < len(self.parent.gcode.layerList) or self.gcodeDisplayList == None: + if self.gcodeDisplayList != None: + glDeleteLists(self.gcodeDisplayList, self.gcodeDisplayListCount) + self.gcodeDisplayList = glGenLists(len(self.parent.gcode.layerList)); + self.gcodeDisplayListCount = len(self.parent.gcode.layerList) self.parent.gcodeDirty = False - glNewList(self.gcodeDisplayList, GL_COMPILE) prevLayerZ = 0.0 curLayerZ = 0.0 layerThickness = 0.0 - filamentRadius = float(profile.getProfileSetting('filament_diameter')) / 2 + filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2 filamentArea = math.pi * filamentRadius * filamentRadius - lineWidth = float(profile.getProfileSetting('nozzle_size')) / 2 / 10 + lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10 curLayerNum = 0 for layer in self.parent.gcode.layerList: + glNewList(self.gcodeDisplayList + curLayerNum, GL_COMPILE) + glDisable(GL_CULL_FACE) curLayerZ = layer[0].list[1].z layerThickness = curLayerZ - prevLayerZ prevLayerZ = layer[-1].list[-1].z for path in layer: c = 1.0 - if curLayerNum != self.parent.layerSpin.GetValue(): - if curLayerNum < self.parent.layerSpin.GetValue(): - c = 0.9 - (self.parent.layerSpin.GetValue() - curLayerNum) * 0.1 - if c < 0.4: - c = 0.4 - else: - break + #if curLayerNum != self.parent.layerSpin.GetValue(): + # if curLayerNum < self.parent.layerSpin.GetValue(): + # c = 0.9 - (self.parent.layerSpin.GetValue() - curLayerNum) * 0.1 + # if c < 0.4: + # c = 0.4 + # else: + # break if path.type == 'move': glColor3f(0,0,c) if path.type == 'extrude': @@ -529,9 +528,24 @@ class PreviewGLCanvas(glcanvas.GLCanvas): glVertex3f(v.x, v.y, v.z) glEnd() curLayerNum += 1 - glEndList() + glEnable(GL_CULL_FACE) + glEndList() if self.viewMode == "GCode" or self.viewMode == "Mixed": - glCallList(self.gcodeDisplayList) + glEnable(GL_COLOR_MATERIAL) + glEnable(GL_LIGHTING) + glLightfv(GL_LIGHT0, GL_DIFFUSE, [0,0,0,0]) + for i in xrange(0, self.parent.layerSpin.GetValue() + 1): + c = 1.0 + if i < self.parent.layerSpin.GetValue(): + c = 0.9 - (self.parent.layerSpin.GetValue() - i) * 0.1 + if c < 0.4: + c = (0.4 + c) / 2 + if c < 0.1: + c = 0.1 + glLightfv(GL_LIGHT0, GL_AMBIENT, [c,c,c,c]) + glCallList(self.gcodeDisplayList + i) + glDisable(GL_COLOR_MATERIAL) + glDisable(GL_LIGHTING) glTranslate(self.parent.machineCenter.x, self.parent.machineCenter.y, 0) for obj in self.parent.objectList: