chiark / gitweb /
Added start/end gcode editor (read only, doesn't save yet)
authorDaid <daid303@gmail.com>
Tue, 21 Feb 2012 22:05:30 +0000 (23:05 +0100)
committerDaid <daid303@gmail.com>
Tue, 21 Feb 2012 22:05:30 +0000 (23:05 +0100)
Added GCode preview (Loads to do there)
Added help tooltip option (Loads of help to write)

SkeinPyPy_NewUI/fabmetheus_utilities/settings.py
SkeinPyPy_NewUI/newui/alterationPanel.py [new file with mode: 0644]
SkeinPyPy_NewUI/newui/mainWindow.py
SkeinPyPy_NewUI/newui/preview3d.py
SkeinPyPy_NewUI/newui/skeinRun.py
SkeinPyPy_NewUI/newui/sliceProgessPanel.py

index 311544c25f6ee0c3b08b0a735d36ca980d60f473..dc479a9b30dbcb0bf08cfea219bec8c99c595aa4 100644 (file)
@@ -10,6 +10,8 @@ import __init__
 import ConfigParser
 import os, sys
 
+from fabmetheus_utilities import archive
+
 def getSkeinPyPyConfigInformation():
        return {
                'carve': {
@@ -401,12 +403,19 @@ def printProgressByNumber(layerIndex, numberOfLayers, procedureName):
 
 def getAlterationFileLines(fileName):
        'Get the alteration file line and the text lines from the fileName in the alterations directories.'
-       print ('getAlterationFileLines:', fileName)
-       return []
+       return getAlterationLines(fileName)
 
 def getAlterationLines(fileName):
-       print ('getAlterationLines:', fileName)
-       return []
+       #print ('getAlterationLines:', fileName)
+       return archive.getTextLines(getAlterationFile(fileName))
+
+def getAlterationFile(fileName):
+       "Get the file from the fileName or the lowercase fileName in the alterations directories."
+       alterationsDirectory = archive.getSkeinforgePath('alterations')
+       fullFilename = os.path.join(alterationsDirectory, fileName)
+       if os.path.isfile(fullFilename):
+               return archive.getFileText( fullFilename )
+       return ''
 
 ####################################
 ## Configuration settings classes ##
diff --git a/SkeinPyPy_NewUI/newui/alterationPanel.py b/SkeinPyPy_NewUI/newui/alterationPanel.py
new file mode 100644 (file)
index 0000000..6618a24
--- /dev/null
@@ -0,0 +1,29 @@
+import wx\r
+import sys,math,threading\r
+\r
+from fabmetheus_utilities import settings\r
+\r
+class alterationPanel(wx.Panel):\r
+       def __init__(self, parent):\r
+               wx.Panel.__init__(self, parent,-1)\r
+\r
+               self.alterationFileList = ['start.gcode', 'end.gcode', 'cool_start.gcode', 'cool_end.gcode']\r
+\r
+               self.textArea = wx.TextCtrl(self, style=wx.TE_MULTILINE)\r
+               self.list = wx.ListBox(self, choices=self.alterationFileList, style=wx.LB_SINGLE)\r
+               self.list.SetSelection(0)\r
+               self.Bind(wx.EVT_LISTBOX, self.OnSelect, self.list)\r
+               self.OnSelect(None)\r
+               \r
+               sizer = wx.GridBagSizer()\r
+               sizer.Add(self.list, (0,0), span=(1,1), flag=wx.EXPAND)\r
+               sizer.Add(self.textArea, (0,1), span=(1,1), flag=wx.EXPAND)\r
+               sizer.AddGrowableCol(1)\r
+               sizer.AddGrowableRow(0)\r
+               self.SetSizer(sizer)\r
+\r
+       def OnSelect(self, e):\r
+               self.loadFile(self.alterationFileList[self.list.GetSelection()])\r
+\r
+       def loadFile(self, filename):\r
+               self.textArea.SetValue(settings.getAlterationFile(filename))\r
index ec6f1b65883ece446aa12252307801f09b06bcef..b42822cd2a734f520efa6023372d50aba0cf65ce 100644 (file)
@@ -9,6 +9,7 @@ from skeinforge_application.skeinforge_utilities import skeinforge_profile
 
 from newui import preview3d
 from newui import sliceProgessPanel
+from newui import alterationPanel
 
 def main():
        app = wx.App(False)
@@ -31,6 +32,8 @@ class mainWindow(wx.Frame):
                #menubar.Append(wx.Menu(), 'Expert')
                self.SetMenuBar(menubar)
                
+               wx.ToolTip.SetDelay(0)
+               
                self.lastPath = ""
                self.filename = None
                self.progressPanelList = []
@@ -57,7 +60,7 @@ class mainWindow(wx.Frame):
                configPanel.SetSizer(sizer)
                
                self.AddTitle(configPanel, "Accuracy")
-               self.AddSetting(configPanel, "Layer height (mm)", self.plugins['carve'].preferencesDict['Layer_Height_mm'])
+               self.AddSetting(configPanel, "Layer height (mm)", self.plugins['carve'].preferencesDict['Layer_Height_mm'], 'Layer height in millimeters.\n0.2 is a good value for quick prints.\n0.1 gives high quality prints.')
                self.AddTitle(configPanel, "Skirt")
                self.AddSetting(configPanel, "Enable skirt", self.plugins['skirt'].preferencesDict['Activate_Skirt'])
                self.AddSetting(configPanel, "Skirt distance (mm)", self.plugins['skirt'].preferencesDict['Gap_Width_mm'])
@@ -93,7 +96,7 @@ class mainWindow(wx.Frame):
                self.AddSetting(configPanel, "Diameter (mm)", self.plugins['dimension'].preferencesDict['Filament_Diameter_mm'])
                self.AddSetting(configPanel, "Packing Density", self.plugins['dimension'].preferencesDict['Filament_Packing_Density_ratio'])
                
-               nb.AddPage(wx.Panel(nb), "Start/End-GCode")
+               nb.AddPage(alterationPanel.alterationPanel(nb), "Start/End-GCode")
 
                #Preview window, load and slice buttons.
                self.preview3d = preview3d.myGLCanvas(p)
@@ -102,7 +105,7 @@ class mainWindow(wx.Frame):
                sliceButton = wx.Button(p, -1, 'Slice to GCode')
                self.Bind(wx.EVT_BUTTON, self.OnLoadSTL, loadButton)
                self.Bind(wx.EVT_BUTTON, self.OnSlice, sliceButton)
-               
+
                sizer = wx.GridBagSizer()
                sizer.Add(nb, (0,0), span=(2,1), flag=wx.EXPAND)
                sizer.Add(self.preview3d, (0,1), span=(1,3), flag=wx.EXPAND)
@@ -128,7 +131,7 @@ class mainWindow(wx.Frame):
                sizer.Add(wx.StaticLine(panel), (sizer.GetRows()+1,1), (1,3), flag=wx.EXPAND)
                sizer.SetRows(sizer.GetRows() + 2)
        
-       def AddSetting(self, panel, name, setting, help = False):
+       def AddSetting(self, panel, name, setting, help = 'TODO'):
                "Add a setting to the configuration panel"
                sizer = panel.GetSizer()
                sizer.Add(wx.StaticText(panel, -1, name), (sizer.GetRows(),1), flag=wx.ALIGN_CENTER_VERTICAL)
@@ -148,6 +151,7 @@ class mainWindow(wx.Frame):
                        sizer.Add(ctrl, (sizer.GetRows(),2), flag=wx.ALIGN_BOTTOM|wx.EXPAND)
                helpButton = wx.Button(panel, -1, "?", style=wx.BU_EXACTFIT)
                sizer.Add(helpButton, (sizer.GetRows(),3))
+               helpButton.SetToolTip(wx.ToolTip(help))
                sizer.SetRows(sizer.GetRows()+1)
                return ctrl
 
@@ -179,15 +183,14 @@ class mainWindow(wx.Frame):
                        if not(os.path.exists(self.filename)):
                                return
                        self.lastPath = os.path.split(self.filename)[0]
-                       self.preview3d.loadFile(self.filename)
+                       self.preview3d.loadModelFile(self.filename)
                dlg.Destroy()
        
        def OnSlice(self, e):
                if self.filename == None:
                        return
-               for pluginName in self.plugins.keys():
-                       settings.storeRepository(self.plugins[pluginName])
-               settings.saveGlobalConfig(settings.getDefaultConfigPath())
+               self.updateConfigFromControls()
+               
                #Create a progress panel and add it to the window. The progress panel will start the Skein operation.
                spp = sliceProgessPanel.sliceProgessPanel(self, self.panel, self.filename)
                self.sizer.Add(spp, (len(self.progressPanelList)+2,0), span=(1,4), flag=wx.EXPAND)
@@ -209,6 +212,7 @@ class mainWindow(wx.Frame):
                for spp in self.progressPanelList:
                        self.sizer.Add(spp, (i,0), span=(1,4), flag=wx.EXPAND)
                        i += 1
+               self.sizer.Layout()
        
        def updateConfigToControls(self):
                "Update the configuration wx controls to show the new configuration settings"
index cccfb457ef6533aff15f4ffea1905b09cb609501..cf3853b7ea2e8e1a69c527d243b606ac53098090 100644 (file)
@@ -1,4 +1,3 @@
-#from wxPython.glcanvas import wxGLCanvas\r
 import wx\r
 import sys,math,threading\r
 \r
@@ -25,28 +24,83 @@ class myGLCanvas(GLCanvas):
                self.init = 0\r
                self.triangleMesh = None\r
                self.modelDisplayList = None\r
+               self.pathList = None\r
                self.yaw = 30\r
                self.pitch = 60\r
                self.zoom = 150\r
                self.renderTransparent = False\r
                self.machineSize = Vector3(210, 210, 200)\r
-               self.machineCenter = Vector3(100, 100, 0)\r
+               self.machineCenter = Vector3(105, 105, 0)\r
                configButton = wx.Button(self, -1, '', (3,3), (10,10))\r
                self.Bind(wx.EVT_BUTTON, self.OnConfigClick, configButton)\r
        \r
-       def loadFile(self, filename):\r
-               self.filename = filename\r
+       def loadModelFile(self, filename):\r
+               self.modelFilename = filename\r
                #Do the STL file loading in a background thread so we don't block the UI.\r
-               thread = threading.Thread(target=self.DoLoad)\r
+               thread = threading.Thread(target=self.DoModelLoad)\r
+               thread.setDaemon(True)\r
+               thread.start()\r
+\r
+       def loadGCodeFile(self, filename):\r
+               self.gcodeFilename = filename\r
+               #Do the STL file loading in a background thread so we don't block the UI.\r
+               thread = threading.Thread(target=self.DoGCodeLoad)\r
                thread.setDaemon(True)\r
                thread.start()\r
        \r
-       def DoLoad(self):\r
+       def DoModelLoad(self):\r
                self.modelDirty = False\r
-               self.triangleMesh = fabmetheus_interpret.getCarving(self.filename)\r
+               self.triangleMesh = fabmetheus_interpret.getCarving(self.modelFilename)\r
                self.moveModel()\r
                self.Refresh()\r
        \r
+       def getCode(self, str, id):\r
+               pos = str.find(id)\r
+               if pos < 0:\r
+                       return '';\r
+               posEnd = str.find(' ', pos)\r
+               if posEnd < 0:\r
+                       return str[pos+1:]\r
+               return str[pos+1:posEnd]\r
+       \r
+       def DoGCodeLoad(self):\r
+               f = open(self.gcodeFilename, 'r')\r
+               pos = Vector3()\r
+               currentE = 0\r
+               pathList = []\r
+               currentPath = {'type': 'move', 'list': [pos.copy()]}\r
+               for line in f:\r
+                       G = self.getCode(line, 'G')\r
+                       if G != '':\r
+                               if G == '0' or G == '1':\r
+                                       X = self.getCode(line, 'X')\r
+                                       Y = self.getCode(line, 'Y')\r
+                                       Z = self.getCode(line, 'Z')\r
+                                       E = self.getCode(line, 'E')\r
+                                       if X != '':\r
+                                               pos.x = float(X)\r
+                                       if X != '':\r
+                                               pos.y = float(Y)\r
+                                       if Z != '':\r
+                                               pos.z = float(Z)\r
+                                       newPoint = pos.copy()\r
+                                       type = 'move'\r
+                                       if E != '':\r
+                                               newEvalue = float(E)\r
+                                               if newEvalue > currentE:\r
+                                                       type = 'extrude'\r
+                                               if newEvalue < currentE:\r
+                                                       type = 'retract'\r
+                                       if currentPath['type'] != type:\r
+                                               pathList.append(currentPath)\r
+                                               currentPath = {'type': type, 'list': [currentPath['list'][-1]]}\r
+                                       currentPath['list'].append(newPoint)\r
+                               else:\r
+                                       print "Unknown G code:" + G\r
+               self.pathList = pathList\r
+               self.triangleMesh = None\r
+               self.Refresh()\r
+       \r
        def OnConfigClick(self, e):\r
                self.renderTransparent = not self.renderTransparent\r
                self.Refresh()\r
@@ -104,6 +158,7 @@ class myGLCanvas(GLCanvas):
                \r
                glTranslate(-self.machineCenter.x, -self.machineCenter.y, 0)\r
                \r
+               glColor3f(1,1,1)\r
                glLineWidth(4)\r
                glDisable(GL_LIGHTING)\r
                glBegin(GL_LINE_LOOP)\r
@@ -138,6 +193,19 @@ class myGLCanvas(GLCanvas):
                glVertex3f(0, self.machineSize.y, 0)\r
                glVertex3f(0, self.machineSize.y, self.machineSize.z)\r
                glEnd()\r
+\r
+               if self.pathList != None:\r
+                       for path in self.pathList:\r
+                               if path['type'] == 'move':\r
+                                       glColor3f(0,0,1)\r
+                               if path['type'] == 'extrude':\r
+                                       glColor3f(1,0,0)\r
+                               if path['type'] == 'retract':\r
+                                       glColor3f(0,1,0)\r
+                               glBegin(GL_LINE_STRIP)\r
+                               for v in path['list']:\r
+                                       glVertex3f(v.x, v.y, v.z)\r
+                               glEnd()\r
                \r
                if self.triangleMesh != None:\r
                        if self.modelDisplayList == None:\r
@@ -185,9 +253,13 @@ class myGLCanvas(GLCanvas):
                glLoadIdentity()\r
                glViewport(0,0, self.GetSize().GetWidth(), self.GetSize().GetHeight())\r
                \r
-               glLightfv(GL_LIGHT0, GL_DIFFUSE,  [1.0, 0.8, 0.6, 1.0])\r
+               if self.renderTransparent:\r
+                       glLightfv(GL_LIGHT0, GL_DIFFUSE,  [0.5, 0.4, 0.3, 1.0])\r
+                       glLightfv(GL_LIGHT0, GL_AMBIENT,  [0.1, 0.1, 0.1, 0.0])\r
+               else:\r
+                       glLightfv(GL_LIGHT0, GL_DIFFUSE,  [1.0, 0.8, 0.6, 1.0])\r
+                       glLightfv(GL_LIGHT0, GL_AMBIENT,  [0.2, 0.2, 0.2, 0.0])\r
                glLightfv(GL_LIGHT0, GL_POSITION, [1.0, 1.0, 1.0, 0.0])\r
-               glLightfv(GL_LIGHT0, GL_AMBIENT,  [0.2, 0.2, 0.2, 0.0])\r
 \r
                glEnable(GL_LIGHTING)\r
                glEnable(GL_LIGHT0)\r
index 08be13cdf68df558b73f59db546d32ddcb4d43eb..bd1c3c93625ed7c5f99262774141d17a0fea9c57 100644 (file)
@@ -44,5 +44,4 @@ def getSkeinCommand(filename):
        pypyExe = getPyPyExe()
        if pypyExe == False:
                pypyExe = sys.executable
-       return [pypyExe, os.path.join(sys.path[0], sys.argv[0]), filename]
-
+       return [pypyExe, os.path.join(sys.path[0], os.path.split(sys.argv[0])[1]), filename]
index fe90cfe4b82b61c1f411be0ec617508d71f7a393..55e378c4d3f0b3bf54a6f16ae92e031d80238d61 100644 (file)
@@ -12,18 +12,18 @@ class sliceProgessPanel(wx.Panel):
                self.abort = False
 
                box = wx.StaticBox(self, -1, filename)
-               sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
-               
+               self.sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+
                mainSizer = wx.BoxSizer(wx.VERTICAL) 
-               mainSizer.Add(sizer, 0, flag=wx.EXPAND)
+               mainSizer.Add(self.sizer, 0, flag=wx.EXPAND)
 
                self.statusText = wx.StaticText(self, -1, "Starting...")
                self.progressGauge = wx.Gauge(self, -1)
                self.abortButton = wx.Button(self, -1, "X", style=wx.BU_EXACTFIT)
-               sizer.Add(self.statusText, 2, flag=wx.ALIGN_CENTER )
-               sizer.Add(self.progressGauge, 2)
-               sizer.Add(self.abortButton, 0)
-               
+               self.sizer.Add(self.statusText, 2, flag=wx.ALIGN_CENTER )
+               self.sizer.Add(self.progressGauge, 2)
+               self.sizer.Add(self.abortButton, 0)
+
                self.Bind(wx.EVT_BUTTON, self.OnAbort, self.abortButton)
 
                self.SetSizer(mainSizer)
@@ -34,6 +34,20 @@ class sliceProgessPanel(wx.Panel):
                        self.mainWindow.removeSliceProgress(self)
                else:
                        self.abort = True
+       
+       def OnShowGCode(self, e):
+               self.mainWindow.preview3d.loadGCodeFile(self.filename[: self.filename.rfind('.')] + "_export.gcode")
+       
+       def OnSliceDone(self):
+               self.statusText.SetLabel("Ready.")
+               self.progressGauge.Destroy()
+               self.showButton = wx.Button(self, -1, "Show GCode")
+               self.Bind(wx.EVT_BUTTON, self.OnShowGCode, self.showButton)
+               self.sizer.Remove(self.abortButton)
+               self.sizer.Add(self.showButton, 0)
+               self.sizer.Add(self.abortButton, 0)
+               self.sizer.Layout()
+               self.abort = True
 
 class WorkerThread(threading.Thread):
        def __init__(self, notifyWindow, filename):
@@ -48,6 +62,7 @@ class WorkerThread(threading.Thread):
                maxValue = 1
                while(len(line) > 0):
                        line = line.rstrip()
+                       print line
                        if line[0:9] == "Progress[" and line[-1:] == "]":
                                progress = line[9:-1].split(":")
                                if len(progress) > 2:
@@ -62,6 +77,4 @@ class WorkerThread(threading.Thread):
                                wx.CallAfter(self.notifyWindow.statusText.SetLabel, "Aborted by user.")
                                return
                        line = p.stdout.readline()
-               wx.CallAfter(self.notifyWindow.progressGauge.SetValue, maxValue)
-               wx.CallAfter(self.notifyWindow.statusText.SetLabel, "Ready.")
-
+               wx.CallAfter(self.notifyWindow.OnSliceDone)