Added start/end gcode editor (read only, doesn't save yet)

Added GCode preview (Loads to do there)
Added help tooltip option (Loads of help to write)
This commit is contained in:
Daid 2012-02-21 23:05:30 +01:00
parent 1e2d8e372f
commit 7a77a44dea
6 changed files with 159 additions and 33 deletions

View 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 ##

View File

@ -0,0 +1,29 @@
import wx
import sys,math,threading
from fabmetheus_utilities import settings
class alterationPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent,-1)
self.alterationFileList = ['start.gcode', 'end.gcode', 'cool_start.gcode', 'cool_end.gcode']
self.textArea = wx.TextCtrl(self, style=wx.TE_MULTILINE)
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.OnSelect(None)
sizer = wx.GridBagSizer()
sizer.Add(self.list, (0,0), span=(1,1), flag=wx.EXPAND)
sizer.Add(self.textArea, (0,1), span=(1,1), flag=wx.EXPAND)
sizer.AddGrowableCol(1)
sizer.AddGrowableRow(0)
self.SetSizer(sizer)
def OnSelect(self, e):
self.loadFile(self.alterationFileList[self.list.GetSelection()])
def loadFile(self, filename):
self.textArea.SetValue(settings.getAlterationFile(filename))

View 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)
@ -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"

View File

@ -1,4 +1,3 @@
#from wxPython.glcanvas import wxGLCanvas
import wx
import sys,math,threading
@ -25,28 +24,83 @@ class myGLCanvas(GLCanvas):
self.init = 0
self.triangleMesh = None
self.modelDisplayList = None
self.pathList = None
self.yaw = 30
self.pitch = 60
self.zoom = 150
self.renderTransparent = False
self.machineSize = Vector3(210, 210, 200)
self.machineCenter = Vector3(100, 100, 0)
self.machineCenter = Vector3(105, 105, 0)
configButton = wx.Button(self, -1, '', (3,3), (10,10))
self.Bind(wx.EVT_BUTTON, self.OnConfigClick, configButton)
def loadFile(self, filename):
self.filename = filename
def loadModelFile(self, filename):
self.modelFilename = filename
#Do the STL file loading in a background thread so we don't block the UI.
thread = threading.Thread(target=self.DoLoad)
thread = threading.Thread(target=self.DoModelLoad)
thread.setDaemon(True)
thread.start()
def DoLoad(self):
def loadGCodeFile(self, filename):
self.gcodeFilename = filename
#Do the STL file loading in a background thread so we don't block the UI.
thread = threading.Thread(target=self.DoGCodeLoad)
thread.setDaemon(True)
thread.start()
def DoModelLoad(self):
self.modelDirty = False
self.triangleMesh = fabmetheus_interpret.getCarving(self.filename)
self.triangleMesh = fabmetheus_interpret.getCarving(self.modelFilename)
self.moveModel()
self.Refresh()
def getCode(self, str, id):
pos = str.find(id)
if pos < 0:
return '';
posEnd = str.find(' ', pos)
if posEnd < 0:
return str[pos+1:]
return str[pos+1:posEnd]
def DoGCodeLoad(self):
f = open(self.gcodeFilename, 'r')
pos = Vector3()
currentE = 0
pathList = []
currentPath = {'type': 'move', 'list': [pos.copy()]}
for line in f:
G = self.getCode(line, 'G')
if G != '':
if G == '0' or G == '1':
X = self.getCode(line, 'X')
Y = self.getCode(line, 'Y')
Z = self.getCode(line, 'Z')
E = self.getCode(line, 'E')
if X != '':
pos.x = float(X)
if X != '':
pos.y = float(Y)
if Z != '':
pos.z = float(Z)
newPoint = pos.copy()
type = 'move'
if E != '':
newEvalue = float(E)
if newEvalue > currentE:
type = 'extrude'
if newEvalue < currentE:
type = 'retract'
if currentPath['type'] != type:
pathList.append(currentPath)
currentPath = {'type': type, 'list': [currentPath['list'][-1]]}
currentPath['list'].append(newPoint)
else:
print "Unknown G code:" + G
self.pathList = pathList
self.triangleMesh = None
self.Refresh()
def OnConfigClick(self, e):
self.renderTransparent = not self.renderTransparent
self.Refresh()
@ -104,6 +158,7 @@ class myGLCanvas(GLCanvas):
glTranslate(-self.machineCenter.x, -self.machineCenter.y, 0)
glColor3f(1,1,1)
glLineWidth(4)
glDisable(GL_LIGHTING)
glBegin(GL_LINE_LOOP)
@ -139,6 +194,19 @@ class myGLCanvas(GLCanvas):
glVertex3f(0, self.machineSize.y, self.machineSize.z)
glEnd()
if self.pathList != None:
for path in self.pathList:
if path['type'] == 'move':
glColor3f(0,0,1)
if path['type'] == 'extrude':
glColor3f(1,0,0)
if path['type'] == 'retract':
glColor3f(0,1,0)
glBegin(GL_LINE_STRIP)
for v in path['list']:
glVertex3f(v.x, v.y, v.z)
glEnd()
if self.triangleMesh != None:
if self.modelDisplayList == None:
self.modelDisplayList = glGenLists(1);
@ -185,9 +253,13 @@ class myGLCanvas(GLCanvas):
glLoadIdentity()
glViewport(0,0, self.GetSize().GetWidth(), self.GetSize().GetHeight())
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 0.8, 0.6, 1.0])
if self.renderTransparent:
glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.5, 0.4, 0.3, 1.0])
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.1, 0.1, 0.1, 0.0])
else:
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 0.8, 0.6, 1.0])
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.2, 0.2, 0.2, 0.0])
glLightfv(GL_LIGHT0, GL_POSITION, [1.0, 1.0, 1.0, 0.0])
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.2, 0.2, 0.2, 0.0])
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)

View 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]

View File

@ -12,17 +12,17 @@ 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)
@ -35,6 +35,20 @@ class sliceProgessPanel(wx.Panel):
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):
threading.Thread.__init__(self)
@ -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)