Merge branch 'master' of github.com:daid/SkeinPyPy

Conflicts:
	SkeinPyPy_NewUI/newui/mainWindow.py
master
Daid 2012-02-21 18:20:23 +01:00
commit 840998d933
8 changed files with 215 additions and 78 deletions

View File

@ -480,9 +480,9 @@ def getLoopsFromUnprovenMesh(edges, faces, importRadius, vertexes, z):
pointTable = {}
return getDescendingAreaLoops(allPoints, corners, importRadius)
def getLoopLayerAppend(loopLayers, z):
def getLoopLayerAppend(loopLayers, layerCount, z):
'Get next z and add extruder loops.'
settings.printProgress(len(loopLayers), 'slice')
settings.printProgressByNumber(len(loopLayers), layerCount, 'slice')
loopLayer = euclidean.LoopLayer(z)
loopLayers.append(loopLayer)
return loopLayer
@ -812,8 +812,9 @@ class TriangleMesh( group.Group ):
self.zoneArrangement = ZoneArrangement(self.layerHeight, self.getTransformedVertexes())
layerTop = self.cornerMaximum.z - halfHeight * 0.5
z = self.cornerMinimum.z + halfHeight
layerCount = int((layerTop - z) / self.layerHeight)
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
return self.loopLayers

View File

