Fix resources, imports and indentations.
parent
132e6381ea
commit
377ea03c15
30
Cura/cura.py
30
Cura/cura.py
|
@ -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
|
||||
import __init__
|
||||
|
||||
import sys
|
||||
import platform
|
||||
from optparse import OptionParser
|
||||
|
||||
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>
|
||||
Xsainnz <http://forums.reprap.org/profile.php?12,563>
|
||||
Zach Hoeken <http://blog.zachhoeken.com/>
|
||||
Ilya Kulakov (kulakov.ilya@gmail.com)
|
||||
|
||||
Organizations:
|
||||
Ultimaker <http://www.ultimaker.com>
|
||||
|
@ -45,12 +43,18 @@ __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agp
|
|||
|
||||
def main():
|
||||
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("-P", "--project", action="store_true", dest="openprojectplanner", help="Open the project planner")
|
||||
parser.add_option("-F", "--flat", action="store_true", dest="openflatslicer", 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")
|
||||
parser.add_option("-i", "--ini", action="store", type="string", dest="profileini",
|
||||
help="Load settings from a profile ini file")
|
||||
parser.add_option("-P", "--project", action="store_true", dest="openprojectplanner",
|
||||
help="Open the project planner")
|
||||
parser.add_option("-F", "--flat", action="store_true", dest="openflatslicer",
|
||||
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()
|
||||
if options.profile != None:
|
||||
profile.loadGlobalProfileFromString(options.profile)
|
||||
|
@ -58,30 +62,36 @@ def main():
|
|||
profile.loadGlobalProfile(options.profileini)
|
||||
if options.openprojectplanner != None:
|
||||
from gui import projectPlanner
|
||||
|
||||
projectPlanner.main()
|
||||
return
|
||||
if options.openflatslicer != None:
|
||||
from gui import flatSlicerWindow
|
||||
|
||||
flatSlicerWindow.main()
|
||||
return
|
||||
if options.printfile != None:
|
||||
from gui import printWindow
|
||||
|
||||
printWindow.startPrintInterface(options.printfile)
|
||||
return
|
||||
|
||||
if options.slice != None:
|
||||
from util import sliceRun
|
||||
|
||||
sliceRun.runSlice(args)
|
||||
else:
|
||||
if len(args) > 0:
|
||||
profile.putPreference('lastFile', ';'.join(args))
|
||||
from gui import splashScreen
|
||||
|
||||
splashScreen.showSplash(mainWindowRunCallback)
|
||||
|
||||
|
||||
def mainWindowRunCallback(splash):
|
||||
from gui import mainWindow
|
||||
|
||||
mainWindow.main(splash)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
# coding=utf-8
|
||||
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
|
||||
|
||||
from gui import firmwareInstall
|
||||
from gui import toolbarUtil
|
||||
from util import machineCom
|
||||
from util import profile
|
||||
from util.resources import getPathForImage
|
||||
|
||||
class InfoBox(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
|
@ -17,10 +22,15 @@ class InfoBox(wx.Panel):
|
|||
self.sizer = wx.GridBagSizer(5, 5)
|
||||
self.SetSizer(self.sizer)
|
||||
|
||||
self.attentionBitmap = toolbarUtil.getBitmapImage('attention.png')
|
||||
self.errorBitmap = toolbarUtil.getBitmapImage('error.png')
|
||||
self.readyBitmap = toolbarUtil.getBitmapImage('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.attentionBitmap = wx.Bitmap(getPathForImage('attention.png'))
|
||||
self.errorBitmap = wx.Bitmap(getPathForImage('error.png'))
|
||||
self.readyBitmap = wx.Bitmap(getPathForImage('ready.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.text = wx.StaticText(self, -1, '')
|
||||
|
@ -73,6 +83,7 @@ class InfoBox(wx.Panel):
|
|||
self.busyState = None
|
||||
self.bitmap.SetBitmap(self.attentionBitmap)
|
||||
|
||||
|
||||
class InfoPage(wx.wizard.WizardPageSimple):
|
||||
def __init__(self, parent, title):
|
||||
wx.wizard.WizardPageSimple.__init__(self, parent)
|
||||
|
@ -179,6 +190,7 @@ class InfoPage(wx.wizard.WizardPageSimple):
|
|||
def StoreData(self):
|
||||
pass
|
||||
|
||||
|
||||
class FirstInfoPage(InfoPage):
|
||||
def __init__(self, parent):
|
||||
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('* Upgrade your firmware')
|
||||
self.AddText('* Check if your machine is working safely')
|
||||
|
||||
#self.AddText('* Calibrate your machine')
|
||||
#self.AddText('* Do your first print')
|
||||
|
||||
|
||||
class RepRapInfoPage(InfoPage):
|
||||
def __init__(self, parent):
|
||||
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.AddSeperator()
|
||||
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.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
|
||||
|
||||
|
||||
class MachineSelectPage(InfoPage):
|
||||
def __init__(self, parent):
|
||||
super(MachineSelectPage, self).__init__(parent, "Select your machine")
|
||||
|
@ -252,14 +268,18 @@ class MachineSelectPage(InfoPage):
|
|||
profile.putProfileSetting('machine_center_y', '40')
|
||||
profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)
|
||||
|
||||
|
||||
class FirmwareUpgradePage(InfoPage):
|
||||
def __init__(self, parent):
|
||||
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.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.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.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)
|
||||
skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick)
|
||||
|
@ -283,22 +303,24 @@ class FirmwareUpgradePage(InfoPage):
|
|||
def OnUrlClick(self, e):
|
||||
webbrowser.open('http://daid.mine.nu/~daid/marlin_build/')
|
||||
|
||||
|
||||
class UltimakerCheckupPage(InfoPage):
|
||||
def __init__(self, parent):
|
||||
super(UltimakerCheckupPage, self).__init__(parent, "Ultimaker Checkup")
|
||||
|
||||
self.checkBitmap = toolbarUtil.getBitmapImage('checkmark.png')
|
||||
self.crossBitmap = toolbarUtil.getBitmapImage('cross.png')
|
||||
self.unknownBitmap = toolbarUtil.getBitmapImage('question.png')
|
||||
self.endStopNoneBitmap = toolbarUtil.getBitmapImage('endstop_none.png')
|
||||
self.endStopXMinBitmap = toolbarUtil.getBitmapImage('endstop_xmin.png')
|
||||
self.endStopXMaxBitmap = toolbarUtil.getBitmapImage('endstop_xmax.png')
|
||||
self.endStopYMinBitmap = toolbarUtil.getBitmapImage('endstop_ymin.png')
|
||||
self.endStopYMaxBitmap = toolbarUtil.getBitmapImage('endstop_ymax.png')
|
||||
self.endStopZMinBitmap = toolbarUtil.getBitmapImage('endstop_zmin.png')
|
||||
self.endStopZMaxBitmap = toolbarUtil.getBitmapImage('endstop_zmax.png')
|
||||
self.checkBitmap = wx.Bitmap(getPathForImage('checkmark.png'))
|
||||
self.crossBitmap = wx.Bitmap(getPathForImage('cross.png'))
|
||||
self.unknownBitmap = wx.Bitmap(getPathForImage('question.png'))
|
||||
self.endStopNoneBitmap = wx.Bitmap(getPathForImage('endstop_none.png'))
|
||||
self.endStopXMinBitmap = wx.Bitmap(getPathForImage('endstop_xmin.png'))
|
||||
self.endStopXMaxBitmap = wx.Bitmap(getPathForImage('endstop_xmax.png'))
|
||||
self.endStopYMinBitmap = wx.Bitmap(getPathForImage('endstop_ymin.png'))
|
||||
self.endStopYMaxBitmap = wx.Bitmap(getPathForImage('endstop_ymax.png'))
|
||||
self.endStopZMinBitmap = wx.Bitmap(getPathForImage('endstop_zmin.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.Bind(wx.EVT_BUTTON, self.OnCheckClick)
|
||||
b2.Bind(wx.EVT_BUTTON, self.OnSkipClick)
|
||||
|
@ -469,6 +491,7 @@ class UltimakerCheckupPage(InfoPage):
|
|||
def mcZChange(self, newZ):
|
||||
pass
|
||||
|
||||
|
||||
class UltimakerCalibrationPage(InfoPage):
|
||||
def __init__(self, parent):
|
||||
super(UltimakerCalibrationPage, self).__init__(parent, "Ultimaker Calibration")
|
||||
|
@ -484,12 +507,14 @@ class UltimakerCalibrationPage(InfoPage):
|
|||
self.AddSeperator()
|
||||
self.AddText("First we need the diameter of your filament:")
|
||||
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.")
|
||||
|
||||
def StoreData(self):
|
||||
profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue())
|
||||
|
||||
|
||||
class UltimakerCalibrateStepsPerEPage(InfoPage):
|
||||
def __init__(self, parent):
|
||||
super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, "Ultimaker Calibration")
|
||||
|
@ -508,7 +533,8 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
|
|||
self.stepsPerEInput = self.AddTextCtrl(profile.getPreference('steps_per_e'))
|
||||
self.AddText("You can repeat these steps to get better calibration.")
|
||||
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.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick)
|
||||
|
@ -531,7 +557,9 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
|
|||
currentEValue = float(self.stepsPerEInput.GetValue())
|
||||
self.comm = machineCom.MachineCom()
|
||||
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.extrudeButton.Enable(True)
|
||||
return
|
||||
|
@ -561,7 +589,9 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
|
|||
self.extrudeButton.Enable(False)
|
||||
self.comm = machineCom.MachineCom()
|
||||
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.extrudeButton.Enable(True)
|
||||
return
|
||||
|
@ -577,7 +607,9 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
|
|||
time.sleep(3)
|
||||
|
||||
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')
|
||||
time.sleep(1)
|
||||
self.comm.close()
|
||||
|
@ -596,6 +628,7 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
|
|||
def StoreData(self):
|
||||
profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue())
|
||||
|
||||
|
||||
class configWizard(wx.wizard.Wizard):
|
||||
def __init__(self):
|
||||
super(configWizard, self).__init__(None, -1, "Configuration Wizard")
|
||||
|
|
|
@ -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 util3d
|
||||
from util import profile
|
||||
from util.resources import getPathForMesh
|
||||
|
||||
try:
|
||||
import OpenGL
|
||||
|
||||
OpenGL.ERROR_CHECKING = False
|
||||
from OpenGL.GLU import *
|
||||
from OpenGL.GL import *
|
||||
|
||||
hasOpenGLlibs = True
|
||||
except:
|
||||
print "Failed to find PyOpenGL: http://pyopengl.sourceforge.net/"
|
||||
|
@ -61,7 +67,7 @@ def DrawMachine(machineSize):
|
|||
|
||||
global platformMesh
|
||||
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)
|
||||
|
||||
DrawMesh(platformMesh)
|
||||
|
@ -248,6 +254,7 @@ def DrawMachine(machineSize):
|
|||
glPopMatrix()
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
|
||||
|
||||
def ResetMatrixRotationAndScale():
|
||||
matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
|
||||
noZ = False
|
||||
|
@ -278,6 +285,7 @@ def ResetMatrixRotationAndScale():
|
|||
glLoadMatrixf(matrix)
|
||||
return noZ
|
||||
|
||||
|
||||
def DrawBox(vMin, vMax):
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(vMin[0], vMin[1], vMin[2])
|
||||
|
@ -303,6 +311,7 @@ def DrawBox(vMin, vMax):
|
|||
glVertex3f(vMin[0], vMax[1], vMax[2])
|
||||
glEnd()
|
||||
|
||||
|
||||
def DrawMeshOutline(mesh):
|
||||
glEnable(GL_CULL_FACE)
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
@ -317,6 +326,7 @@ def DrawMeshOutline(mesh):
|
|||
|
||||
glDisableClientState(GL_VERTEX_ARRAY)
|
||||
|
||||
|
||||
def DrawMesh(mesh):
|
||||
glEnable(GL_CULL_FACE)
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
@ -346,6 +356,7 @@ def DrawMesh(mesh):
|
|||
glDisableClientState(GL_VERTEX_ARRAY)
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
|
||||
def DrawGCodeLayer(layer):
|
||||
filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
|
||||
filamentArea = math.pi * filamentRadius * filamentRadius
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
# coding=utf-8
|
||||
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 gui import icon
|
||||
|
@ -12,6 +19,7 @@ from util import machineCom
|
|||
from util import profile
|
||||
from util import gcodeInterpreter
|
||||
from util import power
|
||||
from util.resources import getPathForImage
|
||||
|
||||
printWindowMonitorHandle = None
|
||||
|
||||
|
@ -21,6 +29,7 @@ def printFile(filename):
|
|||
printWindowMonitorHandle = printProcessMonitor()
|
||||
printWindowMonitorHandle.loadFile(filename)
|
||||
|
||||
|
||||
def startPrintInterface(filename):
|
||||
#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).
|
||||
|
@ -34,6 +43,7 @@ def startPrintInterface(filename):
|
|||
t.start()
|
||||
app.MainLoop()
|
||||
|
||||
|
||||
class printProcessMonitor():
|
||||
def __init__(self):
|
||||
self.handle = None
|
||||
|
@ -45,7 +55,8 @@ class printProcessMonitor():
|
|||
if platform.machine() == 'i386':
|
||||
cmdList.insert(0, 'arch')
|
||||
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.start()
|
||||
else:
|
||||
|
@ -61,9 +72,10 @@ class printProcessMonitor():
|
|||
self.handle = None
|
||||
self.thread = None
|
||||
|
||||
|
||||
class PrintCommandButton(buttons.GenBitmapButton):
|
||||
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)
|
||||
|
||||
self.commandList = commandList
|
||||
|
@ -81,8 +93,10 @@ class PrintCommandButton(buttons.GenBitmapButton):
|
|||
self.parent.machineCom.sendCommand(cmd)
|
||||
e.Skip()
|
||||
|
||||
|
||||
class printWindow(wx.Frame):
|
||||
"Main user interface window"
|
||||
|
||||
def __init__(self):
|
||||
super(printWindow, self).__init__(None, -1, title='Printing')
|
||||
self.machineCom = None
|
||||
|
@ -131,7 +145,8 @@ class printWindow(wx.Frame):
|
|||
self.OnPowerWarningChange(None)
|
||||
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)
|
||||
|
||||
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.SetRange(0, 400)
|
||||
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.bedTemperatureLabel.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-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 E-2 F120'], 'retract.png', size=(60,20)), pos=(2,10), span=(1,3), flag=wx.EXPAND)
|
||||
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 E-2 F120'], 'retract.png', size=(60, 20)), pos=(2, 10),
|
||||
span=(1, 3), flag=wx.EXPAND)
|
||||
|
||||
nb.AddPage(self.directControlPanel, 'Jog')
|
||||
|
||||
|
@ -319,6 +337,7 @@ class printWindow(wx.Frame):
|
|||
self.statsText.SetMinSize(self.statsText.GetSize())
|
||||
|
||||
self.UpdateButtonStates()
|
||||
|
||||
#self.UpdateProgress()
|
||||
|
||||
def OnCameraTimer(self, e):
|
||||
|
@ -349,16 +368,20 @@ class printWindow(wx.Frame):
|
|||
def UpdateButtonStates(self):
|
||||
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.printButton.Enable(self.machineCom != None and self.machineCom.isOperational() and not (self.machineCom.isPrinting() or self.machineCom.isPaused()))
|
||||
self.pauseButton.Enable(self.machineCom != None and (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.pauseButton.Enable(
|
||||
self.machineCom != None and (self.machineCom.isPrinting() or self.machineCom.isPaused()))
|
||||
if self.machineCom != None and self.machineCom.isPaused():
|
||||
self.pauseButton.SetLabel('Resume')
|
||||
else:
|
||||
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.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())
|
||||
if self.cam != None:
|
||||
for button in self.cam.buttons:
|
||||
|
@ -369,11 +392,13 @@ class printWindow(wx.Frame):
|
|||
if self.gcode == None:
|
||||
status += "Loading gcode...\n"
|
||||
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()
|
||||
if cost != False:
|
||||
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():
|
||||
self.progress.SetValue(0)
|
||||
if self.gcodeList != None:
|
||||
|
@ -381,7 +406,8 @@ class printWindow(wx.Frame):
|
|||
else:
|
||||
printTime = self.machineCom.getPrintTime() / 60
|
||||
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:
|
||||
status += 'Height: %0.1f\n' % (self.currentZ)
|
||||
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.camPreview.Refresh)
|
||||
|
||||
|
||||
class temperatureGraph(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
super(temperatureGraph, self).__init__(parent)
|
||||
|
@ -698,6 +725,7 @@ class temperatureGraph(wx.Panel):
|
|||
self.points.append((temp, tempSP, bedTemp, bedTempSP, time.time()))
|
||||
wx.CallAfter(self.UpdateDrawing)
|
||||
|
||||
|
||||
class LogWindow(wx.Frame):
|
||||
def __init__(self, logText):
|
||||
super(LogWindow, self).__init__(None, title="Machine log")
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
import sys, os
|
||||
#We only need the core here, which speeds up the import. As we want to show the splashscreen ASAP.
|
||||
import wx._core
|
||||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
|
||||
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):
|
||||
def __init__(self, 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)
|
||||
wx.CallAfter(self.DoCallback)
|
||||
|
||||
|
@ -20,20 +17,23 @@ class splashScreen(wx.SplashScreen):
|
|||
self.callback(self)
|
||||
self.Destroy()
|
||||
|
||||
|
||||
def showSplash(callback):
|
||||
app = wx.App(False)
|
||||
splashScreen(callback)
|
||||
app.MainLoop()
|
||||
|
||||
|
||||
def testCallback(splashscreen):
|
||||
print "Callback!"
|
||||
import time
|
||||
|
||||
time.sleep(2)
|
||||
print "!Callback"
|
||||
|
||||
|
||||
def main():
|
||||
showSplash(testCallback)
|
||||
|
||||
if __name__ == u'__main__':
|
||||
main()
|
||||
|
||||
|
|
|
@ -1,24 +1,19 @@
|
|||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
|
||||
import os, sys
|
||||
|
||||
import wx
|
||||
from wx.lib import buttons
|
||||
|
||||
from util import profile
|
||||
from util.resources import getPathForImage
|
||||
|
||||
|
||||
#######################################################
|
||||
# toolbarUtil contains help classes and functions for
|
||||
# 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):
|
||||
def __init__(self, parent):
|
||||
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()
|
||||
popup.SetPosition((x, y + sy))
|
||||
|
||||
|
||||
class ToggleButton(buttons.GenBitmapToggleButton):
|
||||
def __init__(self, parent, profileSetting, bitmapFilenameOn, bitmapFilenameOff,
|
||||
helpText='', id=-1, callback=None, size=(20, 20)):
|
||||
self.bitmapOn = getBitmapImage(bitmapFilenameOn)
|
||||
self.bitmapOff = getBitmapImage(bitmapFilenameOff)
|
||||
self.bitmapOn = wx.Bitmap(getPathForImage(bitmapFilenameOn))
|
||||
self.bitmapOff = wx.Bitmap(getPathForImage(bitmapFilenameOff))
|
||||
|
||||
super(ToggleButton, self).__init__(parent, id, self.bitmapOff, size=size)
|
||||
|
||||
|
@ -117,11 +113,12 @@ class ToggleButton(buttons.GenBitmapToggleButton):
|
|||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
|
||||
class RadioButton(buttons.GenBitmapButton):
|
||||
def __init__(self, parent, group, bitmapFilenameOn, bitmapFilenameOff,
|
||||
helpText='', id=-1, callback=None, size=(20, 20)):
|
||||
self.bitmapOn = getBitmapImage(bitmapFilenameOn)
|
||||
self.bitmapOff = getBitmapImage(bitmapFilenameOff)
|
||||
self.bitmapOn = wx.Bitmap(getPathForImage(bitmapFilenameOn))
|
||||
self.bitmapOff = wx.Bitmap(getPathForImage(bitmapFilenameOff))
|
||||
|
||||
super(RadioButton, self).__init__(parent, id, self.bitmapOff, size=size)
|
||||
|
||||
|
@ -179,10 +176,11 @@ class RadioButton(buttons.GenBitmapButton):
|
|||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
|
||||
class NormalButton(buttons.GenBitmapButton):
|
||||
def __init__(self, parent, callback, bitmapFilename,
|
||||
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)
|
||||
|
||||
self.helpText = helpText
|
||||
|
|
|
@ -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
|
||||
|
||||
from util import profile
|
||||
from util.resources import getPathForImage
|
||||
from gui import toolbarUtil
|
||||
|
||||
try:
|
||||
|
@ -26,6 +34,7 @@ def hasWebcamSupport():
|
|||
return False
|
||||
return True
|
||||
|
||||
|
||||
def getFFMPEGpath():
|
||||
if platform.system() == "Windows":
|
||||
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 os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg"))
|
||||
|
||||
|
||||
class webcam(object):
|
||||
def __init__(self):
|
||||
self._cam = None
|
||||
self._overlayImage = toolbarUtil.getBitmapImage("cura-overlay.png")
|
||||
self._overlayUltimaker = toolbarUtil.getBitmapImage("ultimaker-overlay.png")
|
||||
self._overlayImage = wx.Bitmap(getPathForImage('cura-overlay.png'))
|
||||
self._overlayUltimaker = wx.Bitmap(getPathForImage('ultimaker-overlay.png'))
|
||||
if cv != None:
|
||||
self._cam = highgui.cvCreateCameraCapture(-1)
|
||||
elif win32vidcap != None:
|
||||
|
@ -100,13 +110,15 @@ class webcam(object):
|
|||
dc.SelectObject(bitmap)
|
||||
dc.DrawBitmap(self._overlayImage, bitmap.GetWidth() - self._overlayImage.GetWidth() - 5, 5, True)
|
||||
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)
|
||||
|
||||
self._bitmap = bitmap
|
||||
|
||||
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
|
||||
bitmap.SaveFile(filename, wx.BITMAP_TYPE_JPEG)
|
||||
|
||||
|
@ -127,8 +139,11 @@ class webcam(object):
|
|||
def endTimelaps(self):
|
||||
if self._doTimelaps:
|
||||
ffmpeg = getFFMPEGpath()
|
||||
basePath = os.path.normpath(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])
|
||||
basePath = os.path.normpath(
|
||||
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
|
||||
|
||||
def _cleanTempDir(self):
|
||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue