Fix resources, imports and indentations.

master
Ilya Kulakov 2012-12-05 19:14:06 +07:00
parent 132e6381ea
commit 377ea03c15
8 changed files with 2102 additions and 1971 deletions

View File

@ -9,10 +9,7 @@ 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
import __init__
import sys
import platform
from optparse import OptionParser from optparse import OptionParser
from util import profile from util import profile
@ -36,6 +33,7 @@ Reece.Arnott <http://forums.reprap.org/profile.php?12,152>
Wade <http://forums.reprap.org/profile.php?12,489> Wade <http://forums.reprap.org/profile.php?12,489>
Xsainnz <http://forums.reprap.org/profile.php?12,563> Xsainnz <http://forums.reprap.org/profile.php?12,563>
Zach Hoeken <http://blog.zachhoeken.com/> Zach Hoeken <http://blog.zachhoeken.com/>
Ilya Kulakov (kulakov.ilya@gmail.com)
Organizations: Organizations:
Ultimaker <http://www.ultimaker.com> Ultimaker <http://www.ultimaker.com>
@ -45,12 +43,18 @@ __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agp
def main(): def main():
parser = OptionParser(usage="usage: %prog [options] <filename>.stl") parser = OptionParser(usage="usage: %prog [options] <filename>.stl")
parser.add_option("-i", "--ini", action="store", type="string", dest="profileini", help="Load settings from a profile ini file") parser.add_option("-i", "--ini", action="store", type="string", dest="profileini",
parser.add_option("-P", "--project", action="store_true", dest="openprojectplanner", help="Open the project planner") help="Load settings from a profile ini file")
parser.add_option("-F", "--flat", action="store_true", dest="openflatslicer", help="Open the 2D SVG slicer (unfinished)") parser.add_option("-P", "--project", action="store_true", dest="openprojectplanner",
parser.add_option("-r", "--print", action="store", type="string", dest="printfile", help="Open the printing interface, instead of the normal cura interface.") help="Open the project planner")
parser.add_option("-p", "--profile", action="store", type="string", dest="profile", help="Internal option, do not use!") parser.add_option("-F", "--flat", action="store_true", dest="openflatslicer",
parser.add_option("-s", "--slice", action="store_true", dest="slice", help="Slice the given files instead of opening them in Cura") help="Open the 2D SVG slicer (unfinished)")
parser.add_option("-r", "--print", action="store", type="string", dest="printfile",
help="Open the printing interface, instead of the normal cura interface.")
parser.add_option("-p", "--profile", action="store", type="string", dest="profile",
help="Internal option, do not use!")
parser.add_option("-s", "--slice", action="store_true", dest="slice",
help="Slice the given files instead of opening them in Cura")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
if options.profile != None: if options.profile != None:
profile.loadGlobalProfileFromString(options.profile) profile.loadGlobalProfileFromString(options.profile)
@ -58,30 +62,36 @@ def main():
profile.loadGlobalProfile(options.profileini) profile.loadGlobalProfile(options.profileini)
if options.openprojectplanner != None: if options.openprojectplanner != None:
from gui import projectPlanner from gui import projectPlanner
projectPlanner.main() projectPlanner.main()
return return
if options.openflatslicer != None: if options.openflatslicer != None:
from gui import flatSlicerWindow from gui import flatSlicerWindow
flatSlicerWindow.main() flatSlicerWindow.main()
return return
if options.printfile != None: if options.printfile != None:
from gui import printWindow from gui import printWindow
printWindow.startPrintInterface(options.printfile) printWindow.startPrintInterface(options.printfile)
return return
if options.slice != None: if options.slice != None:
from util import sliceRun from util import sliceRun
sliceRun.runSlice(args) sliceRun.runSlice(args)
else: else:
if len(args) > 0: if len(args) > 0:
profile.putPreference('lastFile', ';'.join(args)) profile.putPreference('lastFile', ';'.join(args))
from gui import splashScreen from gui import splashScreen
splashScreen.showSplash(mainWindowRunCallback) splashScreen.showSplash(mainWindowRunCallback)
def mainWindowRunCallback(splash): def mainWindowRunCallback(splash):
from gui import mainWindow from gui import mainWindow
mainWindow.main(splash) mainWindow.main(splash)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -1,13 +1,18 @@
# coding=utf-8
from __future__ import absolute_import from __future__ import absolute_import
import __init__
import wx, os, platform, types, webbrowser, threading, time, re import webbrowser
import threading
import time
import wx
import wx.wizard import wx.wizard
from gui import firmwareInstall from gui import firmwareInstall
from gui import toolbarUtil from gui import toolbarUtil
from util import machineCom from util import machineCom
from util import profile from util import profile
from util.resources import getPathForImage
class InfoBox(wx.Panel): class InfoBox(wx.Panel):
def __init__(self, parent): def __init__(self, parent):
@ -17,10 +22,15 @@ class InfoBox(wx.Panel):
self.sizer = wx.GridBagSizer(5, 5) self.sizer = wx.GridBagSizer(5, 5)
self.SetSizer(self.sizer) self.SetSizer(self.sizer)
self.attentionBitmap = toolbarUtil.getBitmapImage('attention.png') self.attentionBitmap = wx.Bitmap(getPathForImage('attention.png'))
self.errorBitmap = toolbarUtil.getBitmapImage('error.png') self.errorBitmap = wx.Bitmap(getPathForImage('error.png'))
self.readyBitmap = toolbarUtil.getBitmapImage('ready.png') self.readyBitmap = wx.Bitmap(getPathForImage('ready.png'))
self.busyBitmap = [toolbarUtil.getBitmapImage('busy-0.png'), toolbarUtil.getBitmapImage('busy-1.png'), toolbarUtil.getBitmapImage('busy-2.png'), toolbarUtil.getBitmapImage('busy-3.png')] self.busyBitmap = [
wx.Bitmap(getPathForImage('busy-0.png')),
wx.Bitmap(getPathForImage('busy-1.png')),
wx.Bitmap(getPathForImage('busy-2.png')),
wx.Bitmap(getPathForImage('busy-3.png'))
]
self.bitmap = wx.StaticBitmap(self, -1, wx.EmptyBitmapRGBA(24, 24, red=255, green=255, blue=255, alpha=1)) self.bitmap = wx.StaticBitmap(self, -1, wx.EmptyBitmapRGBA(24, 24, red=255, green=255, blue=255, alpha=1))
self.text = wx.StaticText(self, -1, '') self.text = wx.StaticText(self, -1, '')
@ -73,6 +83,7 @@ class InfoBox(wx.Panel):
self.busyState = None self.busyState = None
self.bitmap.SetBitmap(self.attentionBitmap) self.bitmap.SetBitmap(self.attentionBitmap)
class InfoPage(wx.wizard.WizardPageSimple): class InfoPage(wx.wizard.WizardPageSimple):
def __init__(self, parent, title): def __init__(self, parent, title):
wx.wizard.WizardPageSimple.__init__(self, parent) wx.wizard.WizardPageSimple.__init__(self, parent)
@ -179,6 +190,7 @@ class InfoPage(wx.wizard.WizardPageSimple):
def StoreData(self): def StoreData(self):
pass pass
class FirstInfoPage(InfoPage): class FirstInfoPage(InfoPage):
def __init__(self, parent): def __init__(self, parent):
super(FirstInfoPage, self).__init__(parent, "First time run wizard") super(FirstInfoPage, self).__init__(parent, "First time run wizard")
@ -188,13 +200,16 @@ class FirstInfoPage(InfoPage):
self.AddText('* Configure Cura for your machine') self.AddText('* Configure Cura for your machine')
self.AddText('* Upgrade your firmware') self.AddText('* Upgrade your firmware')
self.AddText('* Check if your machine is working safely') self.AddText('* Check if your machine is working safely')
#self.AddText('* Calibrate your machine') #self.AddText('* Calibrate your machine')
#self.AddText('* Do your first print') #self.AddText('* Do your first print')
class RepRapInfoPage(InfoPage): class RepRapInfoPage(InfoPage):
def __init__(self, parent): def __init__(self, parent):
super(RepRapInfoPage, self).__init__(parent, "RepRap information") super(RepRapInfoPage, self).__init__(parent, "RepRap information")
self.AddText('RepRap machines are vastly different, and there is no\ndefault configuration in Cura for any of them.') self.AddText(
'RepRap machines are vastly different, and there is no\ndefault configuration in Cura for any of them.')
self.AddText('If you like a default profile for your machine added,\nthen make an issue on github.') self.AddText('If you like a default profile for your machine added,\nthen make an issue on github.')
self.AddSeperator() self.AddSeperator()
self.AddText('You will have to manually install Marlin or Sprinter firmware.') self.AddText('You will have to manually install Marlin or Sprinter firmware.')
@ -215,6 +230,7 @@ class RepRapInfoPage(InfoPage):
profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2) profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue())) profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
class MachineSelectPage(InfoPage): class MachineSelectPage(InfoPage):
def __init__(self, parent): def __init__(self, parent):
super(MachineSelectPage, self).__init__(parent, "Select your machine") super(MachineSelectPage, self).__init__(parent, "Select your machine")
@ -252,14 +268,18 @@ class MachineSelectPage(InfoPage):
profile.putProfileSetting('machine_center_y', '40') profile.putProfileSetting('machine_center_y', '40')
profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2) profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)
class FirmwareUpgradePage(InfoPage): class FirmwareUpgradePage(InfoPage):
def __init__(self, parent): def __init__(self, parent):
super(FirmwareUpgradePage, self).__init__(parent, "Upgrade Ultimaker Firmware") super(FirmwareUpgradePage, self).__init__(parent, "Upgrade Ultimaker Firmware")
self.AddText('Firmware is the piece of software running directly on your 3D printer.\nThis firmware controls the step motors, regulates the temperature\nand ultimately makes your printer work.') self.AddText(
'Firmware is the piece of software running directly on your 3D printer.\nThis firmware controls the step motors, regulates the temperature\nand ultimately makes your printer work.')
self.AddHiddenSeperator() self.AddHiddenSeperator()
self.AddText('The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier.') self.AddText(
'The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier.')
self.AddHiddenSeperator() self.AddHiddenSeperator()
self.AddText('Cura requires these new features and thus\nyour firmware will most likely need to be upgraded.\nYou will get the chance to do so now.') self.AddText(
'Cura requires these new features and thus\nyour firmware will most likely need to be upgraded.\nYou will get the chance to do so now.')
upgradeButton, skipUpgradeButton = self.AddDualButton('Upgrade to Marlin firmware', 'Skip upgrade') upgradeButton, skipUpgradeButton = self.AddDualButton('Upgrade to Marlin firmware', 'Skip upgrade')
upgradeButton.Bind(wx.EVT_BUTTON, self.OnUpgradeClick) upgradeButton.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)
skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick) skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick)
@ -283,22 +303,24 @@ class FirmwareUpgradePage(InfoPage):
def OnUrlClick(self, e): def OnUrlClick(self, e):
webbrowser.open('http://daid.mine.nu/~daid/marlin_build/') webbrowser.open('http://daid.mine.nu/~daid/marlin_build/')
class UltimakerCheckupPage(InfoPage): class UltimakerCheckupPage(InfoPage):
def __init__(self, parent): def __init__(self, parent):
super(UltimakerCheckupPage, self).__init__(parent, "Ultimaker Checkup") super(UltimakerCheckupPage, self).__init__(parent, "Ultimaker Checkup")
self.checkBitmap = toolbarUtil.getBitmapImage('checkmark.png') self.checkBitmap = wx.Bitmap(getPathForImage('checkmark.png'))
self.crossBitmap = toolbarUtil.getBitmapImage('cross.png') self.crossBitmap = wx.Bitmap(getPathForImage('cross.png'))
self.unknownBitmap = toolbarUtil.getBitmapImage('question.png') self.unknownBitmap = wx.Bitmap(getPathForImage('question.png'))
self.endStopNoneBitmap = toolbarUtil.getBitmapImage('endstop_none.png') self.endStopNoneBitmap = wx.Bitmap(getPathForImage('endstop_none.png'))
self.endStopXMinBitmap = toolbarUtil.getBitmapImage('endstop_xmin.png') self.endStopXMinBitmap = wx.Bitmap(getPathForImage('endstop_xmin.png'))
self.endStopXMaxBitmap = toolbarUtil.getBitmapImage('endstop_xmax.png') self.endStopXMaxBitmap = wx.Bitmap(getPathForImage('endstop_xmax.png'))
self.endStopYMinBitmap = toolbarUtil.getBitmapImage('endstop_ymin.png') self.endStopYMinBitmap = wx.Bitmap(getPathForImage('endstop_ymin.png'))
self.endStopYMaxBitmap = toolbarUtil.getBitmapImage('endstop_ymax.png') self.endStopYMaxBitmap = wx.Bitmap(getPathForImage('endstop_ymax.png'))
self.endStopZMinBitmap = toolbarUtil.getBitmapImage('endstop_zmin.png') self.endStopZMinBitmap = wx.Bitmap(getPathForImage('endstop_zmin.png'))
self.endStopZMaxBitmap = toolbarUtil.getBitmapImage('endstop_zmax.png') self.endStopZMaxBitmap = wx.Bitmap(getPathForImage('endstop_zmax.png'))
self.AddText('It is a good idea to do a few sanity checks now on your Ultimaker.\nYou can skip these if you know your machine is functional.') self.AddText(
'It is a good idea to do a few sanity checks now on your Ultimaker.\nYou can skip these if you know your machine is functional.')
b1, b2 = self.AddDualButton('Run checks', 'Skip checks') b1, b2 = self.AddDualButton('Run checks', 'Skip checks')
b1.Bind(wx.EVT_BUTTON, self.OnCheckClick) b1.Bind(wx.EVT_BUTTON, self.OnCheckClick)
b2.Bind(wx.EVT_BUTTON, self.OnSkipClick) b2.Bind(wx.EVT_BUTTON, self.OnSkipClick)
@ -469,6 +491,7 @@ class UltimakerCheckupPage(InfoPage):
def mcZChange(self, newZ): def mcZChange(self, newZ):
pass pass
class UltimakerCalibrationPage(InfoPage): class UltimakerCalibrationPage(InfoPage):
def __init__(self, parent): def __init__(self, parent):
super(UltimakerCalibrationPage, self).__init__(parent, "Ultimaker Calibration") super(UltimakerCalibrationPage, self).__init__(parent, "Ultimaker Calibration")
@ -484,12 +507,14 @@ class UltimakerCalibrationPage(InfoPage):
self.AddSeperator() self.AddSeperator()
self.AddText("First we need the diameter of your filament:") self.AddText("First we need the diameter of your filament:")
self.filamentDiameter = self.AddTextCtrl(profile.getProfileSetting('filament_diameter')) self.filamentDiameter = self.AddTextCtrl(profile.getProfileSetting('filament_diameter'))
self.AddText("If you do not own digital Calipers that can measure\nat least 2 digits then use 2.89mm.\nWhich is the average diameter of most filament.") self.AddText(
"If you do not own digital Calipers that can measure\nat least 2 digits then use 2.89mm.\nWhich is the average diameter of most filament.")
self.AddText("Note: This value can be changed later at any time.") self.AddText("Note: This value can be changed later at any time.")
def StoreData(self): def StoreData(self):
profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue()) profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue())
class UltimakerCalibrateStepsPerEPage(InfoPage): class UltimakerCalibrateStepsPerEPage(InfoPage):
def __init__(self, parent): def __init__(self, parent):
super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, "Ultimaker Calibration") super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, "Ultimaker Calibration")
@ -508,7 +533,8 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
self.stepsPerEInput = self.AddTextCtrl(profile.getPreference('steps_per_e')) self.stepsPerEInput = self.AddTextCtrl(profile.getPreference('steps_per_e'))
self.AddText("You can repeat these steps to get better calibration.") self.AddText("You can repeat these steps to get better calibration.")
self.AddSeperator() self.AddSeperator()
self.AddText("If you still have filament in your printer which needs\nheat to remove, press the heat up button below:") self.AddText(
"If you still have filament in your printer which needs\nheat to remove, press the heat up button below:")
self.heatButton = self.AddButton("Heatup for filament removal") self.heatButton = self.AddButton("Heatup for filament removal")
self.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick) self.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick)
@ -531,7 +557,9 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
currentEValue = float(self.stepsPerEInput.GetValue()) currentEValue = float(self.stepsPerEInput.GetValue())
self.comm = machineCom.MachineCom() self.comm = machineCom.MachineCom()
if not self.comm.isOpen(): if not self.comm.isOpen():
wx.MessageBox("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable", 'Printer error', wx.OK | wx.ICON_INFORMATION) wx.MessageBox(
"Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable",
'Printer error', wx.OK | wx.ICON_INFORMATION)
self.heatButton.Enable(True) self.heatButton.Enable(True)
self.extrudeButton.Enable(True) self.extrudeButton.Enable(True)
return return
@ -561,7 +589,9 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
self.extrudeButton.Enable(False) self.extrudeButton.Enable(False)
self.comm = machineCom.MachineCom() self.comm = machineCom.MachineCom()
if not self.comm.isOpen(): if not self.comm.isOpen():
wx.MessageBox("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable", 'Printer error', wx.OK | wx.ICON_INFORMATION) wx.MessageBox(
"Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable",
'Printer error', wx.OK | wx.ICON_INFORMATION)
self.heatButton.Enable(True) self.heatButton.Enable(True)
self.extrudeButton.Enable(True) self.extrudeButton.Enable(True)
return return
@ -577,7 +607,9 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
time.sleep(3) time.sleep(3)
self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out. self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out.
wx.MessageBox('Wait till you can remove the filament from the machine, and press OK.\n(Temperature is set to 200C)', 'Machine heatup', wx.OK | wx.ICON_INFORMATION) wx.MessageBox(
'Wait till you can remove the filament from the machine, and press OK.\n(Temperature is set to 200C)',
'Machine heatup', wx.OK | wx.ICON_INFORMATION)
self.sendGCommand('M104 S0') self.sendGCommand('M104 S0')
time.sleep(1) time.sleep(1)
self.comm.close() self.comm.close()
@ -596,6 +628,7 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
def StoreData(self): def StoreData(self):
profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue()) profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue())
class configWizard(wx.wizard.Wizard): class configWizard(wx.wizard.Wizard):
def __init__(self): def __init__(self):
super(configWizard, self).__init__(None, -1, "Configuration Wizard") super(configWizard, self).__init__(None, -1, "Configuration Wizard")

View File

@ -1,14 +1,20 @@
import math, time, os # coding=utf-8
from __future__ import absolute_import
import math
from util import meshLoader from util import meshLoader
from util import util3d from util import util3d
from util import profile from util import profile
from util.resources import getPathForMesh
try: try:
import OpenGL import OpenGL
OpenGL.ERROR_CHECKING = False OpenGL.ERROR_CHECKING = False
from OpenGL.GLU import * from OpenGL.GLU import *
from OpenGL.GL import * from OpenGL.GL import *
hasOpenGLlibs = True hasOpenGLlibs = True
except: except:
print "Failed to find PyOpenGL: http://pyopengl.sourceforge.net/" print "Failed to find PyOpenGL: http://pyopengl.sourceforge.net/"
@ -61,7 +67,7 @@ def DrawMachine(machineSize):
global platformMesh global platformMesh
if platformMesh == None: if platformMesh == None:
platformMesh = meshLoader.loadMesh(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../images", 'ultimaker_platform.stl'))) platformMesh = meshLoader.loadMesh(getPathForMesh('ultimaker_platform.stl'))
platformMesh.setRotateMirror(0, False, False, False, False, False) platformMesh.setRotateMirror(0, False, False, False, False, False)
DrawMesh(platformMesh) DrawMesh(platformMesh)
@ -248,6 +254,7 @@ def DrawMachine(machineSize):
glPopMatrix() glPopMatrix()
glEnable(GL_DEPTH_TEST) glEnable(GL_DEPTH_TEST)
def ResetMatrixRotationAndScale(): def ResetMatrixRotationAndScale():
matrix = glGetFloatv(GL_MODELVIEW_MATRIX) matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
noZ = False noZ = False
@ -278,6 +285,7 @@ def ResetMatrixRotationAndScale():
glLoadMatrixf(matrix) glLoadMatrixf(matrix)
return noZ return noZ
def DrawBox(vMin, vMax): def DrawBox(vMin, vMax):
glBegin(GL_LINE_LOOP) glBegin(GL_LINE_LOOP)
glVertex3f(vMin[0], vMin[1], vMin[2]) glVertex3f(vMin[0], vMin[1], vMin[2])
@ -303,6 +311,7 @@ def DrawBox(vMin, vMax):
glVertex3f(vMin[0], vMax[1], vMax[2]) glVertex3f(vMin[0], vMax[1], vMax[2])
glEnd() glEnd()
def DrawMeshOutline(mesh): def DrawMeshOutline(mesh):
glEnable(GL_CULL_FACE) glEnable(GL_CULL_FACE)
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
@ -317,6 +326,7 @@ def DrawMeshOutline(mesh):
glDisableClientState(GL_VERTEX_ARRAY) glDisableClientState(GL_VERTEX_ARRAY)
def DrawMesh(mesh): def DrawMesh(mesh):
glEnable(GL_CULL_FACE) glEnable(GL_CULL_FACE)
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
@ -346,6 +356,7 @@ def DrawMesh(mesh):
glDisableClientState(GL_VERTEX_ARRAY) glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
def DrawGCodeLayer(layer): def DrawGCodeLayer(layer):
filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
filamentArea = math.pi * filamentRadius * filamentRadius filamentArea = math.pi * filamentRadius * filamentRadius

View File

@ -1,7 +1,14 @@
# coding=utf-8
from __future__ import absolute_import from __future__ import absolute_import
import __init__
import wx, threading, re, subprocess, sys, os, time, platform import threading
import re
import subprocess
import sys
import time
import platform
import wx
from wx.lib import buttons from wx.lib import buttons
from gui import icon from gui import icon
@ -12,6 +19,7 @@ from util import machineCom
from util import profile from util import profile
from util import gcodeInterpreter from util import gcodeInterpreter
from util import power from util import power
from util.resources import getPathForImage
printWindowMonitorHandle = None printWindowMonitorHandle = None
@ -21,6 +29,7 @@ def printFile(filename):
printWindowMonitorHandle = printProcessMonitor() printWindowMonitorHandle = printProcessMonitor()
printWindowMonitorHandle.loadFile(filename) printWindowMonitorHandle.loadFile(filename)
def startPrintInterface(filename): def startPrintInterface(filename):
#startPrintInterface is called from the main script when we want the printer interface to run in a seperate process. #startPrintInterface is called from the main script when we want the printer interface to run in a seperate process.
# It needs to run in a seperate process, as any running python code blocks the GCode sender pyton code (http://wiki.python.org/moin/GlobalInterpreterLock). # It needs to run in a seperate process, as any running python code blocks the GCode sender pyton code (http://wiki.python.org/moin/GlobalInterpreterLock).
@ -34,6 +43,7 @@ def startPrintInterface(filename):
t.start() t.start()
app.MainLoop() app.MainLoop()
class printProcessMonitor(): class printProcessMonitor():
def __init__(self): def __init__(self):
self.handle = None self.handle = None
@ -45,7 +55,8 @@ class printProcessMonitor():
if platform.machine() == 'i386': if platform.machine() == 'i386':
cmdList.insert(0, 'arch') cmdList.insert(0, 'arch')
cmdList.insert(1, '-i386') cmdList.insert(1, '-i386')
self.handle = subprocess.Popen(cmdList, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.handle = subprocess.Popen(cmdList, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
self.thread = threading.Thread(target=self.Monitor) self.thread = threading.Thread(target=self.Monitor)
self.thread.start() self.thread.start()
else: else:
@ -61,9 +72,10 @@ class printProcessMonitor():
self.handle = None self.handle = None
self.thread = None self.thread = None
class PrintCommandButton(buttons.GenBitmapButton): class PrintCommandButton(buttons.GenBitmapButton):
def __init__(self, parent, commandList, bitmapFilename, size=(20, 20)): def __init__(self, parent, commandList, bitmapFilename, size=(20, 20)):
self.bitmap = toolbarUtil.getBitmapImage(bitmapFilename) self.bitmap = wx.Bitmap(getPathForImage(bitmapFilename))
super(PrintCommandButton, self).__init__(parent.directControlPanel, -1, self.bitmap, size=size) super(PrintCommandButton, self).__init__(parent.directControlPanel, -1, self.bitmap, size=size)
self.commandList = commandList self.commandList = commandList
@ -81,8 +93,10 @@ class PrintCommandButton(buttons.GenBitmapButton):
self.parent.machineCom.sendCommand(cmd) self.parent.machineCom.sendCommand(cmd)
e.Skip() e.Skip()
class printWindow(wx.Frame): class printWindow(wx.Frame):
"Main user interface window" "Main user interface window"
def __init__(self): def __init__(self):
super(printWindow, self).__init__(None, -1, title='Printing') super(printWindow, self).__init__(None, -1, title='Printing')
self.machineCom = None self.machineCom = None
@ -131,7 +145,8 @@ class printWindow(wx.Frame):
self.OnPowerWarningChange(None) self.OnPowerWarningChange(None)
self.powerWarningTimer.Start(10000) self.powerWarningTimer.Start(10000)
self.statsText = wx.StaticText(self.panel, -1, "Filament: ####.##m #.##g\nEstimated print time: #####:##\nMachine state:\nDetecting baudrateXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX") self.statsText = wx.StaticText(self.panel, -1,
"Filament: ####.##m #.##g\nEstimated print time: #####:##\nMachine state:\nDetecting baudrateXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
boxsizer.Add(self.statsText, flag=wx.LEFT, border=5) boxsizer.Add(self.statsText, flag=wx.LEFT, border=5)
self.sizer.Add(boxsizer, pos=(0, 0), span=(7, 1), flag=wx.EXPAND) self.sizer.Add(boxsizer, pos=(0, 0), span=(7, 1), flag=wx.EXPAND)
@ -162,7 +177,8 @@ class printWindow(wx.Frame):
self.temperatureSelect = wx.SpinCtrl(self.temperaturePanel, -1, '0', size=(21 * 3, 21), style=wx.SP_ARROW_KEYS) self.temperatureSelect = wx.SpinCtrl(self.temperaturePanel, -1, '0', size=(21 * 3, 21), style=wx.SP_ARROW_KEYS)
self.temperatureSelect.SetRange(0, 400) self.temperatureSelect.SetRange(0, 400)
self.bedTemperatureLabel = wx.StaticText(self.temperaturePanel, -1, "BedTemp:") self.bedTemperatureLabel = wx.StaticText(self.temperaturePanel, -1, "BedTemp:")
self.bedTemperatureSelect = wx.SpinCtrl(self.temperaturePanel, -1, '0', size=(21*3,21), style=wx.SP_ARROW_KEYS) self.bedTemperatureSelect = wx.SpinCtrl(self.temperaturePanel, -1, '0', size=(21 * 3, 21),
style=wx.SP_ARROW_KEYS)
self.bedTemperatureSelect.SetRange(0, 400) self.bedTemperatureSelect.SetRange(0, 400)
self.bedTemperatureLabel.Show(False) self.bedTemperatureLabel.Show(False)
self.bedTemperatureSelect.Show(False) self.bedTemperatureSelect.Show(False)
@ -211,8 +227,10 @@ class printWindow(wx.Frame):
sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z-1 F200', 'G90'], 'print-move-z-1.png'), pos=(5, 8)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z-1 F200', 'G90'], 'print-move-z-1.png'), pos=(5, 8))
sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z-10 F200', 'G90'], 'print-move-z-10.png'), pos=(6, 8)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z-10 F200', 'G90'], 'print-move-z-10.png'), pos=(6, 8))
sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E2 F120'], 'extrude.png', size=(60,20)), pos=(1,10), span=(1,3), flag=wx.EXPAND) sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E2 F120'], 'extrude.png', size=(60, 20)), pos=(1, 10),
sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E-2 F120'], 'retract.png', size=(60,20)), pos=(2,10), span=(1,3), flag=wx.EXPAND) span=(1, 3), flag=wx.EXPAND)
sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E-2 F120'], 'retract.png', size=(60, 20)), pos=(2, 10),
span=(1, 3), flag=wx.EXPAND)
nb.AddPage(self.directControlPanel, 'Jog') nb.AddPage(self.directControlPanel, 'Jog')
@ -319,6 +337,7 @@ class printWindow(wx.Frame):
self.statsText.SetMinSize(self.statsText.GetSize()) self.statsText.SetMinSize(self.statsText.GetSize())
self.UpdateButtonStates() self.UpdateButtonStates()
#self.UpdateProgress() #self.UpdateProgress()
def OnCameraTimer(self, e): def OnCameraTimer(self, e):
@ -349,16 +368,20 @@ class printWindow(wx.Frame):
def UpdateButtonStates(self): def UpdateButtonStates(self):
self.connectButton.Enable(self.machineCom == None or self.machineCom.isClosedOrError()) self.connectButton.Enable(self.machineCom == None or self.machineCom.isClosedOrError())
#self.loadButton.Enable(self.machineCom == None or not (self.machineCom.isPrinting() or self.machineCom.isPaused())) #self.loadButton.Enable(self.machineCom == None or not (self.machineCom.isPrinting() or self.machineCom.isPaused()))
self.printButton.Enable(self.machineCom != None and self.machineCom.isOperational() and not (self.machineCom.isPrinting() or self.machineCom.isPaused())) self.printButton.Enable(self.machineCom != None and self.machineCom.isOperational() and not (
self.pauseButton.Enable(self.machineCom != None and (self.machineCom.isPrinting() or self.machineCom.isPaused())) self.machineCom.isPrinting() or self.machineCom.isPaused()))
self.pauseButton.Enable(
self.machineCom != None and (self.machineCom.isPrinting() or self.machineCom.isPaused()))
if self.machineCom != None and self.machineCom.isPaused(): if self.machineCom != None and self.machineCom.isPaused():
self.pauseButton.SetLabel('Resume') self.pauseButton.SetLabel('Resume')
else: else:
self.pauseButton.SetLabel('Pause') self.pauseButton.SetLabel('Pause')
self.cancelButton.Enable(self.machineCom != None and (self.machineCom.isPrinting() or self.machineCom.isPaused())) self.cancelButton.Enable(
self.machineCom != None and (self.machineCom.isPrinting() or self.machineCom.isPaused()))
self.temperatureSelect.Enable(self.machineCom != None and self.machineCom.isOperational()) self.temperatureSelect.Enable(self.machineCom != None and self.machineCom.isOperational())
self.bedTemperatureSelect.Enable(self.machineCom != None and self.machineCom.isOperational()) self.bedTemperatureSelect.Enable(self.machineCom != None and self.machineCom.isOperational())
self.directControlPanel.Enable(self.machineCom != None and self.machineCom.isOperational() and not self.machineCom.isPrinting()) self.directControlPanel.Enable(
self.machineCom != None and self.machineCom.isOperational() and not self.machineCom.isPrinting())
self.machineLogButton.Show(self.machineCom != None and self.machineCom.isClosedOrError()) self.machineLogButton.Show(self.machineCom != None and self.machineCom.isClosedOrError())
if self.cam != None: if self.cam != None:
for button in self.cam.buttons: for button in self.cam.buttons:
@ -369,11 +392,13 @@ class printWindow(wx.Frame):
if self.gcode == None: if self.gcode == None:
status += "Loading gcode...\n" status += "Loading gcode...\n"
else: else:
status += "Filament: %.2fm %.2fg\n" % (self.gcode.extrusionAmount / 1000, self.gcode.calculateWeight() * 1000) status += "Filament: %.2fm %.2fg\n" % (
self.gcode.extrusionAmount / 1000, self.gcode.calculateWeight() * 1000)
cost = self.gcode.calculateCost() cost = self.gcode.calculateCost()
if cost != False: if cost != False:
status += "Filament cost: %s\n" % (cost) status += "Filament cost: %s\n" % (cost)
status += "Estimated print time: %02d:%02d\n" % (int(self.gcode.totalMoveTimeMinute / 60), int(self.gcode.totalMoveTimeMinute % 60)) status += "Estimated print time: %02d:%02d\n" % (
int(self.gcode.totalMoveTimeMinute / 60), int(self.gcode.totalMoveTimeMinute % 60))
if self.machineCom == None or not self.machineCom.isPrinting(): if self.machineCom == None or not self.machineCom.isPrinting():
self.progress.SetValue(0) self.progress.SetValue(0)
if self.gcodeList != None: if self.gcodeList != None:
@ -381,7 +406,8 @@ class printWindow(wx.Frame):
else: else:
printTime = self.machineCom.getPrintTime() / 60 printTime = self.machineCom.getPrintTime() / 60
printTimeLeft = self.machineCom.getPrintTimeRemainingEstimate() printTimeLeft = self.machineCom.getPrintTimeRemainingEstimate()
status += 'Line: %d/%d %d%%\n' % (self.machineCom.getPrintPos(), len(self.gcodeList), self.machineCom.getPrintPos() * 100 / len(self.gcodeList)) status += 'Line: %d/%d %d%%\n' % (self.machineCom.getPrintPos(), len(self.gcodeList),
self.machineCom.getPrintPos() * 100 / len(self.gcodeList))
if self.currentZ > 0: if self.currentZ > 0:
status += 'Height: %0.1f\n' % (self.currentZ) status += 'Height: %0.1f\n' % (self.currentZ)
status += 'Print time: %02d:%02d\n' % (int(printTime / 60), int(printTime % 60)) status += 'Print time: %02d:%02d\n' % (int(printTime / 60), int(printTime % 60))
@ -583,6 +609,7 @@ class printWindow(wx.Frame):
wx.CallAfter(self.cam.takeNewImage) wx.CallAfter(self.cam.takeNewImage)
wx.CallAfter(self.camPreview.Refresh) wx.CallAfter(self.camPreview.Refresh)
class temperatureGraph(wx.Panel): class temperatureGraph(wx.Panel):
def __init__(self, parent): def __init__(self, parent):
super(temperatureGraph, self).__init__(parent) super(temperatureGraph, self).__init__(parent)
@ -698,6 +725,7 @@ class temperatureGraph(wx.Panel):
self.points.append((temp, tempSP, bedTemp, bedTempSP, time.time())) self.points.append((temp, tempSP, bedTemp, bedTempSP, time.time()))
wx.CallAfter(self.UpdateDrawing) wx.CallAfter(self.UpdateDrawing)
class LogWindow(wx.Frame): class LogWindow(wx.Frame):
def __init__(self, logText): def __init__(self, logText):
super(LogWindow, self).__init__(None, title="Machine log") super(LogWindow, self).__init__(None, title="Machine log")

View File

@ -1,18 +1,15 @@
import sys, os # coding=utf-8
#We only need the core here, which speeds up the import. As we want to show the splashscreen ASAP. from __future__ import absolute_import
import wx._core
import wx._core #We only need the core here, which speeds up the import. As we want to show the splashscreen ASAP.
from util.resources import getPathForImage
def getBitmapImage(filename):
#The frozen executable has the script files in a zip, so we need to exit another level to get to our images.
if hasattr(sys, 'frozen'):
return wx.Bitmap(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../../images", filename)))
else:
return wx.Bitmap(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../images", filename)))
class splashScreen(wx.SplashScreen): class splashScreen(wx.SplashScreen):
def __init__(self, callback): def __init__(self, callback):
self.callback = callback self.callback = callback
bitmap = getBitmapImage("splash.png") bitmap = wx.Bitmap(getPathForImage('splash.png'))
super(splashScreen, self).__init__(bitmap, wx.SPLASH_CENTRE_ON_SCREEN, 0, None) super(splashScreen, self).__init__(bitmap, wx.SPLASH_CENTRE_ON_SCREEN, 0, None)
wx.CallAfter(self.DoCallback) wx.CallAfter(self.DoCallback)
@ -20,20 +17,23 @@ class splashScreen(wx.SplashScreen):
self.callback(self) self.callback(self)
self.Destroy() self.Destroy()
def showSplash(callback): def showSplash(callback):
app = wx.App(False) app = wx.App(False)
splashScreen(callback) splashScreen(callback)
app.MainLoop() app.MainLoop()
def testCallback(splashscreen): def testCallback(splashscreen):
print "Callback!" print "Callback!"
import time import time
time.sleep(2) time.sleep(2)
print "!Callback" print "!Callback"
def main(): def main():
showSplash(testCallback) showSplash(testCallback)
if __name__ == u'__main__': if __name__ == u'__main__':
main() main()

View File

@ -1,24 +1,19 @@
# coding=utf-8
from __future__ import absolute_import
from __future__ import division from __future__ import division
import os, sys
import wx import wx
from wx.lib import buttons from wx.lib import buttons
from util import profile from util import profile
from util.resources import getPathForImage
####################################################### #######################################################
# toolbarUtil contains help classes and functions for # toolbarUtil contains help classes and functions for
# toolbar buttons. # toolbar buttons.
####################################################### #######################################################
def getBitmapImage(filename):
#The frozen executable has the script files in a zip, so we need to exit another level to get to our images.
if hasattr(sys, 'frozen'):
return wx.Bitmap(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../../images", filename)))
else:
return wx.Bitmap(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../images", filename)))
class Toolbar(wx.ToolBar): class Toolbar(wx.ToolBar):
def __init__(self, parent): def __init__(self, parent):
super(Toolbar, self).__init__(parent, -1, style=wx.TB_HORIZONTAL | wx.NO_BORDER) super(Toolbar, self).__init__(parent, -1, style=wx.TB_HORIZONTAL | wx.NO_BORDER)
@ -52,11 +47,12 @@ class Toolbar(wx.ToolBar):
sx, sy = control.GetSizeTuple() sx, sy = control.GetSizeTuple()
popup.SetPosition((x, y + sy)) popup.SetPosition((x, y + sy))
class ToggleButton(buttons.GenBitmapToggleButton): class ToggleButton(buttons.GenBitmapToggleButton):
def __init__(self, parent, profileSetting, bitmapFilenameOn, bitmapFilenameOff, def __init__(self, parent, profileSetting, bitmapFilenameOn, bitmapFilenameOff,
helpText='', id=-1, callback=None, size=(20, 20)): helpText='', id=-1, callback=None, size=(20, 20)):
self.bitmapOn = getBitmapImage(bitmapFilenameOn) self.bitmapOn = wx.Bitmap(getPathForImage(bitmapFilenameOn))
self.bitmapOff = getBitmapImage(bitmapFilenameOff) self.bitmapOff = wx.Bitmap(getPathForImage(bitmapFilenameOff))
super(ToggleButton, self).__init__(parent, id, self.bitmapOff, size=size) super(ToggleButton, self).__init__(parent, id, self.bitmapOff, size=size)
@ -117,11 +113,12 @@ class ToggleButton(buttons.GenBitmapToggleButton):
self.Refresh() self.Refresh()
event.Skip() event.Skip()
class RadioButton(buttons.GenBitmapButton): class RadioButton(buttons.GenBitmapButton):
def __init__(self, parent, group, bitmapFilenameOn, bitmapFilenameOff, def __init__(self, parent, group, bitmapFilenameOn, bitmapFilenameOff,
helpText='', id=-1, callback=None, size=(20, 20)): helpText='', id=-1, callback=None, size=(20, 20)):
self.bitmapOn = getBitmapImage(bitmapFilenameOn) self.bitmapOn = wx.Bitmap(getPathForImage(bitmapFilenameOn))
self.bitmapOff = getBitmapImage(bitmapFilenameOff) self.bitmapOff = wx.Bitmap(getPathForImage(bitmapFilenameOff))
super(RadioButton, self).__init__(parent, id, self.bitmapOff, size=size) super(RadioButton, self).__init__(parent, id, self.bitmapOff, size=size)
@ -179,10 +176,11 @@ class RadioButton(buttons.GenBitmapButton):
self.Refresh() self.Refresh()
event.Skip() event.Skip()
class NormalButton(buttons.GenBitmapButton): class NormalButton(buttons.GenBitmapButton):
def __init__(self, parent, callback, bitmapFilename, def __init__(self, parent, callback, bitmapFilename,
helpText='', id=-1, size=(20, 20)): helpText='', id=-1, size=(20, 20)):
self.bitmap = getBitmapImage(bitmapFilename) self.bitmap = wx.Bitmap(getPathForImage(bitmapFilename))
super(NormalButton, self).__init__(parent, id, self.bitmap, size=size) super(NormalButton, self).__init__(parent, id, self.bitmap, size=size)
self.helpText = helpText self.helpText = helpText

View File

@ -1,7 +1,15 @@
import os, glob, subprocess, platform # coding=utf-8
from __future__ import absolute_import
import os
import glob
import subprocess
import platform
import wx import wx
from util import profile from util import profile
from util.resources import getPathForImage
from gui import toolbarUtil from gui import toolbarUtil
try: try:
@ -26,6 +34,7 @@ def hasWebcamSupport():
return False return False
return True return True
def getFFMPEGpath(): def getFFMPEGpath():
if platform.system() == "Windows": if platform.system() == "Windows":
return os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg.exe")) return os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg.exe"))
@ -33,11 +42,12 @@ def getFFMPEGpath():
return '/usr/bin/ffmpeg' return '/usr/bin/ffmpeg'
return os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg")) return os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg"))
class webcam(object): class webcam(object):
def __init__(self): def __init__(self):
self._cam = None self._cam = None
self._overlayImage = toolbarUtil.getBitmapImage("cura-overlay.png") self._overlayImage = wx.Bitmap(getPathForImage('cura-overlay.png'))
self._overlayUltimaker = toolbarUtil.getBitmapImage("ultimaker-overlay.png") self._overlayUltimaker = wx.Bitmap(getPathForImage('ultimaker-overlay.png'))
if cv != None: if cv != None:
self._cam = highgui.cvCreateCameraCapture(-1) self._cam = highgui.cvCreateCameraCapture(-1)
elif win32vidcap != None: elif win32vidcap != None:
@ -100,13 +110,15 @@ class webcam(object):
dc.SelectObject(bitmap) dc.SelectObject(bitmap)
dc.DrawBitmap(self._overlayImage, bitmap.GetWidth() - self._overlayImage.GetWidth() - 5, 5, True) dc.DrawBitmap(self._overlayImage, bitmap.GetWidth() - self._overlayImage.GetWidth() - 5, 5, True)
if profile.getPreference('machine_type') == 'ultimaker': if profile.getPreference('machine_type') == 'ultimaker':
dc.DrawBitmap(self._overlayUltimaker, (bitmap.GetWidth() - self._overlayUltimaker.GetWidth()) / 2, bitmap.GetHeight() - self._overlayUltimaker.GetHeight() - 5, True) dc.DrawBitmap(self._overlayUltimaker, (bitmap.GetWidth() - self._overlayUltimaker.GetWidth()) / 2,
bitmap.GetHeight() - self._overlayUltimaker.GetHeight() - 5, True)
dc.SelectObject(wx.NullBitmap) dc.SelectObject(wx.NullBitmap)
self._bitmap = bitmap self._bitmap = bitmap
if self._doTimelaps: if self._doTimelaps:
filename = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap", "__tmp_snap_%04d.jpg" % (self._snapshotCount))) filename = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap",
"__tmp_snap_%04d.jpg" % (self._snapshotCount)))
self._snapshotCount += 1 self._snapshotCount += 1
bitmap.SaveFile(filename, wx.BITMAP_TYPE_JPEG) bitmap.SaveFile(filename, wx.BITMAP_TYPE_JPEG)
@ -127,8 +139,11 @@ class webcam(object):
def endTimelaps(self): def endTimelaps(self):
if self._doTimelaps: if self._doTimelaps:
ffmpeg = getFFMPEGpath() ffmpeg = getFFMPEGpath()
basePath = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap", "__tmp_snap_%04d.jpg")) basePath = os.path.normpath(
subprocess.call([ffmpeg, '-r', '12.5', '-i', basePath, '-vcodec', 'mpeg2video', '-pix_fmt', 'yuv420p', '-r', '25', '-y', '-b:v', '1500k', '-f', 'vob', self._timelapsFilename]) os.path.join(os.path.split(__file__)[0], "../__tmp_snap", "__tmp_snap_%04d.jpg"))
subprocess.call(
[ffmpeg, '-r', '12.5', '-i', basePath, '-vcodec', 'mpeg2video', '-pix_fmt', 'yuv420p', '-r', '25', '-y',
'-b:v', '1500k', '-f', 'vob', self._timelapsFilename])
self._doTimelaps = False self._doTimelaps = False
def _cleanTempDir(self): def _cleanTempDir(self):

36
Cura/util/resources.py Normal file
View File

@ -0,0 +1,36 @@
# coding=utf-8
from __future__ import absolute_import
import os
import sys
__all__ = ['getPathForResource', 'getPathForImage', 'getPathForMesh']
if sys.platform.startswith('darwin'):
if hasattr(sys, 'frozen'):
from Foundation import *
imagesPath = os.path.join(NSBundle.mainBundle().resourcePath(), 'images')
meshesPath = os.path.join(NSBundle.mainBundle().resourcePath(), 'images')
else:
imagesPath = os.path.join(os.path.dirname(__file__), "../images")
meshesPath = os.path.join(os.path.dirname(__file__), "../images")
else:
if hasattr(sys, 'frozen'):
imagesPath = os.path.join(os.path.dirname(__file__), "../../images")
meshesPath = os.path.join(os.path.dirname(__file__), "../../images")
else:
imagesPath = os.path.join(os.path.dirname(__file__), "../images")
meshesPath = os.path.join(os.path.dirname(__file__), "../images")
def getPathForResource(dir, resource_name):
assert os.path.isdir(dir), "{p} is not a directory".format(p=dir)
path = os.path.normpath(os.path.join(dir, resource_name))
assert os.path.isfile(path), "{p} is not a file.".format(p=path)
return path
def getPathForImage(name):
return getPathForResource(imagesPath, name)
def getPathForMesh(name):
return getPathForResource(meshesPath, name)