@ -8,7 +8,7 @@ from __future__ import absolute_import
import __init__
import ConfigParser
import os
import os, sys
def getSkeinPyPyConfigInformation():
return {
@ -145,7 +145,7 @@ def getSkeinPyPyConfigInformation():
},'skirt': {
'Activate_Skirt': 'save',
'Convex': 'ignore',
'Gap_over_Perimeter_Width_ratio': 'save',
'Gap_Width_mm': 'save',
'Layers_To_index': 'ignore',
},'chamber': {
'Activate_Chamber': 'ignore',
@ -384,13 +384,20 @@ def storeRepository(repository):
continue
if info[name] == "save":
try:
globalConfigParser.add_section(repository.name)
except:
pass
globalConfigParser.set(repository.name, name, str(p.value))
return repository
def printProgress(layerIndex, procedureName):
print("Progress: ", procedureName, layerIndex)
print ("Progress[" + procedureName + ":" + str(layerIndex) + "]")
sys.stdout.flush()
def printProgressByNumber(layerIndex, numberOfLayers, procedureName):
print("Progress: ", procedureName, layerIndex, numberOfLayers)
print ("Progress[" + procedureName + ":" + str(layerIndex) + ":" + str(numberOfLayers) + "]")
sys.stdout.flush()
def getAlterationFileLines(fileName):
'Get the alteration file line and the text lines from the fileName in the alterations directories.'
@ -422,7 +429,7 @@ class StringSetting(GeneralSetting):
class BooleanSetting( GeneralSetting ):
"A class to display, read & write a boolean."
def setValueToString(self, value):
self.value = value == "True"
self.value = str(value) == "True"
class LatentStringVar:
"This is actually used as 'group' object for Radio buttons. (Did I mention the code is a mess?)"

View File

@ -1,15 +1,15 @@
from __future__ import absolute_import
import __init__
import skeinpypy
import wx, os
from newui import preview3d
from fabmetheus_utilities import archive
from fabmetheus_utilities import settings
from skeinforge_application.skeinforge_utilities import skeinforge_profile
from newui import preview3d
from newui import sliceProgessPanel
def main():
app = wx.App(False)
mainWindow()
@ -22,15 +22,18 @@ class mainWindow(wx.Frame):
menubar = wx.MenuBar()
fileMenu = wx.Menu()
fitem = fileMenu.Append(-1, 'Open Profile...', 'Open Profile...')
self.Bind(wx.EVT_MENU, self.OnLoadProfile, fitem)
fitem = fileMenu.Append(-1, 'Save Profile...', 'Save Profile...')
self.Bind(wx.EVT_MENU, self.OnSaveProfile, fitem)
fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
menubar.Append(fileMenu, '&File')
menubar.Append(wx.Menu(), 'Expert')
#menubar.Append(wx.Menu(), 'Expert')
self.SetMenuBar(menubar)
self.lastPath = ""
self.filename = None
self.progressPanelList = []
self.controlList = []
self.plugins = {}
for m in skeinforge_profile.getCraftTypePluginModule().getCraftSequence():
@ -49,7 +52,7 @@ class mainWindow(wx.Frame):
nb = wx.Notebook(p, size=(500,10))
configPanel = wx.Panel(nb);
nb.AddPage(configPanel, "Print")
nb.AddPage(configPanel, "Print config")
sizer = wx.GridBagSizer(2, 2)
configPanel.SetSizer(sizer)
@ -57,7 +60,7 @@ class mainWindow(wx.Frame):
self.AddSetting(configPanel, "Layer height (mm)", self.plugins['carve'].preferencesDict['Layer_Height_mm'])
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_over_Perimeter_Width_ratio'])
self.AddSetting(configPanel, "Skirt distance (mm)", self.plugins['skirt'].preferencesDict['Gap_Width_mm'])
self.AddTitle(configPanel, "Fill")
self.AddSetting(configPanel, "Solid layers", self.plugins['fill'].preferencesDict['Solid_Surface_Thickness_layers'])
self.AddSetting(configPanel, "Fill Density", self.plugins['fill'].preferencesDict['Infill_Solidity_ratio'])
@ -68,7 +71,7 @@ class mainWindow(wx.Frame):
self.AddSetting(configPanel, "Minimal travel (mm)", self.plugins['dimension'].preferencesDict['Minimum_Travel_for_Retraction_millimeters'])
configPanel = wx.Panel(nb);
nb.AddPage(configPanel, "Machine")
nb.AddPage(configPanel, "Machine config")
sizer = wx.GridBagSizer(2, 2)
configPanel.SetSizer(sizer)
@ -108,20 +111,25 @@ class mainWindow(wx.Frame):
sizer.AddGrowableCol(2)
sizer.AddGrowableRow(0)
p.SetSizer(sizer)
self.panel = p
self.sizer = sizer
self.SetSize((800, 400))
self.Centre()
self.Show(True)
def AddTitle(self, panel, name):
"Add a title row to the configuration panel"
sizer = panel.GetSizer()
title = wx.StaticText(panel, -1, name)
title.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
sizer.Add(title, (sizer.GetRows(),1), (1,2), flag=wx.EXPAND)
sizer.Add(wx.StaticLine(panel), (sizer.GetRows()+1,1), (1,2), flag=wx.EXPAND)
sizer.Add(title, (sizer.GetRows(),1), (1,3), flag=wx.EXPAND)
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):
def AddSetting(self, panel, name, setting, help = False):
"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)
ctrl = None
@ -138,25 +146,41 @@ class mainWindow(wx.Frame):
ctrl.setting = setting
self.controlList.append(ctrl)
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))
sizer.SetRows(sizer.GetRows()+1)
return ctrl
def OnSaveProfile(self, e):
dlg=wx.FileDialog(self, "Select profile file to save", style=wx.FD_SAVE)
def OnLoadProfile(self, e):
dlg=wx.FileDialog(self, "Select profile file to load", self.lastPath, style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("ini files (*.ini)|*.ini")
if dlg.ShowModal() == wx.ID_OK:
profileFile = dlg.GetPath()
self.updateConfig()
self.lastPath = os.path.split(profileFile)[0]
settings.loadGlobalConfig(profileFile)
self.updateConfigToControls()
dlg.Destroy()
def OnSaveProfile(self, e):
dlg=wx.FileDialog(self, "Select profile file to save", self.lastPath, style=wx.FD_SAVE)
dlg.SetWildcard("ini files (*.ini)|*.ini")
if dlg.ShowModal() == wx.ID_OK:
profileFile = dlg.GetPath()
self.lastPath = os.path.split(profileFile)[0]
settings.saveGlobalConfig(profileFile)
self.updateConfigFromControls()
dlg.Destroy()
def OnLoadSTL(self, e):
dlg=wx.FileDialog(self, "Open file to print", style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("OBJ, STL files (*.stl;*.STL;*.obj;*.OBJ;)")
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;*.obj)|*.stl;*.obj")
if dlg.ShowModal() == wx.ID_OK:
self.filename=dlg.GetPath()
if not(os.path.exists(self.filename)):
return
self.lastPath = os.path.split(self.filename)[0]
self.preview3d.loadFile(self.filename)
dlg.Destroy()
def OnSlice(self, e):
if self.filename == None:
@ -164,9 +188,41 @@ class mainWindow(wx.Frame):
for pluginName in self.plugins.keys():
settings.storeRepository(self.plugins[pluginName])
settings.saveGlobalConfig(settings.getDefaultConfigPath())
skeinpypy.runSkein([self.filename])
#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)
self.sizer.Layout()
newSize = self.GetSize();
newSize.IncBy(0, spp.GetSize().GetHeight())
self.SetSize(newSize)
self.progressPanelList.append(spp)
def removeSliceProgress(self, spp):
self.progressPanelList.remove(spp)
newSize = self.GetSize();
newSize.IncBy(0, -spp.GetSize().GetHeight())
self.SetSize(newSize)
spp.Destroy()
for spp in self.progressPanelList:
self.sizer.Remove(spp)
i = 2
for spp in self.progressPanelList:
self.sizer.Add(spp, (i,0), span=(1,4), flag=wx.EXPAND)
i += 1
def updateConfig(self):
def updateConfigToControls(self):
"Update the configuration wx controls to show the new configuration settings"
for pluginName in self.plugins.keys():
settings.getReadRepository(self.plugins[pluginName])
settings.saveGlobalConfig(settings.getDefaultConfigPath())
for ctrl in self.controlList:
if ctrl.setting.__class__ is settings.BooleanSetting:
ctrl.SetValue(ctrl.setting.value)
else:
ctrl.SetValue(str(ctrl.setting.value))
def updateConfigFromControls(self):
"Update the configuration settings with values from the wx controls"
for ctrl in self.controlList:
ctrl.setting.setValueToString(ctrl.GetValue())
for pluginName in self.plugins.keys():

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

View File

@ -0,0 +1,67 @@
from __future__ import absolute_import
import __init__
import wx,sys,math,threading,subprocess
from newui import skeinRun
class sliceProgessPanel(wx.Panel):
def __init__(self, mainWindow, parent, filename):
wx.Panel.__init__(self, parent, -1)
self.mainWindow = mainWindow
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.mainWindow.removeSliceProgress(self)
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()
wx.CallAfter(self.notifyWindow.progressGauge.SetValue, maxValue)
wx.CallAfter(self.notifyWindow.statusText.SetLabel, "Ready.")

View File

@ -328,9 +328,9 @@ class ExportRepository:
self.alsoSendOutputTo = settings.StringSetting().getFromValue('Also Send Output To:', self, '')
self.analyzeGcode = settings.BooleanSetting().getFromValue('Analyze Gcode', self, True)
self.commentChoice = settings.MenuButtonDisplay().getFromName('Comment Choice:', self)
self.doNotDeleteComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Do Not Delete Comments', self, False)
self.doNotDeleteComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Do Not Delete Comments', self, True)
self.deleteCraftingComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Delete Crafting Comments', self, False)
self.deleteAllComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Delete All Comments', self, True)
self.deleteAllComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Delete All Comments', self, False)
exportPluginsFolderPath = archive.getAbsoluteFrozenFolderPath(archive.getCraftPluginsDirectoryPath('export.py'), 'export_plugins')
exportStaticDirectoryPath = os.path.join(exportPluginsFolderPath, 'static_plugins')
exportPluginFileNames = archive.getPluginFileNamesFromDirectoryPath(exportPluginsFolderPath)

View File

@ -131,9 +131,9 @@ class SkirtRepository:
self.fileNameInput = settings.FileNameInput().getFromFileName(
fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Skirt', self, '')
self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skirt')
self.activateSkirt = settings.BooleanSetting().getFromValue('Activate Skirt', self, False)
self.activateSkirt = settings.BooleanSetting().getFromValue('Activate Skirt', self, True)
self.convex = settings.BooleanSetting().getFromValue('Convex:', self, True)
self.gapOverEdgeWidth = settings.FloatSpin().getFromValue(1.0, 'Gap over Perimeter Width (ratio):', self, 5.0, 3.0)
self.gapWidth = settings.FloatSpin().getFromValue(1.0, 'Gap Width (mm):', self, 5.0, 3.0)
self.layersTo = settings.IntSpin().getSingleIncrementFromValue(0, 'Layers To (index):', self, 912345678, 1)
self.executeTitle = 'Skirt'
@ -270,7 +270,7 @@ class SkirtSkein:
self.skirtFlowRate = self.oldFlowRate
elif firstWord == '(<edgeWidth>':
self.edgeWidth = float(splitLine[1])
self.skirtOutset = (self.repository.gapOverEdgeWidth.value + 0.5) * self.edgeWidth
self.skirtOutset = self.repository.gapWidth.value + 0.5 * self.edgeWidth
self.distanceFeedRate.addTagRoundedLine('skirtOutset', self.skirtOutset)
elif firstWord == '(<travelFeedRatePerSecond>':
self.travelFeedRateMinute = 60.0 * float(splitLine[1])

View File

@ -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 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
except:
pass
import os
from newui import mainWindow
from newui import skeinRun
import sys
import platform
import subprocess
__author__ = 'Daid'
__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'
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():
parser = OptionParser()
(options, args) = parser.parse_args()
sys.argv = [sys.argv[0]] + args
if len( args ) > 0:
runSkein(args)
skeinRun.runSkein(args)
else:
mainWindow.main()