--- /dev/null
+\r
+avrChipDB = {\r
+ 'ATMega2560': {\r
+ 'signature': [0x1E, 0x98, 0x01],\r
+ 'pageSize': 128,\r
+ 'pageCount': 1024,\r
+ },\r
+}\r
+\r
+def getChipFromDB(sig):\r
+ for chip in avrChipDB.values():\r
+ if chip['signature'] == sig:\r
+ return chip\r
+ return False\r
--- /dev/null
+import io\r
+\r
+def readHex(filename):\r
+ data = []\r
+ extraAddr = 0\r
+ f = io.open(filename, "r")\r
+ for line in f:\r
+ line = line.strip()\r
+ if line[0] != ':':\r
+ raise Exception("Hex file has a line not starting with ':'")\r
+ recLen = int(line[1:3], 16)\r
+ addr = int(line[3:7], 16) + extraAddr\r
+ recType = int(line[7:9], 16)\r
+ if len(line) != recLen * 2 + 11:\r
+ raise Exception("Error in hex file: " + line)\r
+ checkSum = 0\r
+ for i in xrange(0, recLen + 5):\r
+ checkSum += int(line[i*2+1:i*2+3], 16)\r
+ checkSum &= 0xFF\r
+ if checkSum != 0:\r
+ raise Exception("Checksum error in hex file: " + line)\r
+ \r
+ if recType == 0:#Data record\r
+ while len(data) < addr + recLen:\r
+ data.append(0)\r
+ for i in xrange(0, recLen):\r
+ data[addr + i] = int(line[i*2+9:i*2+11], 16)\r
+ elif recType == 1: #End Of File record\r
+ pass\r
+ elif recType == 2: #Extended Segment Address Record\r
+ extraAddr = int(line[9:13], 16) * 16\r
+ else:\r
+ print recType, recLen, addr, checkSum, line\r
+ f.close()\r
+ return data
\ No newline at end of file
--- /dev/null
+import os, struct, sys, time\r
+\r
+from serial import Serial\r
+\r
+import chipDB\r
+\r
+class IspBase():\r
+ def programChip(self, flashData):\r
+ self.curExtAddr = -1\r
+ self.chip = chipDB.getChipFromDB(self.getSignature())\r
+ if self.chip == False:\r
+ print "Chip with signature: " + str(self.getSignature()) + "not found"\r
+ return False\r
+ self.chipErase()\r
+ \r
+ print "Flashing %i bytes" % len(flashData)\r
+ self.writeFlash(flashData)\r
+ print "Verifying %i bytes" % len(flashData)\r
+ self.verifyFlash(flashData)\r
+ \r
+ return True\r
+\r
+ #low level ISP commands\r
+ def getSignature(self):\r
+ sig = []\r
+ sig.append(self.sendISP([0x30, 0x00, 0x00, 0x00])[3])\r
+ sig.append(self.sendISP([0x30, 0x00, 0x01, 0x00])[3])\r
+ sig.append(self.sendISP([0x30, 0x00, 0x02, 0x00])[3])\r
+ return sig\r
+ \r
+ def chipErase(self):\r
+ self.sendISP([0xAC, 0x80, 0x00, 0x00])\r
+\r
+class IspError():\r
+ def __init__(self, value):\r
+ self.value = value\r
+ def __str__(self):\r
+ return repr(self.value)\r
--- /dev/null
+import os, struct, sys, time\r
+\r
+from serial import Serial\r
+\r
+import ispBase, intelHex\r
+\r
+class Stk500v2(ispBase.IspBase):\r
+ def __init__(self):\r
+ self.serial = None\r
+ self.seq = 1\r
+ self.lastAddr = -1\r
+ \r
+ def connect(self, port = 'COM3', speed = 115200):\r
+ if self.serial != None:\r
+ self.serial.close()\r
+ self.serial = Serial(port, speed, timeout=5)\r
+ self.seq = 1\r
+ \r
+ #Reset the controller\r
+ self.serial.setDTR(1)\r
+ self.serial.setDTR(0)\r
+ time.sleep(0.2)\r
+ \r
+ self.sendMessage([1])\r
+ if self.sendMessage([0x10, 0xc8, 0x64, 0x19, 0x20, 0x00, 0x53, 0x03, 0xac, 0x53, 0x00, 0x00]) != [0x10, 0x00]:\r
+ raise ispBase.IspError("Failed to enter programming mode")\r
+ \r
+ def sendISP(self, data):\r
+ recv = self.sendMessage([0x1D, 4, 4, 0, data[0], data[1], data[2], data[3]])\r
+ return recv[2:6]\r
+ \r
+ def writeFlash(self, flashData):\r
+ #Set load addr to 0 (with more then 64k load)\r
+ self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])\r
+ \r
+ loadCount = (len(flashData) + 0xFF) / 0x100\r
+ for i in xrange(0, loadCount):\r
+ recv = self.sendMessage([0x13, 0x01, 0x00, 0xc1, 0x0a, 0x40, 0x4c, 0x20, 0x00, 0x00] + flashData[(i * 0x100):(i * 0x100 + 0x100)])\r
+ print "#%i#%i#" % (i + 1, loadCount)\r
+ \r
+ def verifyFlash(self, flashData):\r
+ #Set load addr to 0 (with more then 64k load)\r
+ self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])\r
+ \r
+ loadCount = (len(flashData) + 0xFF) / 0x100\r
+ for i in xrange(0, loadCount):\r
+ recv = self.sendMessage([0x14, 0x01, 0x00, 0x20])[2:0x102]\r
+ print "#%i#%i#" % (i + 1, loadCount)\r
+ for j in xrange(0, 0x100):\r
+ if i * 0x100 + j < len(flashData) and flashData[i * 0x100 + j] != recv[j]:\r
+ raise ispBase.IspError('Verify error at: 0x%x' % (i * 0x100 + j))\r
+\r
+ def sendMessage(self, data):\r
+ message = struct.pack(">BBHB", 0x1B, self.seq, len(data), 0x0E)\r
+ for c in data:\r
+ message += struct.pack(">B", c)\r
+ checksum = 0\r
+ for c in message:\r
+ checksum ^= ord(c)\r
+ message += struct.pack(">B", checksum)\r
+ self.serial.write(message)\r
+ self.serial.flush()\r
+ self.seq = (self.seq + 1) & 0xFF\r
+ return self.recvMessage()\r
+ \r
+ def recvMessage(self):\r
+ state = 'Start'\r
+ checksum = 0\r
+ while True:\r
+ s = self.serial.read()\r
+ if len(s) < 1:\r
+ raise ispBase.IspError("Timeout")\r
+ b = struct.unpack(">B", s)[0]\r
+ checksum ^= b\r
+ #print hex(b)\r
+ if state == 'Start':\r
+ if b == 0x1B:\r
+ state = 'GetSeq'\r
+ checksum = 0x1B\r
+ elif state == 'GetSeq':\r
+ state = 'MsgSize1'\r
+ elif state == 'MsgSize1':\r
+ msgSize = b << 8\r
+ state = 'MsgSize2'\r
+ elif state == 'MsgSize2':\r
+ msgSize |= b\r
+ state = 'Token'\r
+ elif state == 'Token':\r
+ if b != 0x0E:\r
+ state = 'Start'\r
+ else:\r
+ state = 'Data'\r
+ data = []\r
+ elif state == 'Data':\r
+ data.append(b)\r
+ if len(data) == msgSize:\r
+ state = 'Checksum'\r
+ elif state == 'Checksum':\r
+ if checksum != 0:\r
+ state = 'Start'\r
+ else:\r
+ return data\r
+\r
+\r
+def main():\r
+ programmer = Stk500v2()\r
+ programmer.connect()\r
+ programmer.programChip(intelHex.readHex("cfg_4f55234def059.hex"))\r
+ sys.exit(1)\r
+\r
+if __name__ == '__main__':\r
+ main()\r
return setting.value
def storedSetting(name):
- return lambda setting: getSetting(name, setting.value)
+ return lambda setting: getProfileSetting(name, setting.value)
def ifSettingAboveZero(name):
- return lambda setting: float(getSetting(name, '0.0')) > 0
+ return lambda setting: float(getProfileSetting(name, '0.0')) > 0
def ifSettingIs(name, value):
- return lambda setting: getSetting(name) == value
+ return lambda setting: getProfileSetting(name) == value
def storedPercentSetting(name):
- return lambda setting: float(getSetting(name, setting.value)) / 100
+ return lambda setting: float(getProfileSetting(name, setting.value)) / 100
def calculateEdgeWidth(setting):
- wallThickness = float(getSetting('wall_thickness'))
- nozzleSize = float(getSetting('nozzle_size'))
+ wallThickness = float(getProfileSetting('wall_thickness'))
+ nozzleSize = float(getProfileSetting('nozzle_size'))
if wallThickness < nozzleSize:
return wallThickness
return lineWidth
def calculateShells(setting):
- return calculateShellsImp(float(getSetting('wall_thickness')))
+ return calculateShellsImp(float(getProfileSetting('wall_thickness')))
def calculateShellsBase(setting):
- return calculateShellsImp(float(getSetting('wall_thickness')) + float(getSetting('extra_base_wall_thickness', '0')))
+ return calculateShellsImp(float(getProfileSetting('wall_thickness')) + float(getProfileSetting('extra_base_wall_thickness', '0')))
def calculateShellsImp(wallThickness):
- nozzleSize = float(getSetting('nozzle_size'))
+ nozzleSize = float(getProfileSetting('nozzle_size'))
if wallThickness < nozzleSize:
return 0
return lineCount - 1
def calculateSolidLayerCount(setting):
- layerHeight = float(getSetting('layer_height'))
- solidThickness = float(getSetting('solid_layer_thickness'))
+ layerHeight = float(getProfileSetting('layer_height'))
+ solidThickness = float(getProfileSetting('solid_layer_thickness'))
ret = int(math.ceil(solidThickness / layerHeight - 0.0001))
return ret
def firstLayerSpeedRatio(setting):
- bottomSpeed = float(getSetting('bottom_layer_speed'))
- speed = float(getSetting('print_speed'))
+ bottomSpeed = float(getProfileSetting('bottom_layer_speed'))
+ speed = float(getProfileSetting('print_speed'))
return bottomSpeed/speed
def getSkeinPyPyProfileInformation():
def saveGlobalProfile(filename):
globalProfileParser.write(open(filename, 'w'))
-def getSetting(name, default = "", section = 'profile'):
+def getProfileSetting(name, default = "ERR", section = 'profile'):
#Check if we have a configuration file loaded, else load the default.
if not globals().has_key('globalProfileParser'):
loadGlobalProfile(getDefaultProfilePath())
if not globalProfileParser.has_section(section):
globalProfileParser.add_section(section)
globalProfileParser.set(section, name, str(default))
- print name + " not found in profile, so using default"
+ print name + " not found in profile, so using default: " + str(default)
return default
return globalProfileParser.get(section, name)
-def putSetting(name, value, section = 'profile'):
+def putProfileSetting(name, value, section = 'profile'):
#Check if we have a configuration file loaded, else load the default.
if not globals().has_key('globalProfileParser'):
loadGlobalProfile(getDefaultProfilePath())
globalProfileParser.add_section(section)
globalProfileParser.set(section, name, str(value))
+global globalPreferenceParser
+globalPreferenceParser = None
+
+def getPreferencePath():
+ return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../preferences.ini"))
+
+def getPreference(name, default = "ERR"):
+ global globalPreferenceParser
+ if globalPreferenceParser == None:
+ globalPreferenceParser = ConfigParser.ConfigParser()
+ globalPreferenceParser.read(getPreferencePath())
+ if not globalPreferenceParser.has_option('preference', name):
+ if not globalPreferenceParser.has_section('preference'):
+ globalPreferenceParser.add_section('preference')
+ globalPreferenceParser.set('preference', name, str(default))
+ print name + " not found in preferences, so using default: " + str(default)
+ return default
+ return globalPreferenceParser.get('preference', name)
+
+def putPreference(name, value):
+ #Check if we have a configuration file loaded, else load the default.
+ global globalPreferenceParser
+ if globalPreferenceParser == None:
+ globalPreferenceParser = ConfigParser.ConfigParser()
+ globalPreferenceParser.read(getPreferencePath())
+ if not globalPreferenceParser.has_section('preference'):
+ globalPreferenceParser.add_section('preference')
+ globalPreferenceParser.set('preference', name, str(value))
+ globalPreferenceParser.write(open(getPreferencePath(), 'w'))
+
+
def getDefaultProfilePath():
return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../current_profile.ini"))
if fileName == 'start.gcode':
#For the start code, hack the temperature and the steps per E value into it. So the temperature is reached before the start code extrusion.
#We also set our steps per E here, if configured.
- eSteps = float(getSetting('steps_per_e_unit', '0'))
+ eSteps = float(getProfileSetting('steps_per_e_unit', '0'))
if eSteps > 0:
prefix += 'M92 E'+str(eSteps)+'\n'
- temp = float(getSetting('print_temperature', '0'))
+ temp = float(getProfileSetting('print_temperature', '0'))
if temp > 0:
prefix += 'M109 S'+str(temp)+'\n'
elif fileName == 'replace.csv':
def __init__(self):
super(advancedConfigWindow, self).__init__(title='Advanced config')
+ wx.EVT_CLOSE(self, self.OnClose)
+
left, right, main = self.CreateConfigPanel(self)
configBase.TitleRow(left, "Accuracy")
c = configBase.SettingRow(left, "Extra Wall thickness for bottom/top (mm)", 'extra_base_wall_thickness', '0.0', 'Additional wall thickness of the bottom and top layers.')
validators.validFloat(c, 0.0)
- validators.wallThicknessValidator(c)
configBase.TitleRow(left, "Sequence")
c = configBase.SettingRow(left, "Print order sequence", 'sequence', ['Loops > Perimeter > Infill', 'Loops > Infill > Perimeter', 'Infill > Loops > Perimeter', 'Infill > Perimeter > Loops', 'Perimeter > Infill > Loops', 'Perimeter > Loops > Infill'], 'Sequence of printing. The perimeter is the outer print edge, the loops are the insides of the walls, and the infill is the insides.');
c = configBase.SettingRow(left, "Force first layer sequence", 'force_first_layer_sequence', ['True', 'False'], 'This setting forces the order of the first layer to be \'Perimeter > Loops > Infill\'')
main.Fit()
self.Fit()
+ def OnClose(self, e):
+ self.Destroy()
import __init__
import wx, os, platform, types
-import ConfigParser
from fabmetheus_utilities import settings
def OnPopupDisplay(self, setting):
x, y = setting.ctrl.ClientToScreenXY(0, 0)
sx, sy = setting.ctrl.GetSizeTuple()
- if platform.system() == "Windows":
- #for some reason, under windows, the popup is relative to the main window...
- wx, wy = self.ClientToScreenXY(0, 0)
- x -= wx
- y -= wy
+ #if platform.system() == "Windows":
+ # for some reason, under windows, the popup is relative to the main window... in some cases. (Wierd ass bug)
+ # wx, wy = self.ClientToScreenXY(0, 0)
+ # x -= wx
+ # y -= wy
self.popup.setting = setting
self.UpdatePopup(setting)
self.popup.SetPosition((x, y+sy))
def updateProfileToControls(self):
"Update the configuration wx controls to show the new configuration settings"
for setting in self.settingControlList:
- setting.SetValue(settings.getSetting(setting.configName))
+ if setting.type == 'profile':
+ setting.SetValue(settings.getProfileSetting(setting.configName))
+ else:
+ setting.SetValue(settings.getPreference(setting.configName))
class TitleRow():
def __init__(self, panel, name):
sizer.SetRows(sizer.GetRows() + 2)
class SettingRow():
- def __init__(self, panel, label, configName, defaultValue = '', helpText = 'Help: TODO'):
+ def __init__(self, panel, label, configName, defaultValue = '', helpText = 'Help: TODO', type = 'profile'):
"Add a setting to the configuration panel"
sizer = panel.GetSizer()
x = sizer.GetRows()
self.helpText = helpText
self.configName = configName
self.panel = panel
+ self.type = type
self.label = wx.StaticText(panel, -1, label)
- if isinstance(defaultValue, types.StringTypes):
- self.ctrl = wx.TextCtrl(panel, -1, settings.getSetting(configName, defaultValue))
+ if self.type == 'profile':
+ if isinstance(defaultValue, types.StringTypes):
+ self.ctrl = wx.TextCtrl(panel, -1, settings.getProfileSetting(configName, defaultValue))
+ else:
+ self.ctrl = wx.ComboBox(panel, -1, settings.getProfileSetting(configName, defaultValue[0]), choices=defaultValue, style=wx.CB_DROPDOWN|wx.CB_READONLY)
else:
- self.ctrl = wx.ComboBox(panel, -1, settings.getSetting(configName, defaultValue[0]), choices=defaultValue, style=wx.CB_DROPDOWN|wx.CB_READONLY)
+ if isinstance(defaultValue, types.StringTypes):
+ self.ctrl = wx.TextCtrl(panel, -1, settings.getPreference(configName, defaultValue))
+ else:
+ self.ctrl = wx.ComboBox(panel, -1, settings.getPreference(configName, defaultValue[0]), choices=defaultValue, style=wx.CB_DROPDOWN|wx.CB_READONLY)
#self.helpButton = wx.Button(panel, -1, "?", style=wx.BU_EXACTFIT)
#self.helpButton.SetToolTip(wx.ToolTip(help))
sizer.SetRows(x+1)
def OnSettingTextChange(self, e):
- settings.putSetting(self.configName, self.GetValue())
+ if self.type == 'profile':
+ settings.putProfileSetting(self.configName, self.GetValue())
+ else:
+ settings.putPreference(self.configName, self.GetValue())
result = validators.SUCCESS
msgs = []
for validator in self.validators:
return validators.SUCCESS, ''
except ValueError:
return validators.SUCCESS, ''
-
-def getPreferencePath():
- return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../preferences.ini"))
-
-def getPreference(name, default):
- if not globals().has_key('globalPreferenceParser'):
- globalPreferenceParser = ConfigParser.ConfigParser()
- globalPreferenceParser.read(getPreferencePath())
- if not globalPreferenceParser.has_option('preference', name):
- if not globalPreferenceParser.has_section('preference'):
- globalPreferenceParser.add_section('preference')
- globalPreferenceParser.set('preference', name, str(default))
- print name + " not found in profile, so using default"
- return default
- return globalPreferenceParser.get('preference', name)
-
-def putPreference(name, value):
- #Check if we have a configuration file loaded, else load the default.
- if not globals().has_key('globalPreferenceParser'):
- globalPreferenceParser = ConfigParser.ConfigParser()
- globalPreferenceParser.read(getPreferencePath())
- if not globalPreferenceParser.has_section('preference'):
- globalPreferenceParser.add_section('preference')
- globalPreferenceParser.set('preference', name, str(value))
- globalPreferenceParser.write(open(getPreferencePath(), 'w'))
-
--- /dev/null
+from __future__ import absolute_import\r
+import __init__\r
+\r
+import wx, os, platform, types\r
+import wx.wizard\r
+\r
+from fabmetheus_utilities import settings\r
+\r
+class InfoPage(wx.wizard.WizardPageSimple):\r
+ def __init__(self, parent, title):\r
+ """Constructor"""\r
+ wx.wizard.WizardPageSimple.__init__(self, parent)\r
+\r
+ sizer = wx.BoxSizer(wx.VERTICAL)\r
+ self.sizer = sizer\r
+ self.SetSizer(sizer)\r
+\r
+ title = wx.StaticText(self, -1, title)\r
+ title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))\r
+ sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 5)\r
+ sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 5)\r
+ \r
+ def AddText(self,info):\r
+ self.GetSizer().Add(wx.StaticText(self, -1, info), 0, wx.LEFT|wx.RIGHT, 5)\r
+ \r
+ def AddSeperator(self):\r
+ self.GetSizer().Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 5)\r
+ \r
+ def AddHiddenSeperator(self):\r
+ self.AddText('')\r
+ \r
+ def AddRadioButton(self, label, style = 0):\r
+ radio = wx.RadioButton(self, -1, label, style=style)\r
+ self.GetSizer().Add(radio, 0, wx.EXPAND|wx.ALL, 5)\r
+ return radio\r
+ \r
+ def AllowNext(self):\r
+ return True\r
+ \r
+ def StoreData(self):\r
+ pass\r
+\r
+class FirstInfoPage(InfoPage):\r
+ def __init__(self, parent):\r
+ super(FirstInfoPage, self).__init__(parent, "First time run wizard")\r
+ self.AddText('Welcome, and thanks for trying SkeinPyPy!')\r
+ self.AddSeperator()\r
+ self.AddText('This wizard will help you with the following steps:')\r
+ self.AddText('* Configure SkeinPyPy for your machine')\r
+ self.AddText('* Upgrade your firmware')\r
+ self.AddText('* Calibrate your machine')\r
+ #self.AddText('* Do your first print')\r
+\r
+class MachineSelectPage(InfoPage):\r
+ def __init__(self, parent):\r
+ super(MachineSelectPage, self).__init__(parent, "Select your machine")\r
+ self.AddText('What kind of machine do you have:')\r
+\r
+ self.UltimakerRadio = self.AddRadioButton("Ultimaker", style=wx.RB_GROUP)\r
+ self.UltimakerRadio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimakerSelect)\r
+ self.OtherRadio = self.AddRadioButton("Other (Ex: RepRap)")\r
+ self.OtherRadio.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)\r
+ \r
+ def OnUltimakerSelect(self, e):\r
+ wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerFirmwareUpgradePage)\r
+ \r
+ def OnOtherSelect(self, e):\r
+ wx.wizard.WizardPageSimple.Chain(self, self.GetParent().configureMachineDimensions)\r
+ \r
+ def StoreData(self):\r
+ if self.UltimakerRadio.GetValue():\r
+ settings.putPreference('machine_width', '205')\r
+ settings.putPreference('machine_depth', '205')\r
+ settings.putPreference('machine_height', '200')\r
+ settings.putProfileSetting('nozzle_size', '0.4')\r
+ settings.putProfileSetting('machine_center_x', '100')\r
+ settings.putProfileSetting('machine_center_x', '100')\r
+\r
+class FirmwareUpgradePage(InfoPage):\r
+ def __init__(self, parent):\r
+ super(FirmwareUpgradePage, self).__init__(parent, "Upgrade Ultimaker Firmware")\r
+ 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.')\r
+ self.AddHiddenSeperator()\r
+ self.AddText('The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier.')\r
+ self.AddHiddenSeperator()\r
+ self.AddText('SkeinPyPy requires these new features and thus\nyour firmware will most likely need to be upgraded.\nYou will get the chance to do so now.')\r
+ self.AddHiddenSeperator()\r
+ button = wx.Button(self, -1, 'Upgrade firmware')\r
+ self.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)\r
+ self.GetSizer().Add(button, 0)\r
+ self.AddHiddenSeperator()\r
+ self.AddText('Do not upgrade to this firmware if:')\r
+ self.AddText('* You have an older machine based on ATMega1280')\r
+ self.AddText('* Using an LCD panel')\r
+ self.AddText('* Have other changes in the firmware')\r
+ \r
+ def OnUpgradeClick(self, e):\r
+ pass\r
+\r
+class configWizard(wx.wizard.Wizard):\r
+ def __init__(self):\r
+ super(configWizard, self).__init__(None, -1, "Configuration Wizard")\r
+ \r
+ self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)\r
+ self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)\r
+ \r
+ self.firstInfoPage = FirstInfoPage(self)\r
+ self.machineSelectPage = MachineSelectPage(self)\r
+ self.ultimakerFirmwareUpgradePage = FirmwareUpgradePage(self)\r
+ self.configureMachineDimensions = InfoPage(self, 'BLA2')\r
+ \r
+ wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage)\r
+ wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerFirmwareUpgradePage)\r
+ \r
+ self.FitToPage(self.firstInfoPage)\r
+ self.GetPageAreaSizer().Add(self.firstInfoPage)\r
+ \r
+ self.RunWizard(self.firstInfoPage)\r
+ self.Destroy()\r
+\r
+ def OnPageChanging(self, e):\r
+ e.GetPage().StoreData()\r
+\r
+ def OnPageChanged(self, e):\r
+ if e.GetPage().AllowNext():\r
+ self.FindWindowById(wx.ID_FORWARD).Enable() \r
+ else:\r
+ self.FindWindowById(wx.ID_FORWARD).Disable() \r
+ self.FindWindowById(wx.ID_BACKWARD).Disable() \r
import __init__
import wx, os, platform, types
-import ConfigParser
from fabmetheus_utilities import settings
from newui import sliceProgessPanel
from newui import alterationPanel
from newui import validators
+from newui import preferencesDialog
+from newui import configWizard
def main():
app = wx.App(False)
wx.EVT_CLOSE(self, self.OnClose)
+ if settings.getPreference('wizardDone', 'False') == 'False':
+ configWizard.configWizard()
+
menubar = wx.MenuBar()
fileMenu = wx.Menu()
i = fileMenu.Append(-1, 'Open Profile...', 'Open Profile...')
self.Bind(wx.EVT_MENU, self.OnLoadProfile, i)
i = fileMenu.Append(-1, 'Save Profile...', 'Save Profile...')
self.Bind(wx.EVT_MENU, self.OnSaveProfile, i)
+ fileMenu.AppendSeparator()
+ i = fileMenu.Append(-1, 'Preferences...', 'Preferences...')
+ self.Bind(wx.EVT_MENU, self.OnPreferences, i)
+ fileMenu.AppendSeparator()
i = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
self.Bind(wx.EVT_MENU, self.OnQuit, i)
menubar.Append(fileMenu, '&File')
self.SetMenuBar(menubar)
self.lastPath = ""
- self.filename = configBase.getPreference('lastFile', None)
+ self.filename = settings.getPreference('lastFile', "None")
self.progressPanelList = []
#Preview window
c = configBase.SettingRow(right, "Support type", 'support', ['None', 'Exterior only', 'Everywhere', 'Empty layers only'], 'Type of support structure build.\nNone does not do any support.\nExterior only only creates support on the outside.\nEverywhere creates support even on the insides of the model.\nOnly on empty layers is for stacked objects.')
configBase.TitleRow(right, "Filament")
- c = configBase.SettingRow(right, "Diameter (mm)", 'filament_diameter', '2.98', 'Diameter of your filament, as accurately as possible.\nIf you cannot measure this value you will have to callibrate it, a higher number means less extrusion, a smaller number generates more extrusion.')
+ c = configBase.SettingRow(right, "Diameter (mm)", 'filament_diameter', '2.89', 'Diameter of your filament, as accurately as possible.\nIf you cannot measure this value you will have to callibrate it, a higher number means less extrusion, a smaller number generates more extrusion.')
validators.validFloat(c, 1.0)
c = configBase.SettingRow(right, "Packing Density", 'filament_density', '1.00', 'Packing density of your filament. This should be 1.00 for PLA and 0.85 for ABS')
validators.validFloat(c, 0.5, 1.5)
sizer.Add(sliceButton, (1,2))
self.sizer = sizer
- if self.filename != None:
+ if self.filename != "None":
self.preview3d.loadModelFile(self.filename)
self.lastPath = os.path.split(self.filename)[0]
settings.saveGlobalProfile(profileFile)
dlg.Destroy()
+ def OnPreferences(self, e):
+ prefDialog = preferencesDialog.preferencesDialog(self)
+ prefDialog.Centre()
+ prefDialog.Show(True)
+
def OnLoadSTL(self, e):
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()
- configBase.putPreference('lastFile', self.filename)
+ settings.putPreference('lastFile', self.filename)
if not(os.path.exists(self.filename)):
return
self.lastPath = os.path.split(self.filename)[0]
self.sizer.Add(spp, (i,0), span=(1,4), flag=wx.EXPAND)
i += 1
self.sizer.Layout()
-
- def updateProfileToControls(self):
- "Update the configuration wx controls to show the new configuration settings"
- for setting in self.settingControlList:
- setting.SetValue(settings.getSetting(setting.configName))
def OnQuit(self, e):
self.Close()
--- /dev/null
+from __future__ import absolute_import\r
+import __init__\r
+\r
+import wx, os, platform, types\r
+import ConfigParser\r
+\r
+from newui import configBase\r
+\r
+class preferencesDialog(configBase.configWindowBase):\r
+ def __init__(self, parent):\r
+ super(preferencesDialog, self).__init__(title="Preferences")\r
+ \r
+ wx.EVT_CLOSE(self, self.OnClose)\r
+ \r
+ left, right, main = self.CreateConfigPanel(self)\r
+ configBase.TitleRow(left, 'Machine settings')\r
+ c = configBase.SettingRow(left, 'Steps per E', 'steps_per_e', '0', 'Amount of steps per mm filament extrusion', type = 'preference')\r
+ validators.validFloat(c, 0.1)\r
+ c = configBase.SettingRow(left, 'Machine width', 'machine_width', '205', 'Size of the machine in mm', type = 'preference')\r
+ validators.validFloat(c, 10.0)\r
+ c = configBase.SettingRow(left, 'Machine depth', 'machine_depth', '205', 'Size of the machine in mm', type = 'preference')\r
+ validators.validFloat(c, 10.0)\r
+ c = configBase.SettingRow(left, 'Machine height', 'machine_height', '200', 'Size of the machine in mm', type = 'preference')\r
+ validators.validFloat(c, 10.0)\r
+\r
+ configBase.TitleRow(left, 'Communication settings')\r
+ c = configBase.SettingRow(left, 'Serial port', 'serial_port', 'AUTO', 'Serial port to use for communication with the printer', type = 'preference')\r
+ c = configBase.SettingRow(left, 'Baudrate', 'serial_baud', '250000', 'Speed of the serial port communication\nNeeds to match your firmware settings', type = 'preference')\r
+ \r
+ self.MakeModal(True)\r
+ main.Fit()\r
+ self.Fit()\r
+\r
+ def OnClose(self, e):\r
+ self.MakeModal(False)\r
+ self.Destroy()\r
self.init = 0\r
self.triangleMesh = None\r
self.gcode = None\r
- self.machineSize = Vector3(210, 210, 200)\r
+ self.machineSize = Vector3(float(settings.getPreference('machine_width', '205')), float(settings.getPreference('machine_depth', '205')), float(settings.getPreference('machine_height', '200')))\r
self.machineCenter = Vector3(0, 0, 0)\r
\r
- tb = wx.ToolBar( self, -1 )\r
- self.ToolBar = tb\r
- tb.SetToolBitmapSize( ( 21, 21 ) )\r
+ self.toolbar = wx.ToolBar( self, -1 )\r
+ self.toolbar.SetToolBitmapSize( ( 21, 21 ) )\r
\r
- button = wx.Button(tb, -1, "3D", size=(21*2,21))\r
- tb.AddControl(button)\r
+ button = wx.Button(self.toolbar, -1, "3D", size=(21*2,21))\r
+ self.toolbar.AddControl(button)\r
self.Bind(wx.EVT_BUTTON, self.On3DClick, button)\r
\r
- button = wx.Button(tb, -1, "Top", size=(21*2,21))\r
- tb.AddControl(button)\r
+ button = wx.Button(self.toolbar, -1, "Top", size=(21*2,21))\r
+ self.toolbar.AddControl(button)\r
self.Bind(wx.EVT_BUTTON, self.OnTopClick, button)\r
\r
- self.transparentButton = wx.Button(tb, -1, "T", size=(21,21))\r
- tb.AddControl(self.transparentButton)\r
+ self.transparentButton = wx.Button(self.toolbar, -1, "T", size=(21,21))\r
+ self.toolbar.AddControl(self.transparentButton)\r
self.Bind(wx.EVT_BUTTON, self.OnTransparentClick, self.transparentButton)\r
- self.depthComplexityButton = wx.Button(tb, -1, "DC", size=(21*2,21))\r
- tb.AddControl(self.depthComplexityButton)\r
+ self.depthComplexityButton = wx.Button(self.toolbar, -1, "DC", size=(21*2,21))\r
+ self.toolbar.AddControl(self.depthComplexityButton)\r
self.Bind(wx.EVT_BUTTON, self.OnDepthComplexityClick, self.depthComplexityButton)\r
\r
- self.layerSpin = wx.SpinCtrl(tb, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS)\r
- tb.AddControl(self.layerSpin)\r
+ self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS)\r
+ self.toolbar.AddControl(self.layerSpin)\r
self.Bind(wx.EVT_SPINCTRL, self.OnLayerNrChange, self.layerSpin)\r
- self.transparentButton.Show(False)\r
- self.layerSpin.Show(False)\r
-\r
- tb.Realize()\r
-\r
+ \r
+ self.updateToolbar()\r
+ \r
sizer = wx.BoxSizer(wx.VERTICAL)\r
- sizer.Add(tb, 0, flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, border=1)\r
+ sizer.Add(self.toolbar, 0, flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, border=1)\r
sizer.Add(self.glCanvas, 1, flag=wx.EXPAND)\r
self.SetSizer(sizer)\r
\r
self.glCanvas.lineWidth = settings.calculateEdgeWidth(setting)\r
\r
def updateInfillLineWidth(self, setting):\r
- self.glCanvas.infillLineWidth = settings.getSetting('nozzle_size')\r
+ self.glCanvas.infillLineWidth = settings.getProfileSetting('nozzle_size')\r
\r
def loadModelFile(self, filename):\r
self.modelFilename = filename\r
\r
def updateToolbar(self):\r
self.transparentButton.Show(self.triangleMesh != None)\r
+ self.depthComplexityButton.Show(self.triangleMesh != None)\r
self.layerSpin.Show(self.gcode != None)\r
if self.gcode != None:\r
self.layerSpin.SetRange(1, self.gcode.layerCount)\r
+ self.toolbar.Realize()\r
\r
def OnTransparentClick(self, e):\r
self.glCanvas.renderTransparent = not self.glCanvas.renderTransparent\r
glEnd()\r
glLineWidth(2)\r
glBegin(GL_LINES)\r
- for i in xrange(0, machineSize.x, 10):\r
+ for i in xrange(0, int(machineSize.x), 10):\r
glVertex3f(i, 0, 0)\r
glVertex3f(i, machineSize.y, 0)\r
- for i in xrange(0, machineSize.y, 10):\r
+ for i in xrange(0, int(machineSize.y), 10):\r
glVertex3f(0, i, 0)\r
glVertex3f(machineSize.x, i, 0)\r
glEnd()\r
glStencilFunc(GL_EQUAL, i, 0xFF);\r
glColor(0, float(i)/10, 0)\r
glBegin(GL_QUADS)\r
- glVertex3f(-10,-10,-1)\r
- glVertex3f( 10,-10,-1)\r
- glVertex3f( 10, 10,-1)\r
- glVertex3f(-10, 10,-1)\r
+ glVertex3f(-1000,-1000,-1)\r
+ glVertex3f( 1000,-1000,-1)\r
+ glVertex3f( 1000, 1000,-1)\r
+ glVertex3f(-1000, 1000,-1)\r
glEnd()\r
for i in xrange(1, 20, 2):\r
glStencilFunc(GL_EQUAL, i, 0xFF);\r
glColor(float(i)/10, 0, 0)\r
glBegin(GL_QUADS)\r
- glVertex3f(-10,-10,-1)\r
- glVertex3f( 10,-10,-1)\r
- glVertex3f( 10, 10,-1)\r
- glVertex3f(-10, 10,-1)\r
+ glVertex3f(-1000,-1000,-1)\r
+ glVertex3f( 1000,-1000,-1)\r
+ glVertex3f( 1000, 1000,-1)\r
+ glVertex3f(-1000, 1000,-1)\r
glEnd()\r
glPopMatrix()\r
\r
def validate(self):
try:
wallThickness = float(self.setting.GetValue())
- nozzleSize = float(settings.getSetting('nozzle_size'))
+ nozzleSize = float(settings.getProfileSetting('nozzle_size'))
if wallThickness <= nozzleSize * 0.5:
return ERROR, 'Trying to print walls thinner then the half of your nozzle size, this will not produce anything usable'
if wallThickness <= nozzleSize * 0.85: