Added slicing progress window
Fixed the circular dependency
This commit is contained in:
parent
68944bb221
commit
ac9f65c098
6 changed files with 147 additions and 60 deletions
|
@ -480,9 +480,9 @@ def getLoopsFromUnprovenMesh(edges, faces, importRadius, vertexes, z):
|
||||||
pointTable = {}
|
pointTable = {}
|
||||||
return getDescendingAreaLoops(allPoints, corners, importRadius)
|
return getDescendingAreaLoops(allPoints, corners, importRadius)
|
||||||
|
|
||||||
def getLoopLayerAppend(loopLayers, z):
|
def getLoopLayerAppend(loopLayers, layerCount, z):
|
||||||
'Get next z and add extruder loops.'
|
'Get next z and add extruder loops.'
|
||||||
settings.printProgress(len(loopLayers), 'slice')
|
settings.printProgressByNumber(len(loopLayers), layerCount, 'slice')
|
||||||
loopLayer = euclidean.LoopLayer(z)
|
loopLayer = euclidean.LoopLayer(z)
|
||||||
loopLayers.append(loopLayer)
|
loopLayers.append(loopLayer)
|
||||||
return loopLayer
|
return loopLayer
|
||||||
|
@ -812,8 +812,9 @@ class TriangleMesh( group.Group ):
|
||||||
self.zoneArrangement = ZoneArrangement(self.layerHeight, self.getTransformedVertexes())
|
self.zoneArrangement = ZoneArrangement(self.layerHeight, self.getTransformedVertexes())
|
||||||
layerTop = self.cornerMaximum.z - halfHeight * 0.5
|
layerTop = self.cornerMaximum.z - halfHeight * 0.5
|
||||||
z = self.cornerMinimum.z + halfHeight
|
z = self.cornerMinimum.z + halfHeight
|
||||||
|
layerCount = int((layerTop - z) / self.layerHeight)
|
||||||
while z < layerTop:
|
while z < layerTop:
|
||||||
getLoopLayerAppend(self.loopLayers, z).loops = self.getLoopsFromMesh(self.zoneArrangement.getEmptyZ(z))
|
getLoopLayerAppend(self.loopLayers, layerCount, z).loops = self.getLoopsFromMesh(self.zoneArrangement.getEmptyZ(z))
|
||||||
z += self.layerHeight
|
z += self.layerHeight
|
||||||
return self.loopLayers
|
return self.loopLayers
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ from __future__ import absolute_import
|
||||||
import __init__
|
import __init__
|
||||||
|
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
import os
|
import os, sys
|
||||||
|
|
||||||
def getSkeinPyPyConfigInformation():
|
def getSkeinPyPyConfigInformation():
|
||||||
return {
|
return {
|
||||||
|
@ -388,9 +388,12 @@ def storeRepository(repository):
|
||||||
return repository
|
return repository
|
||||||
|
|
||||||
def printProgress(layerIndex, procedureName):
|
def printProgress(layerIndex, procedureName):
|
||||||
print("Progress: ", procedureName, layerIndex)
|
print ("Progress[" + procedureName + ":" + str(layerIndex) + "]")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
def printProgressByNumber(layerIndex, numberOfLayers, procedureName):
|
def printProgressByNumber(layerIndex, numberOfLayers, procedureName):
|
||||||
print("Progress: ", procedureName, layerIndex, numberOfLayers)
|
print ("Progress[" + procedureName + ":" + str(layerIndex) + ":" + str(numberOfLayers) + "]")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
def getAlterationFileLines(fileName):
|
def getAlterationFileLines(fileName):
|
||||||
'Get the alteration file line and the text lines from the fileName in the alterations directories.'
|
'Get the alteration file line and the text lines from the fileName in the alterations directories.'
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
import __init__
|
import __init__
|
||||||
|
|
||||||
import skeinpypy
|
|
||||||
|
|
||||||
import wx, os
|
import wx, os
|
||||||
|
|
||||||
from newui import preview3d
|
|
||||||
from fabmetheus_utilities import archive
|
from fabmetheus_utilities import archive
|
||||||
from fabmetheus_utilities import settings
|
from fabmetheus_utilities import settings
|
||||||
from skeinforge_application.skeinforge_utilities import skeinforge_profile
|
from skeinforge_application.skeinforge_utilities import skeinforge_profile
|
||||||
|
|
||||||
|
from newui import preview3d
|
||||||
|
from newui import sliceProgessPanel
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
app = wx.App(False)
|
app = wx.App(False)
|
||||||
mainWindow()
|
mainWindow()
|
||||||
|
@ -30,6 +30,7 @@ class mainWindow(wx.Frame):
|
||||||
menubar.Append(wx.Menu(), 'Expert')
|
menubar.Append(wx.Menu(), 'Expert')
|
||||||
self.SetMenuBar(menubar)
|
self.SetMenuBar(menubar)
|
||||||
|
|
||||||
|
self.lastPath = ""
|
||||||
self.filename = None
|
self.filename = None
|
||||||
self.controlList = []
|
self.controlList = []
|
||||||
self.plugins = {}
|
self.plugins = {}
|
||||||
|
@ -106,6 +107,10 @@ class mainWindow(wx.Frame):
|
||||||
sizer.AddGrowableRow(0)
|
sizer.AddGrowableRow(0)
|
||||||
p.SetSizer(sizer)
|
p.SetSizer(sizer)
|
||||||
|
|
||||||
|
self.panel = p
|
||||||
|
self.sizer = sizer
|
||||||
|
self.sizer.SetRows(2)
|
||||||
|
|
||||||
self.SetSize((800, 400))
|
self.SetSize((800, 400))
|
||||||
self.Centre()
|
self.Centre()
|
||||||
self.Show(True)
|
self.Show(True)
|
||||||
|
@ -138,21 +143,25 @@ class mainWindow(wx.Frame):
|
||||||
sizer.SetRows(sizer.GetRows()+1)
|
sizer.SetRows(sizer.GetRows()+1)
|
||||||
|
|
||||||
def OnSaveProfile(self, e):
|
def OnSaveProfile(self, e):
|
||||||
dlg=wx.FileDialog(self, "Select profile file to save", style=wx.FD_SAVE)
|
dlg=wx.FileDialog(self, "Select profile file to save", self.lastPath, style=wx.FD_SAVE)
|
||||||
dlg.SetWildcard("ini files (*.ini)|*.ini")
|
dlg.SetWildcard("ini files (*.ini)|*.ini")
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
profileFile = dlg.GetPath()
|
profileFile = dlg.GetPath()
|
||||||
|
self.lastPath = os.path.split(profileFile)[0]
|
||||||
self.updateConfig()
|
self.updateConfig()
|
||||||
settings.saveGlobalConfig(profileFile)
|
settings.saveGlobalConfig(profileFile)
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
def OnLoadSTL(self, e):
|
def OnLoadSTL(self, e):
|
||||||
dlg=wx.FileDialog(self, "Open file to print", style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
|
dlg=wx.FileDialog(self, "Open file to print", self.lastPath, style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
|
||||||
dlg.SetWildcard("OBJ, STL files (*.stl;*.STL;*.obj;*.OBJ;)")
|
dlg.SetWildcard("OBJ, STL files (*.stl;*.obj)|*.stl;*.obj")
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
self.filename=dlg.GetPath()
|
self.filename=dlg.GetPath()
|
||||||
if not(os.path.exists(self.filename)):
|
if not(os.path.exists(self.filename)):
|
||||||
return
|
return
|
||||||
|
self.lastPath = os.path.split(self.filename)[0]
|
||||||
self.preview3d.loadFile(self.filename)
|
self.preview3d.loadFile(self.filename)
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
def OnSlice(self, e):
|
def OnSlice(self, e):
|
||||||
if self.filename == None:
|
if self.filename == None:
|
||||||
|
@ -160,7 +169,11 @@ class mainWindow(wx.Frame):
|
||||||
for pluginName in self.plugins.keys():
|
for pluginName in self.plugins.keys():
|
||||||
settings.storeRepository(self.plugins[pluginName])
|
settings.storeRepository(self.plugins[pluginName])
|
||||||
settings.saveGlobalConfig(settings.getDefaultConfigPath())
|
settings.saveGlobalConfig(settings.getDefaultConfigPath())
|
||||||
skeinpypy.runSkein([self.filename])
|
#skeinpypy.runSkein([self.filename])
|
||||||
|
spp = sliceProgessPanel.sliceProgessPanel(self.panel, self.filename)
|
||||||
|
self.sizer.Add(spp, (self.sizer.GetRows(),0), span=(1,4), flag=wx.EXPAND)
|
||||||
|
self.sizer.SetRows(self.sizer.GetRows()+1)
|
||||||
|
self.sizer.Layout()
|
||||||
|
|
||||||
def updateConfig(self):
|
def updateConfig(self):
|
||||||
for ctrl in self.controlList:
|
for ctrl in self.controlList:
|
||||||
|
|
48
SkeinPyPy_NewUI/newui/skeinRun.py
Normal file
48
SkeinPyPy_NewUI/newui/skeinRun.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
import platform, os, subprocess, sys
|
||||||
|
|
||||||
|
from skeinforge_application.skeinforge_utilities import skeinforge_craft
|
||||||
|
|
||||||
|
def getPyPyExe():
|
||||||
|
"Return the path to the pypy executable if we can find it. Else return False"
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
pypyExe = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../pypy/pypy.exe"));
|
||||||
|
else:
|
||||||
|
pypyExe = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../pypy/bin/pypy"));
|
||||||
|
if os.path.exists(pypyExe):
|
||||||
|
return pypyExe
|
||||||
|
pypyExe = "/bin/pypy";
|
||||||
|
if os.path.exists(pypyExe):
|
||||||
|
return pypyExe
|
||||||
|
pypyExe = "/usr/bin/pypy";
|
||||||
|
if os.path.exists(pypyExe):
|
||||||
|
return pypyExe
|
||||||
|
pypyExe = "/usr/local/bin/pypy";
|
||||||
|
if os.path.exists(pypyExe):
|
||||||
|
return pypyExe
|
||||||
|
return False
|
||||||
|
|
||||||
|
def runSkein(fileNames):
|
||||||
|
"Run the slicer on the files. If we are running with PyPy then just do the slicing action. If we are running as Python, try to find pypy."
|
||||||
|
pypyExe = getPyPyExe()
|
||||||
|
for fileName in fileNames:
|
||||||
|
if platform.python_implementation() == "PyPy":
|
||||||
|
skeinforge_craft.writeOutput(fileName)
|
||||||
|
elif pypyExe == False:
|
||||||
|
print "************************************************"
|
||||||
|
print "* Failed to find pypy, so slicing with python! *"
|
||||||
|
print "************************************************"
|
||||||
|
skeinforge_craft.writeOutput(fileName)
|
||||||
|
print "************************************************"
|
||||||
|
print "* Failed to find pypy, so sliced with python! *"
|
||||||
|
print "************************************************"
|
||||||
|
else:
|
||||||
|
subprocess.call([pypyExe, os.path.join(sys.path[0], sys.argv[0]), fileName])
|
||||||
|
|
||||||
|
def getSkeinCommand(filename):
|
||||||
|
pypyExe = getPyPyExe()
|
||||||
|
if pypyExe == False:
|
||||||
|
pypyExe = sys.executable
|
||||||
|
return [pypyExe, os.path.join(sys.path[0], sys.argv[0]), filename]
|
||||||
|
|
64
SkeinPyPy_NewUI/newui/sliceProgessPanel.py
Normal file
64
SkeinPyPy_NewUI/newui/sliceProgessPanel.py
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
|
import __init__
|
||||||
|
|
||||||
|
import wx,sys,math,threading,subprocess
|
||||||
|
from newui import skeinRun
|
||||||
|
|
||||||
|
class sliceProgessPanel(wx.Panel):
|
||||||
|
def __init__(self, parent, filename):
|
||||||
|
wx.Panel.__init__(self, parent, -1)
|
||||||
|
self.filename = filename
|
||||||
|
self.abort = False
|
||||||
|
|
||||||
|
box = wx.StaticBox(self, -1, filename)
|
||||||
|
sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
|
||||||
|
|
||||||
|
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
mainSizer.Add(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.Bind(wx.EVT_BUTTON, self.OnAbort, self.abortButton)
|
||||||
|
|
||||||
|
self.SetSizer(mainSizer)
|
||||||
|
self.thread = WorkerThread(self, filename)
|
||||||
|
|
||||||
|
def OnAbort(self, e):
|
||||||
|
if self.abort:
|
||||||
|
self.Destroy()
|
||||||
|
else:
|
||||||
|
self.abort = True
|
||||||
|
|
||||||
|
class WorkerThread(threading.Thread):
|
||||||
|
def __init__(self, notifyWindow, filename):
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
self.filename = filename
|
||||||
|
self.notifyWindow = notifyWindow
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
p = subprocess.Popen(skeinRun.getSkeinCommand(self.filename), 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.notifyWindow.progressGauge.SetRange, maxValue)
|
||||||
|
wx.CallAfter(self.notifyWindow.statusText.SetLabel, progress[0] + " [" + progress[1] + "/" + str(maxValue) + "]")
|
||||||
|
wx.CallAfter(self.notifyWindow.progressGauge.SetValue, int(progress[1]))
|
||||||
|
else:
|
||||||
|
wx.CallAfter(self.notifyWindow.statusText.SetLabel, line)
|
||||||
|
if self.notifyWindow.abort:
|
||||||
|
p.terminate()
|
||||||
|
wx.CallAfter(self.notifyWindow.statusText.SetLabel, "Aborted by user.")
|
||||||
|
return
|
||||||
|
line = p.stdout.readline()
|
||||||
|
|
|
@ -12,16 +12,10 @@ The slicing code is the same as Skeinforge. But the UI has been revamped to be..
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
from skeinforge_application.skeinforge_utilities import skeinforge_craft
|
|
||||||
#For some reason the newui import fails when we are importing this from newui.mainWindow (circle references not allowed?) in that case we don't need the UI so skip it.
|
|
||||||
try:
|
|
||||||
from newui import mainWindow
|
from newui import mainWindow
|
||||||
except:
|
from newui import skeinRun
|
||||||
pass
|
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import platform
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
__author__ = 'Daid'
|
__author__ = 'Daid'
|
||||||
__credits__ = """
|
__credits__ = """
|
||||||
|
@ -47,48 +41,12 @@ Art of Illusion <http://www.artofillusion.org/>"""
|
||||||
|
|
||||||
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
||||||
|
|
||||||
def getPyPyExe():
|
|
||||||
"Return the path to the pypy executable if we can find it. Else return False"
|
|
||||||
if platform.system() == "Windows":
|
|
||||||
pypyExe = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../pypy/pypy.exe"));
|
|
||||||
else:
|
|
||||||
pypyExe = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../pypy/bin/pypy"));
|
|
||||||
if os.path.exists(pypyExe):
|
|
||||||
return pypyExe
|
|
||||||
pypyExe = "/bin/pypy";
|
|
||||||
if os.path.exists(pypyExe):
|
|
||||||
return pypyExe
|
|
||||||
pypyExe = "/usr/bin/pypy";
|
|
||||||
if os.path.exists(pypyExe):
|
|
||||||
return pypyExe
|
|
||||||
pypyExe = "/usr/local/bin/pypy";
|
|
||||||
if os.path.exists(pypyExe):
|
|
||||||
return pypyExe
|
|
||||||
return False
|
|
||||||
|
|
||||||
def runSkein(fileNames):
|
|
||||||
"Run the slicer on the files. If we are running with PyPy then just do the slicing action. If we are running as Python, try to find pypy."
|
|
||||||
pypyExe = getPyPyExe()
|
|
||||||
for fileName in fileNames:
|
|
||||||
if platform.python_implementation() == "PyPy":
|
|
||||||
skeinforge_craft.writeOutput(fileName)
|
|
||||||
elif pypyExe == False:
|
|
||||||
print "************************************************"
|
|
||||||
print "* Failed to find pypy, so slicing with python! *"
|
|
||||||
print "************************************************"
|
|
||||||
skeinforge_craft.writeOutput(fileName)
|
|
||||||
print "************************************************"
|
|
||||||
print "* Failed to find pypy, so sliced with python! *"
|
|
||||||
print "************************************************"
|
|
||||||
else:
|
|
||||||
subprocess.call([pypyExe, __file__, fileName])
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
sys.argv = [sys.argv[0]] + args
|
sys.argv = [sys.argv[0]] + args
|
||||||
if len( args ) > 0:
|
if len( args ) > 0:
|
||||||
runSkein(args)
|
skeinRun.runSkein(args)
|
||||||
else:
|
else:
|
||||||
mainWindow.main()
|
mainWindow.main()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue