mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-04 17:50:35 +08:00
Added basic batch run tool. Still needs some more enhancements.
This commit is contained in:
parent
c3502d9ca4
commit
a91261cc7a
185
Cura/gui/batchRun.py
Normal file
185
Cura/gui/batchRun.py
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
|
import __init__
|
||||||
|
|
||||||
|
import wx, os, platform, types, webbrowser, math, subprocess, threading, time, re
|
||||||
|
|
||||||
|
from util import profile
|
||||||
|
from util import sliceRun
|
||||||
|
|
||||||
|
class batchRunWindow(wx.Frame):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super(batchRunWindow, self).__init__(parent, title='Cura - Batch run')
|
||||||
|
|
||||||
|
self.list = []
|
||||||
|
|
||||||
|
wx.EVT_CLOSE(self, self.OnClose)
|
||||||
|
self.panel = wx.Panel(self, -1)
|
||||||
|
self.SetSizer(wx.BoxSizer(wx.VERTICAL))
|
||||||
|
self.GetSizer().Add(self.panel, 1, flag=wx.EXPAND)
|
||||||
|
#self.SetIcon(icon.getMainIcon())
|
||||||
|
|
||||||
|
self.sizer = wx.GridBagSizer(2,2)
|
||||||
|
self.panel.SetSizer(self.sizer)
|
||||||
|
|
||||||
|
self.listbox = wx.ListBox(self.panel, -1, choices=[])
|
||||||
|
self.addButton = wx.Button(self.panel, -1, "Add")
|
||||||
|
self.remButton = wx.Button(self.panel, -1, "Remove")
|
||||||
|
self.sliceButton = wx.Button(self.panel, -1, "Slice")
|
||||||
|
|
||||||
|
self.addButton.Bind(wx.EVT_BUTTON, self.OnAddModel)
|
||||||
|
self.remButton.Bind(wx.EVT_BUTTON, self.OnRemModel)
|
||||||
|
self.sliceButton.Bind(wx.EVT_BUTTON, self.OnSlice)
|
||||||
|
self.listbox.Bind(wx.EVT_LISTBOX, self.OnListSelect)
|
||||||
|
|
||||||
|
self.sizer.Add(self.listbox, (0,0), span=(1,3), flag=wx.EXPAND)
|
||||||
|
self.sizer.Add(self.addButton, (1,0), span=(1,1))
|
||||||
|
self.sizer.Add(self.remButton, (1,1), span=(1,1))
|
||||||
|
self.sizer.Add(self.sliceButton, (1,2), span=(1,1))
|
||||||
|
|
||||||
|
self.sizer.AddGrowableCol(2)
|
||||||
|
self.sizer.AddGrowableRow(0)
|
||||||
|
|
||||||
|
def OnAddModel(self, e):
|
||||||
|
dlg=wx.FileDialog(self, "Open file to batch slice", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST|wx.FD_MULTIPLE)
|
||||||
|
dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL")
|
||||||
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
|
for filename in dlg.GetPaths():
|
||||||
|
profile.putPreference('lastFile', filename)
|
||||||
|
self.list.append(filename)
|
||||||
|
self.selection = filename
|
||||||
|
self._updateListbox()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def OnRemModel(self, e):
|
||||||
|
if self.selection == None:
|
||||||
|
return
|
||||||
|
self.list.remove(self.selection)
|
||||||
|
self._updateListbox()
|
||||||
|
|
||||||
|
def OnListSelect(self, e):
|
||||||
|
if self.listbox.GetSelection() == -1:
|
||||||
|
return
|
||||||
|
self.selection = self.list[self.listbox.GetSelection()]
|
||||||
|
|
||||||
|
def _updateListbox(self):
|
||||||
|
self.listbox.Clear()
|
||||||
|
for item in self.list:
|
||||||
|
self.listbox.AppendAndEnsureVisible(os.path.split(item)[1])
|
||||||
|
if self.selection in self.list:
|
||||||
|
self.listbox.SetSelection(self.list.index(self.selection))
|
||||||
|
elif len(self.list) > 0:
|
||||||
|
self.selection = self.list[0]
|
||||||
|
self.listbox.SetSelection(0)
|
||||||
|
else:
|
||||||
|
self.selection = None
|
||||||
|
self.listbox.SetSelection(-1)
|
||||||
|
|
||||||
|
def OnClose(self, e):
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
def OnSlice(self, e):
|
||||||
|
sliceCmdList = []
|
||||||
|
for filename in self.list:
|
||||||
|
sliceCmdList.append(sliceRun.getSliceCommand(filename))
|
||||||
|
bspw = BatchSliceProgressWindow(self.list[:], sliceCmdList)
|
||||||
|
bspw.Centre()
|
||||||
|
bspw.Show(True)
|
||||||
|
|
||||||
|
class BatchSliceProgressWindow(wx.Frame):
|
||||||
|
def __init__(self, filenameList, sliceCmdList):
|
||||||
|
super(BatchSliceProgressWindow, self).__init__(None, title='Cura')
|
||||||
|
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
|
||||||
|
|
||||||
|
self.filenameList = filenameList
|
||||||
|
self.sliceCmdList = sliceCmdList
|
||||||
|
self.abort = False
|
||||||
|
self.prevStep = 'start'
|
||||||
|
self.totalDoneFactor = 0.0
|
||||||
|
self.startTime = time.time()
|
||||||
|
self.sliceStartTime = time.time()
|
||||||
|
|
||||||
|
self.sizer = wx.GridBagSizer(2, 2)
|
||||||
|
self.statusText = wx.StaticText(self, -1, "Building: %d XXXXXXXXXXXXXXXXXXXXX" % (len(self.sliceCmdList)))
|
||||||
|
self.progressGauge = wx.Gauge(self, -1)
|
||||||
|
self.progressGauge.SetRange(10000)
|
||||||
|
self.progressGauge2 = wx.Gauge(self, -1)
|
||||||
|
self.progressGauge2.SetRange(len(self.sliceCmdList))
|
||||||
|
self.abortButton = wx.Button(self, -1, "Abort")
|
||||||
|
self.sizer.Add(self.statusText, (0,0), span=(1,4))
|
||||||
|
self.sizer.Add(self.progressGauge, (1, 0), span=(1,4), flag=wx.EXPAND)
|
||||||
|
self.sizer.Add(self.progressGauge2, (2, 0), span=(1,4), flag=wx.EXPAND)
|
||||||
|
|
||||||
|
self.sizer.Add(self.abortButton, (3,0), span=(1,4), flag=wx.ALIGN_CENTER)
|
||||||
|
self.sizer.AddGrowableCol(0)
|
||||||
|
self.sizer.AddGrowableRow(0)
|
||||||
|
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnAbort, self.abortButton)
|
||||||
|
self.SetSizer(self.sizer)
|
||||||
|
self.Layout()
|
||||||
|
self.Fit()
|
||||||
|
|
||||||
|
threading.Thread(target=self.OnRun).start()
|
||||||
|
|
||||||
|
def OnAbort(self, e):
|
||||||
|
if self.abort:
|
||||||
|
self.Close()
|
||||||
|
else:
|
||||||
|
self.abort = True
|
||||||
|
self.abortButton.SetLabel('Close')
|
||||||
|
|
||||||
|
def SetProgress(self, stepName, layer, maxLayer):
|
||||||
|
if self.prevStep != stepName:
|
||||||
|
self.totalDoneFactor += sliceRun.sliceStepTimeFactor[self.prevStep]
|
||||||
|
newTime = time.time()
|
||||||
|
#print "#####" + str(newTime-self.startTime) + " " + self.prevStep + " -> " + stepName
|
||||||
|
self.startTime = newTime
|
||||||
|
self.prevStep = stepName
|
||||||
|
|
||||||
|
progresValue = ((self.totalDoneFactor + sliceRun.sliceStepTimeFactor[stepName] * layer / maxLayer) / sliceRun.totalRunTimeFactor) * 10000
|
||||||
|
self.progressGauge.SetValue(int(progresValue))
|
||||||
|
self.statusText.SetLabel(stepName + " [" + str(layer) + "/" + str(maxLayer) + "]")
|
||||||
|
|
||||||
|
def OnRun(self):
|
||||||
|
for action in self.sliceCmdList:
|
||||||
|
wx.CallAfter(self.SetTitle, "Building: [%d/%d]" % (self.sliceCmdList.index(action) + 1, len(self.sliceCmdList)))
|
||||||
|
|
||||||
|
p = subprocess.Popen(action, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
line = p.stdout.readline()
|
||||||
|
maxValue = 1
|
||||||
|
while(len(line) > 0):
|
||||||
|
line = line.rstrip()
|
||||||
|
if line[0:9] == "Progress[" and line[-1:] == "]":
|
||||||
|
progress = line[9:-1].split(":")
|
||||||
|
if len(progress) > 2:
|
||||||
|
maxValue = int(progress[2])
|
||||||
|
wx.CallAfter(self.SetProgress, progress[0], int(progress[1]), maxValue)
|
||||||
|
else:
|
||||||
|
print line
|
||||||
|
wx.CallAfter(self.statusText.SetLabel, line)
|
||||||
|
if self.abort:
|
||||||
|
p.terminate()
|
||||||
|
wx.CallAfter(self.statusText.SetLabel, "Aborted by user.")
|
||||||
|
return
|
||||||
|
line = p.stdout.readline()
|
||||||
|
self.returnCode = p.wait()
|
||||||
|
|
||||||
|
wx.CallAfter(self.progressGauge.SetValue, 10000)
|
||||||
|
self.totalDoneFactor = 0.0
|
||||||
|
wx.CallAfter(self.progressGauge2.SetValue, self.sliceCmdList.index(action) + 1)
|
||||||
|
|
||||||
|
self.abort = True
|
||||||
|
sliceTime = time.time() - self.sliceStartTime
|
||||||
|
status = "Build: %d" % (len(self.sliceCmdList))
|
||||||
|
status += "\nSlicing took: %02d:%02d" % (sliceTime / 60, sliceTime % 60)
|
||||||
|
|
||||||
|
wx.CallAfter(self.statusText.SetLabel, status)
|
||||||
|
wx.CallAfter(self.OnSliceDone)
|
||||||
|
|
||||||
|
def OnSliceDone(self):
|
||||||
|
self.abortButton.Destroy()
|
||||||
|
self.closeButton = wx.Button(self, -1, "Close")
|
||||||
|
self.sizer.Add(self.closeButton, (3,0), span=(1,1))
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnAbort, self.closeButton)
|
||||||
|
self.Layout()
|
||||||
|
self.Fit()
|
||||||
|
|
@ -15,6 +15,7 @@ from gui import firmwareInstall
|
|||||||
from gui import printWindow
|
from gui import printWindow
|
||||||
from gui import simpleMode
|
from gui import simpleMode
|
||||||
from gui import projectPlanner
|
from gui import projectPlanner
|
||||||
|
from gui import batchRun
|
||||||
from gui import flatSlicerWindow
|
from gui import flatSlicerWindow
|
||||||
from gui import icon
|
from gui import icon
|
||||||
from util import profile
|
from util import profile
|
||||||
@ -53,6 +54,8 @@ class mainWindow(configBase.configWindowBase):
|
|||||||
i = fileMenu.Append(-1, 'Reset Profile to default')
|
i = fileMenu.Append(-1, 'Reset Profile to default')
|
||||||
self.Bind(wx.EVT_MENU, self.OnResetProfile, i)
|
self.Bind(wx.EVT_MENU, self.OnResetProfile, i)
|
||||||
fileMenu.AppendSeparator()
|
fileMenu.AppendSeparator()
|
||||||
|
i = fileMenu.Append(-1, 'Batch run...')
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnBatchRun, i)
|
||||||
i = fileMenu.Append(-1, 'Preferences...')
|
i = fileMenu.Append(-1, 'Preferences...')
|
||||||
self.Bind(wx.EVT_MENU, self.OnPreferences, i)
|
self.Bind(wx.EVT_MENU, self.OnPreferences, i)
|
||||||
fileMenu.AppendSeparator()
|
fileMenu.AppendSeparator()
|
||||||
@ -267,6 +270,11 @@ class mainWindow(configBase.configWindowBase):
|
|||||||
profile.resetGlobalProfile()
|
profile.resetGlobalProfile()
|
||||||
self.updateProfileToControls()
|
self.updateProfileToControls()
|
||||||
|
|
||||||
|
def OnBatchRun(self, e):
|
||||||
|
br = batchRun.batchRunWindow(self)
|
||||||
|
br.Centre()
|
||||||
|
br.Show(True)
|
||||||
|
|
||||||
def OnPreferences(self, e):
|
def OnPreferences(self, e):
|
||||||
prefDialog = preferencesDialog.preferencesDialog(self)
|
prefDialog = preferencesDialog.preferencesDialog(self)
|
||||||
prefDialog.Centre()
|
prefDialog.Centre()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user