1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
12 from Cura.gui import firmwareInstall
13 from Cura.gui import printWindow
14 from Cura.util import machineCom
15 from Cura.util import profile
16 from Cura.util import gcodeGenerator
17 from Cura.util import resources
20 class InfoBox(wx.Panel):
21 def __init__(self, parent):
22 super(InfoBox, self).__init__(parent)
23 self.SetBackgroundColour('#FFFF80')
25 self.sizer = wx.GridBagSizer(5, 5)
26 self.SetSizer(self.sizer)
28 self.attentionBitmap = wx.Bitmap(resources.getPathForImage('attention.png'))
29 self.errorBitmap = wx.Bitmap(resources.getPathForImage('error.png'))
30 self.readyBitmap = wx.Bitmap(resources.getPathForImage('ready.png'))
32 wx.Bitmap(resources.getPathForImage('busy-0.png')),
33 wx.Bitmap(resources.getPathForImage('busy-1.png')),
34 wx.Bitmap(resources.getPathForImage('busy-2.png')),
35 wx.Bitmap(resources.getPathForImage('busy-3.png'))
38 self.bitmap = wx.StaticBitmap(self, -1, wx.EmptyBitmapRGBA(24, 24, red=255, green=255, blue=255, alpha=1))
39 self.text = wx.StaticText(self, -1, '')
40 self.extraInfoButton = wx.Button(self, -1, 'i', style=wx.BU_EXACTFIT)
41 self.sizer.Add(self.bitmap, pos=(0, 0), flag=wx.ALL, border=5)
42 self.sizer.Add(self.text, pos=(0, 1), flag=wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, border=5)
43 self.sizer.Add(self.extraInfoButton, pos=(0,2), flag=wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, border=5)
44 self.sizer.AddGrowableCol(1)
46 self.extraInfoButton.Show(False)
48 self.extraInfoUrl = ''
50 self.timer = wx.Timer(self)
51 self.Bind(wx.EVT_TIMER, self.doBusyUpdate, self.timer)
52 self.Bind(wx.EVT_BUTTON, self.doExtraInfo, self.extraInfoButton)
55 def SetInfo(self, info):
56 self.SetBackgroundColour('#FFFF80')
57 self.text.SetLabel(info)
58 self.extraInfoButton.Show(False)
61 def SetError(self, info, extraInfoUrl):
62 self.extraInfoUrl = extraInfoUrl
63 self.SetBackgroundColour('#FF8080')
64 self.text.SetLabel(info)
65 self.extraInfoButton.Show(True)
67 self.SetErrorIndicator()
70 def SetAttention(self, info):
71 self.SetBackgroundColour('#FFFF80')
72 self.text.SetLabel(info)
73 self.extraInfoButton.Show(False)
74 self.SetAttentionIndicator()
78 def SetBusy(self, info):
80 self.SetBusyIndicator()
82 def SetBusyIndicator(self):
84 self.bitmap.SetBitmap(self.busyBitmap[self.busyState])
86 def doExtraInfo(self, e):
87 webbrowser.open(self.extraInfoUrl)
89 def doBusyUpdate(self, e):
90 if self.busyState is None:
93 if self.busyState >= len(self.busyBitmap):
95 self.bitmap.SetBitmap(self.busyBitmap[self.busyState])
97 def SetReadyIndicator(self):
99 self.bitmap.SetBitmap(self.readyBitmap)
101 def SetErrorIndicator(self):
102 self.busyState = None
103 self.bitmap.SetBitmap(self.errorBitmap)
105 def SetAttentionIndicator(self):
106 self.busyState = None
107 self.bitmap.SetBitmap(self.attentionBitmap)
110 class InfoPage(wx.wizard.WizardPageSimple):
111 def __init__(self, parent, title):
112 wx.wizard.WizardPageSimple.__init__(self, parent)
114 sizer = wx.GridBagSizer(5, 5)
118 title = wx.StaticText(self, -1, title)
119 title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
120 sizer.Add(title, pos=(0, 0), span=(1, 2), flag=wx.ALIGN_CENTRE | wx.ALL)
121 sizer.Add(wx.StaticLine(self, -1), pos=(1, 0), span=(1, 2), flag=wx.EXPAND | wx.ALL)
122 sizer.AddGrowableCol(1)
126 def AddText(self, info):
127 text = wx.StaticText(self, -1, info)
128 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 2), flag=wx.LEFT | wx.RIGHT)
132 def AddSeperator(self):
133 self.GetSizer().Add(wx.StaticLine(self, -1), pos=(self.rowNr, 0), span=(1, 2), flag=wx.EXPAND | wx.ALL)
136 def AddHiddenSeperator(self):
139 def AddInfoBox(self):
140 infoBox = InfoBox(self)
141 self.GetSizer().Add(infoBox, pos=(self.rowNr, 0), span=(1, 2), flag=wx.LEFT | wx.RIGHT | wx.EXPAND)
145 def AddRadioButton(self, label, style=0):
146 radio = wx.RadioButton(self, -1, label, style=style)
147 self.GetSizer().Add(radio, pos=(self.rowNr, 0), span=(1, 2), flag=wx.EXPAND | wx.ALL)
151 def AddCheckbox(self, label, checked=False):
152 check = wx.CheckBox(self, -1)
153 text = wx.StaticText(self, -1, label)
154 check.SetValue(checked)
155 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 1), flag=wx.LEFT | wx.RIGHT)
156 self.GetSizer().Add(check, pos=(self.rowNr, 1), span=(1, 2), flag=wx.ALL)
160 def AddButton(self, label):
161 button = wx.Button(self, -1, label)
162 self.GetSizer().Add(button, pos=(self.rowNr, 0), span=(1, 2), flag=wx.LEFT)
166 def AddDualButton(self, label1, label2):
167 button1 = wx.Button(self, -1, label1)
168 self.GetSizer().Add(button1, pos=(self.rowNr, 0), flag=wx.RIGHT)
169 button2 = wx.Button(self, -1, label2)
170 self.GetSizer().Add(button2, pos=(self.rowNr, 1))
172 return button1, button2
174 def AddTextCtrl(self, value):
175 ret = wx.TextCtrl(self, -1, value)
176 self.GetSizer().Add(ret, pos=(self.rowNr, 0), span=(1, 2), flag=wx.LEFT)
180 def AddLabelTextCtrl(self, info, value):
181 text = wx.StaticText(self, -1, info)
182 ret = wx.TextCtrl(self, -1, value)
183 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 1), flag=wx.LEFT)
184 self.GetSizer().Add(ret, pos=(self.rowNr, 1), span=(1, 1), flag=wx.LEFT)
188 def AddTextCtrlButton(self, value, buttonText):
189 text = wx.TextCtrl(self, -1, value)
190 button = wx.Button(self, -1, buttonText)
191 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 1), flag=wx.LEFT)
192 self.GetSizer().Add(button, pos=(self.rowNr, 1), span=(1, 1), flag=wx.LEFT)
196 def AddBitmap(self, bitmap):
197 bitmap = wx.StaticBitmap(self, -1, bitmap)
198 self.GetSizer().Add(bitmap, pos=(self.rowNr, 0), span=(1, 2), flag=wx.LEFT | wx.RIGHT)
202 def AddCheckmark(self, label, bitmap):
203 check = wx.StaticBitmap(self, -1, bitmap)
204 text = wx.StaticText(self, -1, label)
205 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 1), flag=wx.LEFT | wx.RIGHT)
206 self.GetSizer().Add(check, pos=(self.rowNr, 1), span=(1, 1), flag=wx.ALL)
210 def AddCombo(self, label, options):
211 combo = wx.ComboBox(self, -1, options[0], choices=options, style=wx.CB_DROPDOWN|wx.CB_READONLY)
212 text = wx.StaticText(self, -1, label)
213 self.GetSizer().Add(text, pos=(self.rowNr, 0), span=(1, 1), flag=wx.LEFT | wx.RIGHT)
214 self.GetSizer().Add(combo, pos=(self.rowNr, 1), span=(1, 1), flag=wx.LEFT | wx.RIGHT)
228 class FirstInfoPage(InfoPage):
229 def __init__(self, parent, addNew):
231 super(FirstInfoPage, self).__init__(parent, _("Add new machine wizard"))
233 super(FirstInfoPage, self).__init__(parent, _("First time run wizard"))
234 self.AddText(_("Welcome, and thanks for trying Cura!"))
236 self.AddText(_("This wizard will help you in setting up Cura for your machine."))
239 self._language_option = self.AddCombo(_("Select your language:"), map(lambda o: o[1], resources.getLanguageOptions()))
241 self._language_option = None
242 # self.AddText(_("This wizard will help you with the following steps:"))
243 # self.AddText(_("* Configure Cura for your machine"))
244 # self.AddText(_("* Optionally upgrade your firmware"))
245 # self.AddText(_("* Optionally check if your machine is working safely"))
246 # self.AddText(_("* Optionally level your printer bed"))
248 #self.AddText('* Calibrate your machine')
249 #self.AddText('* Do your first print')
255 if self._language_option is not None:
256 profile.putPreference('language', self._language_option.GetValue())
257 resources.setupLocalization(self._language_option.GetValue())
259 class PrintrbotPage(InfoPage):
260 def __init__(self, parent):
261 self._printer_info = [
262 # X, Y, Z, Nozzle Size, Filament Diameter, PrintTemperature, Print Speed, Travel Speed, Retract speed, Retract amount, use bed level sensor
263 ("Simple Metal", 150, 150, 150, 0.4, 1.75, 208, 40, 70, 30, 1, True),
264 ("Metal Plus", 250, 250, 250, 0.4, 1.75, 208, 40, 70, 30, 1, True),
265 ("Simple Makers Kit", 100, 100, 100, 0.4, 1.75, 208, 40, 70, 30, 1, True),
266 (":" + _("Older models"),),
267 ("Original", 130, 130, 130, 0.5, 2.95, 208, 40, 70, 30, 1, False),
268 ("Simple Maker's Edition v1", 100, 100, 100, 0.5, 1.75, 208, 40, 70, 30, 1, False),
269 ("Simple Maker's Edition v2 (2013 Printrbot Simple)", 100, 100, 100, 0.5, 1.75, 208, 40, 70, 30, 1, False),
270 ("Simple Maker's Edition v3 (2014 Printrbot Simple)", 100, 100, 100, 0.5, 1.75, 208, 40, 70, 30, 1, False),
271 ("Simple Maker's Edition v4 (Model 1405)", 100, 100, 100, 0.5, 1.75, 208, 40, 70, 30, 1, False),
272 ("Jr v1", 150, 100, 80, 0.5, 1.75, 208, 40, 70, 30, 1, False),
273 ("Jr v2", 150, 150, 150, 0.5, 1.75, 208, 40, 70, 30, 1, False),
274 ("LC v2", 150, 150, 150, 0.5, 1.75, 208, 40, 70, 30, 1, False),
275 ("Plus v2", 200, 200, 200, 0.5, 1.75, 208, 40, 70, 30, 1, False),
276 ("Plus v2.1", 200, 200, 200, 0.5, 1.75, 208, 40, 70, 30, 1, False),
277 ("Plus v2.2 (Model 1404/140422)", 250, 250, 250, 0.5, 1.75, 208, 40, 70, 30, 1, False),
278 ("Plus v2.3 (Model 140501)", 250, 250, 250, 0.5, 1.75, 208, 40, 70, 30, 1, False),
279 ("Plus v2.4 (Model 140507)", 250, 250, 250, 0.5, 1.75, 208, 40, 70, 30, 1, False),
280 ("Go v2 Large", 609, 305, 305, 0.5, 1.75, 208, 35, 70, 30, 1, False),
283 super(PrintrbotPage, self).__init__(parent, _("Printrbot Selection"))
284 self.AddBitmap(wx.Bitmap(resources.getPathForImage('Printrbot_logo.png')))
285 self.AddText(_("Select which Printrbot machine you have:"))
287 for printer in self._printer_info:
288 if printer[0].startswith(":"):
290 self.AddText(printer[0][1:])
292 item = self.AddRadioButton(printer[0])
293 item.data = printer[1:]
294 self._items.append(item)
297 profile.putMachineSetting('machine_name', 'Printrbot ???')
298 for item in self._items:
301 profile.putMachineSetting('machine_name', 'Printrbot ' + item.GetLabel())
302 profile.putMachineSetting('machine_width', data[0])
303 profile.putMachineSetting('machine_depth', data[1])
304 profile.putMachineSetting('machine_height', data[2])
305 profile.putProfileSetting('nozzle_size', data[3])
306 profile.putProfileSetting('filament_diameter', data[4])
307 profile.putProfileSetting('print_temperature', data[5])
308 profile.putProfileSetting('print_speed', data[6])
309 profile.putProfileSetting('travel_speed', data[7])
310 profile.putProfileSetting('retraction_speed', data[8])
311 profile.putProfileSetting('retraction_amount', data[9])
312 profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
313 profile.putMachineSetting('has_heated_bed', 'False')
314 profile.putMachineSetting('machine_center_is_zero', 'False')
315 profile.putMachineSetting('extruder_head_size_min_x', '0')
316 profile.putMachineSetting('extruder_head_size_min_y', '0')
317 profile.putMachineSetting('extruder_head_size_max_x', '0')
318 profile.putMachineSetting('extruder_head_size_max_y', '0')
319 profile.putMachineSetting('extruder_head_size_height', '0')
321 profile.setAlterationFile('start.gcode', """;Sliced at: {day} {date} {time}
322 ;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {fill_density}
323 ;Print time: {print_time}
324 ;Filament used: {filament_amount}m {filament_weight}g
325 ;Filament cost: {filament_cost}
326 ;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line
327 ;M109 S{print_temperature} ;Uncomment to add your own temperature line
329 G90 ;absolute positioning
330 M82 ;set extruder to absolute mode
331 M107 ;start with the fan off
333 G28 X0 Y0 ;move X/Y to min endstops
334 G28 Z0 ;move Z to min endstops
335 G29 ;Run the auto bed leveling
337 G1 Z15.0 F{travel_speed} ;move the platform down 15mm
339 G92 E0 ;zero the extruded length
340 G1 F200 E3 ;extrude 3mm of feed stock
341 G92 E0 ;zero the extruded length again
343 ;Put printing message on LCD screen
347 class OtherMachineSelectPage(InfoPage):
348 def __init__(self, parent):
349 super(OtherMachineSelectPage, self).__init__(parent, _("Other machine information"))
350 self.AddText(_("The following pre-defined machine profiles are available"))
351 self.AddText(_("Note that these profiles are not guaranteed to give good results,\nor work at all. Extra tweaks might be required.\nIf you find issues with the predefined profiles,\nor want an extra profile.\nPlease report it at the github issue tracker."))
353 machines = resources.getDefaultMachineProfiles()
355 for filename in machines:
356 name = os.path.splitext(os.path.basename(filename))[0]
357 item = self.AddRadioButton(name)
358 item.filename = filename
359 item.Bind(wx.EVT_RADIOBUTTON, self.OnProfileSelect)
360 self.options.append(item)
362 item = self.AddRadioButton(_('Custom...'))
364 item.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)
366 def OnProfileSelect(self, e):
367 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().otherMachineInfoPage)
369 def OnOtherSelect(self, e):
370 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().customRepRapInfoPage)
373 for option in self.options:
374 if option.GetValue():
375 profile.loadProfile(option.filename)
376 profile.loadMachineSettings(option.filename)
378 class OtherMachineInfoPage(InfoPage):
379 def __init__(self, parent):
380 super(OtherMachineInfoPage, self).__init__(parent, _("Cura Ready!"))
381 self.AddText(_("Cura is now ready to be used!"))
383 class CustomRepRapInfoPage(InfoPage):
384 def __init__(self, parent):
385 super(CustomRepRapInfoPage, self).__init__(parent, _("Custom RepRap information"))
386 self.AddText(_("RepRap machines can be vastly different, so here you can set your own settings."))
387 self.AddText(_("Be sure to review the default profile before running it on your machine."))
388 self.AddText(_("If you like a default profile for your machine added,\nthen make an issue on github."))
390 self.AddText(_("You will have to manually install Marlin or Sprinter firmware."))
392 self.machineName = self.AddLabelTextCtrl(_("Machine name"), "RepRap")
393 self.machineWidth = self.AddLabelTextCtrl(_("Machine width (mm)"), "80")
394 self.machineDepth = self.AddLabelTextCtrl(_("Machine depth (mm)"), "80")
395 self.machineHeight = self.AddLabelTextCtrl(_("Machine height (mm)"), "55")
396 self.nozzleSize = self.AddLabelTextCtrl(_("Nozzle size (mm)"), "0.5")
397 self.heatedBed = self.AddCheckbox(_("Heated bed"))
398 self.HomeAtCenter = self.AddCheckbox(_("Bed center is 0,0,0 (RoStock)"))
401 profile.putMachineSetting('machine_name', self.machineName.GetValue())
402 profile.putMachineSetting('machine_width', self.machineWidth.GetValue())
403 profile.putMachineSetting('machine_depth', self.machineDepth.GetValue())
404 profile.putMachineSetting('machine_height', self.machineHeight.GetValue())
405 profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
406 profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
407 profile.putMachineSetting('has_heated_bed', str(self.heatedBed.GetValue()))
408 profile.putMachineSetting('machine_center_is_zero', str(self.HomeAtCenter.GetValue()))
409 profile.putMachineSetting('extruder_head_size_min_x', '0')
410 profile.putMachineSetting('extruder_head_size_min_y', '0')
411 profile.putMachineSetting('extruder_head_size_max_x', '0')
412 profile.putMachineSetting('extruder_head_size_max_y', '0')
413 profile.putMachineSetting('extruder_head_size_height', '0')
414 profile.checkAndUpdateMachineName()
416 class MachineSelectPage(InfoPage):
417 def __init__(self, parent):
418 super(MachineSelectPage, self).__init__(parent, _("Select your machine"))
419 self.AddText(_("What kind of machine do you have:"))
421 self.Ultimaker2Radio = self.AddRadioButton("Ultimaker2", style=wx.RB_GROUP)
422 self.Ultimaker2Radio.SetValue(True)
423 self.Ultimaker2Radio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimaker2Select)
424 self.UltimakerRadio = self.AddRadioButton("Ultimaker Original")
425 self.UltimakerRadio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimakerSelect)
426 self.UltimakerOPRadio = self.AddRadioButton("Ultimaker Original+")
427 self.UltimakerOPRadio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimakerOPSelect)
428 self.PrintrbotRadio = self.AddRadioButton("Printrbot")
429 self.PrintrbotRadio.Bind(wx.EVT_RADIOBUTTON, self.OnPrintrbotSelect)
430 self.LulzbotTazRadio = self.AddRadioButton("Lulzbot TAZ")
431 self.LulzbotTazRadio.Bind(wx.EVT_RADIOBUTTON, self.OnLulzbotSelect)
432 self.LulzbotMiniRadio = self.AddRadioButton("Lulzbot Mini")
433 self.LulzbotMiniRadio.Bind(wx.EVT_RADIOBUTTON, self.OnLulzbotSelect)
434 self.OtherRadio = self.AddRadioButton(_("Other (Ex: RepRap, MakerBot, Witbox)"))
435 self.OtherRadio.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)
437 self.AddText(_("The collection of anonymous usage information helps with the continued improvement of Cura."))
438 self.AddText(_("This does NOT submit your models online nor gathers any privacy related information."))
439 self.SubmitUserStats = self.AddCheckbox(_("Submit anonymous usage information:"))
440 self.AddText(_("For full details see: http://wiki.ultimaker.com/Cura:stats"))
441 self.SubmitUserStats.SetValue(True)
443 def OnUltimaker2Select(self, e):
444 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimaker2ReadyPage)
446 def OnUltimakerSelect(self, e):
447 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerSelectParts)
449 def OnUltimakerOPSelect(self, e):
450 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerFirmwareUpgradePage)
452 def OnPrintrbotSelect(self, e):
453 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().printrbotSelectType)
455 def OnLulzbotSelect(self, e):
456 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().lulzbotReadyPage)
458 def OnOtherSelect(self, e):
459 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().otherMachineSelectPage)
462 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimaker2ReadyPage)
466 profile.putProfileSetting('retraction_enable', 'True')
467 if self.Ultimaker2Radio.GetValue():
468 profile.putMachineSetting('machine_width', '230')
469 profile.putMachineSetting('machine_depth', '225')
470 profile.putMachineSetting('machine_height', '205')
471 profile.putMachineSetting('machine_name', 'ultimaker2')
472 profile.putMachineSetting('machine_type', 'ultimaker2')
473 profile.putMachineSetting('machine_center_is_zero', 'False')
474 profile.putMachineSetting('has_heated_bed', 'True')
475 profile.putMachineSetting('gcode_flavor', 'UltiGCode')
476 profile.putMachineSetting('extruder_head_size_min_x', '40.0')
477 profile.putMachineSetting('extruder_head_size_min_y', '10.0')
478 profile.putMachineSetting('extruder_head_size_max_x', '60.0')
479 profile.putMachineSetting('extruder_head_size_max_y', '30.0')
480 profile.putMachineSetting('extruder_head_size_height', '48.0')
481 profile.putProfileSetting('nozzle_size', '0.4')
482 profile.putProfileSetting('fan_full_height', '5.0')
483 profile.putMachineSetting('extruder_offset_x1', '18.0')
484 profile.putMachineSetting('extruder_offset_y1', '0.0')
485 elif self.UltimakerRadio.GetValue():
486 profile.putMachineSetting('machine_width', '205')
487 profile.putMachineSetting('machine_depth', '205')
488 profile.putMachineSetting('machine_height', '200')
489 profile.putMachineSetting('machine_name', 'ultimaker original')
490 profile.putMachineSetting('machine_type', 'ultimaker')
491 profile.putMachineSetting('machine_center_is_zero', 'False')
492 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
493 profile.putProfileSetting('nozzle_size', '0.4')
494 profile.putMachineSetting('extruder_head_size_min_x', '75.0')
495 profile.putMachineSetting('extruder_head_size_min_y', '18.0')
496 profile.putMachineSetting('extruder_head_size_max_x', '18.0')
497 profile.putMachineSetting('extruder_head_size_max_y', '35.0')
498 profile.putMachineSetting('extruder_head_size_height', '55.0')
499 elif self.UltimakerOPRadio.GetValue():
500 profile.putMachineSetting('machine_width', '205')
501 profile.putMachineSetting('machine_depth', '205')
502 profile.putMachineSetting('machine_height', '200')
503 profile.putMachineSetting('machine_name', 'ultimaker original+')
504 profile.putMachineSetting('machine_type', 'ultimaker_plus')
505 profile.putMachineSetting('machine_center_is_zero', 'False')
506 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
507 profile.putProfileSetting('nozzle_size', '0.4')
508 profile.putMachineSetting('extruder_head_size_min_x', '75.0')
509 profile.putMachineSetting('extruder_head_size_min_y', '18.0')
510 profile.putMachineSetting('extruder_head_size_max_x', '18.0')
511 profile.putMachineSetting('extruder_head_size_max_y', '35.0')
512 profile.putMachineSetting('extruder_head_size_height', '55.0')
513 profile.putMachineSetting('has_heated_bed', 'True')
514 profile.putMachineSetting('extruder_amount', '1')
515 profile.putProfileSetting('retraction_enable', 'True')
516 elif self.LulzbotTazRadio.GetValue() or self.LulzbotMiniRadio.GetValue():
517 if self.LulzbotTazRadio.GetValue():
518 profile.putMachineSetting('machine_width', '298')
519 profile.putMachineSetting('machine_depth', '275')
520 profile.putMachineSetting('machine_height', '250')
521 profile.putProfileSetting('nozzle_size', '0.35')
522 profile.putMachineSetting('machine_name', 'Lulzbot TAZ')
524 profile.putMachineSetting('machine_width', '160')
525 profile.putMachineSetting('machine_depth', '160')
526 profile.putMachineSetting('machine_height', '160')
527 profile.putProfileSetting('nozzle_size', '0.5')
528 profile.putMachineSetting('machine_name', 'Lulzbot Mini')
529 profile.putMachineSetting('machine_type', 'Aleph Objects')
530 profile.putMachineSetting('machine_center_is_zero', 'False')
531 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
532 profile.putMachineSetting('has_heated_bed', 'True')
533 profile.putMachineSetting('extruder_head_size_min_x', '0.0')
534 profile.putMachineSetting('extruder_head_size_min_y', '0.0')
535 profile.putMachineSetting('extruder_head_size_max_x', '0.0')
536 profile.putMachineSetting('extruder_head_size_max_y', '0.0')
537 profile.putMachineSetting('extruder_head_size_height', '0.0')
539 profile.putMachineSetting('machine_width', '80')
540 profile.putMachineSetting('machine_depth', '80')
541 profile.putMachineSetting('machine_height', '60')
542 profile.putMachineSetting('machine_name', 'reprap')
543 profile.putMachineSetting('machine_type', 'reprap')
544 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
545 profile.putPreference('startMode', 'Normal')
546 profile.putProfileSetting('nozzle_size', '0.5')
547 profile.checkAndUpdateMachineName()
548 profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)
549 if self.SubmitUserStats.GetValue():
550 profile.putPreference('submit_slice_information', 'True')
552 profile.putPreference('submit_slice_information', 'False')
555 class SelectParts(InfoPage):
556 def __init__(self, parent):
557 super(SelectParts, self).__init__(parent, _("Select upgraded parts you have"))
558 self.AddText(_("To assist you in having better default settings for your Ultimaker\nCura would like to know which upgrades you have in your machine."))
560 self.springExtruder = self.AddCheckbox(_("Extruder drive upgrade"))
561 self.heatedBedKit = self.AddCheckbox(_("Heated printer bed (kit)"))
562 self.heatedBed = self.AddCheckbox(_("Heated printer bed (self built)"))
563 self.dualExtrusion = self.AddCheckbox(_("Dual extrusion (experimental)"))
565 self.AddText(_("If you have an Ultimaker bought after october 2012 you will have the\nExtruder drive upgrade. If you do not have this upgrade,\nit is highly recommended to improve reliability."))
566 self.AddText(_("This upgrade can be bought from the Ultimaker webshop\nor found on thingiverse as thing:26094"))
567 self.springExtruder.SetValue(True)
570 profile.putMachineSetting('ultimaker_extruder_upgrade', str(self.springExtruder.GetValue()))
571 if self.heatedBed.GetValue() or self.heatedBedKit.GetValue():
572 profile.putMachineSetting('has_heated_bed', 'True')
574 profile.putMachineSetting('has_heated_bed', 'False')
575 if self.dualExtrusion.GetValue():
576 profile.putMachineSetting('extruder_amount', '2')
577 profile.putMachineSetting('machine_depth', '195')
579 profile.putMachineSetting('extruder_amount', '1')
580 if profile.getMachineSetting('ultimaker_extruder_upgrade') == 'True':
581 profile.putProfileSetting('retraction_enable', 'True')
583 profile.putProfileSetting('retraction_enable', 'False')
586 class UltimakerFirmwareUpgradePage(InfoPage):
587 def __init__(self, parent):
588 super(UltimakerFirmwareUpgradePage, self).__init__(parent, _("Upgrade Ultimaker Firmware"))
589 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."))
590 self.AddHiddenSeperator()
591 self.AddText(_("The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier."))
592 self.AddHiddenSeperator()
593 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."))
594 upgradeButton, skipUpgradeButton = self.AddDualButton('Upgrade to Marlin firmware', 'Skip upgrade')
595 upgradeButton.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)
596 skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick)
597 self.AddHiddenSeperator()
598 if profile.getMachineSetting('machine_type') == 'ultimaker':
599 self.AddText(_("Do not upgrade to this firmware if:"))
600 self.AddText(_("* You have an older machine based on ATMega1280 (Rev 1 machine)"))
601 self.AddText(_("* Build your own heated bed"))
602 self.AddText(_("* Have other changes in the firmware"))
603 # button = self.AddButton('Goto this page for a custom firmware')
604 # button.Bind(wx.EVT_BUTTON, self.OnUrlClick)
609 def OnUpgradeClick(self, e):
610 if firmwareInstall.InstallFirmware():
611 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
613 def OnSkipClick(self, e):
614 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
615 self.GetParent().ShowPage(self.GetNext())
617 def OnUrlClick(self, e):
618 webbrowser.open('http://marlinbuilder.robotfuzz.com/')
620 class UltimakerCheckupPage(InfoPage):
621 def __init__(self, parent):
622 super(UltimakerCheckupPage, self).__init__(parent, _("Ultimaker Checkup"))
624 self.checkBitmap = wx.Bitmap(resources.getPathForImage('checkmark.png'))
625 self.crossBitmap = wx.Bitmap(resources.getPathForImage('cross.png'))
626 self.unknownBitmap = wx.Bitmap(resources.getPathForImage('question.png'))
627 self.endStopNoneBitmap = wx.Bitmap(resources.getPathForImage('endstop_none.png'))
628 self.endStopXMinBitmap = wx.Bitmap(resources.getPathForImage('endstop_xmin.png'))
629 self.endStopXMaxBitmap = wx.Bitmap(resources.getPathForImage('endstop_xmax.png'))
630 self.endStopYMinBitmap = wx.Bitmap(resources.getPathForImage('endstop_ymin.png'))
631 self.endStopYMaxBitmap = wx.Bitmap(resources.getPathForImage('endstop_ymax.png'))
632 self.endStopZMinBitmap = wx.Bitmap(resources.getPathForImage('endstop_zmin.png'))
633 self.endStopZMaxBitmap = wx.Bitmap(resources.getPathForImage('endstop_zmax.png'))
636 _("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."))
637 b1, b2 = self.AddDualButton(_("Run checks"), _("Skip checks"))
638 b1.Bind(wx.EVT_BUTTON, self.OnCheckClick)
639 b2.Bind(wx.EVT_BUTTON, self.OnSkipClick)
641 self.commState = self.AddCheckmark(_("Communication:"), self.unknownBitmap)
642 self.tempState = self.AddCheckmark(_("Temperature:"), self.unknownBitmap)
643 self.stopState = self.AddCheckmark(_("Endstops:"), self.unknownBitmap)
645 self.infoBox = self.AddInfoBox()
646 self.machineState = self.AddText("")
647 self.temperatureLabel = self.AddText("")
648 self.errorLogButton = self.AddButton(_("Show error log"))
649 self.errorLogButton.Show(False)
651 self.endstopBitmap = self.AddBitmap(self.endStopNoneBitmap)
653 self.xMinStop = False
654 self.xMaxStop = False
655 self.yMinStop = False
656 self.yMaxStop = False
657 self.zMinStop = False
658 self.zMaxStop = False
660 self.Bind(wx.EVT_BUTTON, self.OnErrorLog, self.errorLogButton)
663 if self.comm is not None:
667 self.endstopBitmap.Show(False)
670 def OnSkipClick(self, e):
671 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
672 self.GetParent().ShowPage(self.GetNext())
674 def OnCheckClick(self, e=None):
675 self.errorLogButton.Show(False)
676 if self.comm is not None:
680 wx.CallAfter(self.OnCheckClick)
682 self.infoBox.SetBusy(_("Connecting to machine."))
683 self.commState.SetBitmap(self.unknownBitmap)
684 self.tempState.SetBitmap(self.unknownBitmap)
685 self.stopState.SetBitmap(self.unknownBitmap)
686 self.checkupState = 0
687 self.checkExtruderNr = 0
688 self.comm = machineCom.MachineCom(callbackObject=self)
690 def OnErrorLog(self, e):
691 printWindow.LogWindow('\n'.join(self.comm.getLog()))
693 def mcLog(self, message):
696 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
697 if not self.comm.isOperational():
699 if self.checkupState == 0:
700 self.tempCheckTimeout = 20
701 if temp[self.checkExtruderNr] > 70:
702 self.checkupState = 1
703 wx.CallAfter(self.infoBox.SetInfo, _("Cooldown before temperature check."))
704 self.comm.sendCommand("M104 S0 T%d" % (self.checkExtruderNr))
705 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
707 self.startTemp = temp[self.checkExtruderNr]
708 self.checkupState = 2
709 wx.CallAfter(self.infoBox.SetInfo, _("Checking the heater and temperature sensor."))
710 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
711 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
712 elif self.checkupState == 1:
713 if temp[self.checkExtruderNr] < 60:
714 self.startTemp = temp[self.checkExtruderNr]
715 self.checkupState = 2
716 wx.CallAfter(self.infoBox.SetInfo, _("Checking the heater and temperature sensor."))
717 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
718 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
719 elif self.checkupState == 2:
720 #print "WARNING, TEMPERATURE TEST DISABLED FOR TESTING!"
721 if temp[self.checkExtruderNr] > self.startTemp + 40:
722 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
723 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
724 if self.checkExtruderNr < int(profile.getMachineSetting('extruder_amount')):
725 self.checkExtruderNr = 0
726 self.checkupState = 3
727 wx.CallAfter(self.infoBox.SetAttention, _("Please make sure none of the endstops are pressed."))
728 wx.CallAfter(self.endstopBitmap.Show, True)
729 wx.CallAfter(self.Layout)
730 self.comm.sendCommand('M119')
731 wx.CallAfter(self.tempState.SetBitmap, self.checkBitmap)
733 self.checkupState = 0
734 self.checkExtruderNr += 1
736 self.tempCheckTimeout -= 1
737 if self.tempCheckTimeout < 1:
738 self.checkupState = -1
739 wx.CallAfter(self.tempState.SetBitmap, self.crossBitmap)
740 wx.CallAfter(self.infoBox.SetError, _("Temperature measurement FAILED!"), 'http://wiki.ultimaker.com/Cura:_Temperature_measurement_problems')
741 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
742 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
743 elif self.checkupState >= 3 and self.checkupState < 10:
744 self.comm.sendCommand('M119')
745 wx.CallAfter(self.temperatureLabel.SetLabel, _("Head temperature: %d") % (temp[self.checkExtruderNr]))
747 def mcStateChange(self, state):
748 if self.comm is None:
750 if self.comm.isOperational():
751 wx.CallAfter(self.commState.SetBitmap, self.checkBitmap)
752 wx.CallAfter(self.machineState.SetLabel, _("Communication State: %s") % (self.comm.getStateString()))
753 elif self.comm.isError():
754 wx.CallAfter(self.commState.SetBitmap, self.crossBitmap)
755 wx.CallAfter(self.infoBox.SetError, _("Failed to establish connection with the printer."), 'http://wiki.ultimaker.com/Cura:_Connection_problems')
756 wx.CallAfter(self.endstopBitmap.Show, False)
757 wx.CallAfter(self.machineState.SetLabel, '%s' % (self.comm.getErrorString()))
758 wx.CallAfter(self.errorLogButton.Show, True)
759 wx.CallAfter(self.Layout)
761 wx.CallAfter(self.machineState.SetLabel, _("Communication State: %s") % (self.comm.getStateString()))
763 def mcMessage(self, message):
764 if self.checkupState >= 3 and self.checkupState < 10 and ('_min' in message or '_max' in message):
765 for data in message.split(' '):
767 tag, value = data.split(':', 1)
769 self.xMinStop = (value == 'H' or value == 'TRIGGERED')
771 self.xMaxStop = (value == 'H' or value == 'TRIGGERED')
773 self.yMinStop = (value == 'H' or value == 'TRIGGERED')
775 self.yMaxStop = (value == 'H' or value == 'TRIGGERED')
777 self.zMinStop = (value == 'H' or value == 'TRIGGERED')
779 self.zMaxStop = (value == 'H' or value == 'TRIGGERED')
781 tag, value = map(str.strip, message.split(':', 1))
783 self.xMinStop = (value == 'H' or value == 'TRIGGERED')
785 self.xMaxStop = (value == 'H' or value == 'TRIGGERED')
787 self.yMinStop = (value == 'H' or value == 'TRIGGERED')
789 self.yMaxStop = (value == 'H' or value == 'TRIGGERED')
791 self.zMinStop = (value == 'H' or value == 'TRIGGERED')
793 self.zMaxStop = (value == 'H' or value == 'TRIGGERED')
794 if 'z_max' in message:
795 self.comm.sendCommand('M119')
797 if self.checkupState == 3:
798 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
799 if profile.getMachineSetting('machine_type') == 'ultimaker_plus':
800 self.checkupState = 5
801 wx.CallAfter(self.infoBox.SetAttention, _("Please press the left X endstop."))
802 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMinBitmap)
804 self.checkupState = 4
805 wx.CallAfter(self.infoBox.SetAttention, _("Please press the right X endstop."))
806 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMaxBitmap)
807 elif self.checkupState == 4:
808 if not self.xMinStop and self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
809 self.checkupState = 5
810 wx.CallAfter(self.infoBox.SetAttention, _("Please press the left X endstop."))
811 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMinBitmap)
812 elif self.checkupState == 5:
813 if self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
814 self.checkupState = 6
815 wx.CallAfter(self.infoBox.SetAttention, _("Please press the front Y endstop."))
816 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopYMinBitmap)
817 elif self.checkupState == 6:
818 if not self.xMinStop and not self.xMaxStop and self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
819 if profile.getMachineSetting('machine_type') == 'ultimaker_plus':
820 self.checkupState = 8
821 wx.CallAfter(self.infoBox.SetAttention, _("Please press the top Z endstop."))
822 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMinBitmap)
824 self.checkupState = 7
825 wx.CallAfter(self.infoBox.SetAttention, _("Please press the back Y endstop."))
826 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopYMaxBitmap)
827 elif self.checkupState == 7:
828 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and self.yMaxStop and not self.zMinStop and not self.zMaxStop:
829 self.checkupState = 8
830 wx.CallAfter(self.infoBox.SetAttention, _("Please press the top Z endstop."))
831 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMinBitmap)
832 elif self.checkupState == 8:
833 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and self.zMinStop and not self.zMaxStop:
834 if profile.getMachineSetting('machine_type') == 'ultimaker_plus':
835 self.checkupState = 10
837 wx.CallAfter(self.infoBox.SetInfo, _("Checkup finished"))
838 wx.CallAfter(self.infoBox.SetReadyIndicator)
839 wx.CallAfter(self.endstopBitmap.Show, False)
840 wx.CallAfter(self.stopState.SetBitmap, self.checkBitmap)
841 wx.CallAfter(self.OnSkipClick, None)
843 self.checkupState = 9
844 wx.CallAfter(self.infoBox.SetAttention, _("Please press the bottom Z endstop."))
845 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMaxBitmap)
846 elif self.checkupState == 9:
847 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and self.zMaxStop:
848 self.checkupState = 10
850 wx.CallAfter(self.infoBox.SetInfo, _("Checkup finished"))
851 wx.CallAfter(self.infoBox.SetReadyIndicator)
852 wx.CallAfter(self.endstopBitmap.Show, False)
853 wx.CallAfter(self.stopState.SetBitmap, self.checkBitmap)
854 wx.CallAfter(self.OnSkipClick, None)
856 def mcProgress(self, lineNr):
859 def mcZChange(self, newZ):
863 class UltimakerCalibrationPage(InfoPage):
864 def __init__(self, parent):
865 super(UltimakerCalibrationPage, self).__init__(parent, _("Ultimaker Calibration"))
867 self.AddText("Your Ultimaker requires some calibration.")
868 self.AddText("This calibration is needed for a proper extrusion amount.")
870 self.AddText("The following values are needed:")
871 self.AddText("* Diameter of filament")
872 self.AddText("* Number of steps per mm of filament extrusion")
874 self.AddText("The better you have calibrated these values, the better your prints\nwill become.")
876 self.AddText("First we need the diameter of your filament:")
877 self.filamentDiameter = self.AddTextCtrl(profile.getProfileSetting('filament_diameter'))
879 "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.")
880 self.AddText("Note: This value can be changed later at any time.")
883 profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue())
886 class UltimakerCalibrateStepsPerEPage(InfoPage):
887 def __init__(self, parent):
888 super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, _("Ultimaker Calibration"))
890 #if profile.getMachineSetting('steps_per_e') == '0':
891 # profile.putMachineSetting('steps_per_e', '865.888')
893 self.AddText(_("Calibrating the Steps Per E requires some manual actions."))
894 self.AddText(_("First remove any filament from your machine."))
895 self.AddText(_("Next put in your filament so the tip is aligned with the\ntop of the extruder drive."))
896 self.AddText(_("We'll push the filament 100mm"))
897 self.extrudeButton = self.AddButton(_("Extrude 100mm filament"))
898 self.AddText(_("Now measure the amount of extruded filament:\n(this can be more or less then 100mm)"))
899 self.lengthInput, self.saveLengthButton = self.AddTextCtrlButton("100", _("Save"))
900 self.AddText(_("This results in the following steps per E:"))
901 self.stepsPerEInput = self.AddTextCtrl(profile.getMachineSetting('steps_per_e'))
902 self.AddText(_("You can repeat these steps to get better calibration."))
905 _("If you still have filament in your printer which needs\nheat to remove, press the heat up button below:"))
906 self.heatButton = self.AddButton(_("Heatup for filament removal"))
908 self.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick)
909 self.extrudeButton.Bind(wx.EVT_BUTTON, self.OnExtrudeClick)
910 self.heatButton.Bind(wx.EVT_BUTTON, self.OnHeatClick)
912 def OnSaveLengthClick(self, e):
913 currentEValue = float(self.stepsPerEInput.GetValue())
914 realExtrudeLength = float(self.lengthInput.GetValue())
915 newEValue = currentEValue * 100 / realExtrudeLength
916 self.stepsPerEInput.SetValue(str(newEValue))
917 self.lengthInput.SetValue("100")
919 def OnExtrudeClick(self, e):
920 t = threading.Thread(target=self.OnExtrudeRun)
924 def OnExtrudeRun(self):
925 self.heatButton.Enable(False)
926 self.extrudeButton.Enable(False)
927 currentEValue = float(self.stepsPerEInput.GetValue())
928 self.comm = machineCom.MachineCom()
929 if not self.comm.isOpen():
931 _("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable"),
932 'Printer error', wx.OK | wx.ICON_INFORMATION)
933 self.heatButton.Enable(True)
934 self.extrudeButton.Enable(True)
937 line = self.comm.readline()
942 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
945 self.sendGCommand('M302') #Disable cold extrusion protection
946 self.sendGCommand("M92 E%f" % (currentEValue))
947 self.sendGCommand("G92 E0")
948 self.sendGCommand("G1 E100 F600")
951 self.extrudeButton.Enable()
952 self.heatButton.Enable()
954 def OnHeatClick(self, e):
955 t = threading.Thread(target=self.OnHeatRun)
960 self.heatButton.Enable(False)
961 self.extrudeButton.Enable(False)
962 self.comm = machineCom.MachineCom()
963 if not self.comm.isOpen():
965 _("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable"),
966 'Printer error', wx.OK | wx.ICON_INFORMATION)
967 self.heatButton.Enable(True)
968 self.extrudeButton.Enable(True)
971 line = self.comm.readline()
973 self.heatButton.Enable(True)
974 self.extrudeButton.Enable(True)
978 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
981 self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out.
983 'Wait till you can remove the filament from the machine, and press OK.\n(Temperature is set to 200C)',
984 'Machine heatup', wx.OK | wx.ICON_INFORMATION)
985 self.sendGCommand('M104 S0')
988 self.heatButton.Enable(True)
989 self.extrudeButton.Enable(True)
991 def sendGCommand(self, cmd):
992 self.comm.sendCommand(cmd) #Disable cold extrusion protection
994 line = self.comm.readline()
997 if line.startswith('ok'):
1000 def StoreData(self):
1001 profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue())
1003 class Ultimaker2ReadyPage(InfoPage):
1004 def __init__(self, parent):
1005 super(Ultimaker2ReadyPage, self).__init__(parent, _("Ultimaker2"))
1006 self.AddText(_('Congratulations on your the purchase of your brand new Ultimaker2.'))
1007 self.AddText(_('Cura is now ready to be used with your Ultimaker2.'))
1010 class LulzbotReadyPage(InfoPage):
1011 def __init__(self, parent):
1012 super(LulzbotReadyPage, self).__init__(parent, _("Lulzbot TAZ/Mini"))
1013 self.AddText(_('Cura is now ready to be used with your Lulzbot.'))
1016 class ConfigWizard(wx.wizard.Wizard):
1017 def __init__(self, addNew = False):
1018 super(ConfigWizard, self).__init__(None, -1, _("Configuration Wizard"))
1020 self._old_machine_index = int(profile.getPreferenceFloat('active_machine'))
1022 profile.setActiveMachine(profile.getMachineCount())
1024 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
1025 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
1026 self.Bind(wx.wizard.EVT_WIZARD_CANCEL, self.OnCancel)
1028 self.firstInfoPage = FirstInfoPage(self, addNew)
1029 self.machineSelectPage = MachineSelectPage(self)
1030 self.ultimakerSelectParts = SelectParts(self)
1031 self.ultimakerFirmwareUpgradePage = UltimakerFirmwareUpgradePage(self)
1032 self.ultimakerCheckupPage = UltimakerCheckupPage(self)
1033 self.ultimakerCalibrationPage = UltimakerCalibrationPage(self)
1034 self.ultimakerCalibrateStepsPerEPage = UltimakerCalibrateStepsPerEPage(self)
1035 self.bedLevelPage = bedLevelWizardMain(self)
1036 self.headOffsetCalibration = headOffsetCalibrationPage(self)
1037 self.printrbotSelectType = PrintrbotPage(self)
1038 self.otherMachineSelectPage = OtherMachineSelectPage(self)
1039 self.customRepRapInfoPage = CustomRepRapInfoPage(self)
1040 self.otherMachineInfoPage = OtherMachineInfoPage(self)
1042 self.ultimaker2ReadyPage = Ultimaker2ReadyPage(self)
1043 self.lulzbotReadyPage = LulzbotReadyPage(self)
1045 wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage)
1046 #wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimaker2ReadyPage)
1047 wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerSelectParts)
1048 wx.wizard.WizardPageSimple.Chain(self.ultimakerSelectParts, self.ultimakerFirmwareUpgradePage)
1049 wx.wizard.WizardPageSimple.Chain(self.ultimakerFirmwareUpgradePage, self.ultimakerCheckupPage)
1050 wx.wizard.WizardPageSimple.Chain(self.ultimakerCheckupPage, self.bedLevelPage)
1051 #wx.wizard.WizardPageSimple.Chain(self.ultimakerCalibrationPage, self.ultimakerCalibrateStepsPerEPage)
1052 wx.wizard.WizardPageSimple.Chain(self.printrbotSelectType, self.otherMachineInfoPage)
1053 wx.wizard.WizardPageSimple.Chain(self.otherMachineSelectPage, self.customRepRapInfoPage)
1055 self.FitToPage(self.firstInfoPage)
1056 self.GetPageAreaSizer().Add(self.firstInfoPage)
1058 self.RunWizard(self.firstInfoPage)
1061 def OnPageChanging(self, e):
1062 e.GetPage().StoreData()
1064 def OnPageChanged(self, e):
1065 if e.GetPage().AllowNext():
1066 self.FindWindowById(wx.ID_FORWARD).Enable()
1068 self.FindWindowById(wx.ID_FORWARD).Disable()
1069 if e.GetPage().AllowBack():
1070 self.FindWindowById(wx.ID_BACKWARD).Enable()
1072 self.FindWindowById(wx.ID_BACKWARD).Disable()
1074 def OnCancel(self, e):
1075 profile.setActiveMachine(self._old_machine_index)
1077 class bedLevelWizardMain(InfoPage):
1078 def __init__(self, parent):
1079 super(bedLevelWizardMain, self).__init__(parent, _("Bed leveling wizard"))
1081 self.AddText(_('This wizard will help you in leveling your printer bed'))
1083 self.AddText(_('It will do the following steps'))
1084 self.AddText(_('* Move the printer head to each corner'))
1085 self.AddText(_(' and let you adjust the height of the bed to the nozzle'))
1086 self.AddText(_('* Print a line around the bed to check if it is level'))
1089 self.connectButton = self.AddButton(_('Connect to printer'))
1092 self.infoBox = self.AddInfoBox()
1093 self.resumeButton = self.AddButton(_('Resume'))
1094 self.upButton, self.downButton = self.AddDualButton(_('Up 0.2mm'), _('Down 0.2mm'))
1095 self.upButton2, self.downButton2 = self.AddDualButton(_('Up 10mm'), _('Down 10mm'))
1096 self.resumeButton.Enable(False)
1098 self.upButton.Enable(False)
1099 self.downButton.Enable(False)
1100 self.upButton2.Enable(False)
1101 self.downButton2.Enable(False)
1103 self.Bind(wx.EVT_BUTTON, self.OnConnect, self.connectButton)
1104 self.Bind(wx.EVT_BUTTON, self.OnResume, self.resumeButton)
1105 self.Bind(wx.EVT_BUTTON, self.OnBedUp, self.upButton)
1106 self.Bind(wx.EVT_BUTTON, self.OnBedDown, self.downButton)
1107 self.Bind(wx.EVT_BUTTON, self.OnBedUp2, self.upButton2)
1108 self.Bind(wx.EVT_BUTTON, self.OnBedDown2, self.downButton2)
1110 def OnConnect(self, e = None):
1111 if self.comm is not None:
1115 wx.CallAfter(self.OnConnect)
1117 self.connectButton.Enable(False)
1118 self.comm = machineCom.MachineCom(callbackObject=self)
1119 self.infoBox.SetBusy(_('Connecting to machine.'))
1120 self._wizardState = 0
1122 def OnBedUp(self, e):
1123 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1124 self.comm.sendCommand('G92 Z10')
1125 self.comm.sendCommand('G1 Z9.8 F%d' % (feedZ))
1126 self.comm.sendCommand('M400')
1128 def OnBedDown(self, e):
1129 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1130 self.comm.sendCommand('G92 Z10')
1131 self.comm.sendCommand('G1 Z10.2 F%d' % (feedZ))
1132 self.comm.sendCommand('M400')
1134 def OnBedUp2(self, e):
1135 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1136 self.comm.sendCommand('G92 Z10')
1137 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1138 self.comm.sendCommand('M400')
1140 def OnBedDown2(self, e):
1141 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1142 self.comm.sendCommand('G92 Z10')
1143 self.comm.sendCommand('G1 Z20 F%d' % (feedZ))
1144 self.comm.sendCommand('M400')
1146 def AllowNext(self):
1147 if self.GetParent().headOffsetCalibration is not None and int(profile.getMachineSetting('extruder_amount')) > 1:
1148 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().headOffsetCalibration)
1151 def OnResume(self, e):
1152 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1153 feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
1154 if self._wizardState == -1:
1155 wx.CallAfter(self.infoBox.SetInfo, _('Homing printer...'))
1156 wx.CallAfter(self.upButton.Enable, False)
1157 wx.CallAfter(self.downButton.Enable, False)
1158 wx.CallAfter(self.upButton2.Enable, False)
1159 wx.CallAfter(self.downButton2.Enable, False)
1160 self.comm.sendCommand('M105')
1161 self.comm.sendCommand('G28')
1162 self._wizardState = 1
1163 elif self._wizardState == 2:
1164 if profile.getMachineSetting('has_heated_bed') == 'True':
1165 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to back center...'))
1166 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1167 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') / 2.0, profile.getMachineSettingFloat('machine_depth'), feedTravel))
1168 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1169 self.comm.sendCommand('M400')
1170 self._wizardState = 3
1172 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to back left corner...'))
1173 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1174 self.comm.sendCommand('G1 X%d Y%d F%d' % (0, profile.getMachineSettingFloat('machine_depth'), feedTravel))
1175 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1176 self.comm.sendCommand('M400')
1177 self._wizardState = 3
1178 elif self._wizardState == 4:
1179 if profile.getMachineSetting('has_heated_bed') == 'True':
1180 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to front right corner...'))
1181 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1182 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, 5, feedTravel))
1183 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1184 self.comm.sendCommand('M400')
1185 self._wizardState = 7
1187 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to back right corner...'))
1188 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1189 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, profile.getMachineSettingFloat('machine_depth') - 25, feedTravel))
1190 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1191 self.comm.sendCommand('M400')
1192 self._wizardState = 5
1193 elif self._wizardState == 6:
1194 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to front right corner...'))
1195 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1196 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, 20, feedTravel))
1197 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1198 self.comm.sendCommand('M400')
1199 self._wizardState = 7
1200 elif self._wizardState == 8:
1201 wx.CallAfter(self.infoBox.SetBusy, _('Heating up printer...'))
1202 self.comm.sendCommand('G1 Z15 F%d' % (feedZ))
1203 self.comm.sendCommand('M104 S%d' % (profile.getProfileSettingFloat('print_temperature')))
1204 self.comm.sendCommand('G1 X%d Y%d F%d' % (0, 0, feedTravel))
1205 self._wizardState = 9
1206 elif self._wizardState == 10:
1207 self._wizardState = 11
1208 wx.CallAfter(self.infoBox.SetInfo, _('Printing a square on the printer bed at 0.3mm height.'))
1209 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1210 feedPrint = profile.getProfileSettingFloat('print_speed') * 60
1211 feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
1212 w = profile.getMachineSettingFloat('machine_width') - 10
1213 d = profile.getMachineSettingFloat('machine_depth')
1214 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
1215 filamentArea = math.pi * filamentRadius * filamentRadius
1216 ePerMM = (profile.calculateEdgeWidth() * 0.3) / filamentArea
1220 'G1 Z2 F%d' % (feedZ),
1222 'G1 X%d Y%d F%d' % (5, 5, feedTravel),
1223 'G1 Z0.3 F%d' % (feedZ)]
1225 gcodeList.append('G1 E%f F%d' % (eValue, profile.getProfileSettingFloat('retraction_speed') * 60))
1227 for i in xrange(0, 3):
1228 dist = 5.0 + 0.4 * float(i)
1229 eValue += (d - 2.0*dist) * ePerMM
1230 gcodeList.append('G1 X%f Y%f E%f F%d' % (dist, d - dist, eValue, feedPrint))
1231 eValue += (w - 2.0*dist) * ePerMM
1232 gcodeList.append('G1 X%f Y%f E%f F%d' % (w - dist, d - dist, eValue, feedPrint))
1233 eValue += (d - 2.0*dist) * ePerMM
1234 gcodeList.append('G1 X%f Y%f E%f F%d' % (w - dist, dist, eValue, feedPrint))
1235 eValue += (w - 2.0*dist) * ePerMM
1236 gcodeList.append('G1 X%f Y%f E%f F%d' % (dist, dist, eValue, feedPrint))
1238 gcodeList.append('M400')
1239 self.comm.printGCode(gcodeList)
1240 self.resumeButton.Enable(False)
1242 def mcLog(self, message):
1243 print 'Log:', message
1245 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
1246 if self._wizardState == 1:
1247 self._wizardState = 2
1248 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the front left screw of your printer bed\nSo the nozzle just hits the bed.'))
1249 wx.CallAfter(self.resumeButton.Enable, True)
1250 elif self._wizardState == 3:
1251 self._wizardState = 4
1252 if profile.getMachineSetting('has_heated_bed') == 'True':
1253 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the back screw of your printer bed\nSo the nozzle just hits the bed.'))
1255 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the back left screw of your printer bed\nSo the nozzle just hits the bed.'))
1256 wx.CallAfter(self.resumeButton.Enable, True)
1257 elif self._wizardState == 5:
1258 self._wizardState = 6
1259 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the back right screw of your printer bed\nSo the nozzle just hits the bed.'))
1260 wx.CallAfter(self.resumeButton.Enable, True)
1261 elif self._wizardState == 7:
1262 self._wizardState = 8
1263 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the front right screw of your printer bed\nSo the nozzle just hits the bed.'))
1264 wx.CallAfter(self.resumeButton.Enable, True)
1265 elif self._wizardState == 9:
1266 if temp[0] < profile.getProfileSettingFloat('print_temperature') - 5:
1267 wx.CallAfter(self.infoBox.SetInfo, _('Heating up printer: %d/%d') % (temp[0], profile.getProfileSettingFloat('print_temperature')))
1269 wx.CallAfter(self.infoBox.SetAttention, _('The printer is hot now. Please insert some PLA filament into the printer.'))
1270 wx.CallAfter(self.resumeButton.Enable, True)
1271 self._wizardState = 10
1273 def mcStateChange(self, state):
1274 if self.comm is None:
1276 if self.comm.isOperational():
1277 if self._wizardState == 0:
1278 wx.CallAfter(self.infoBox.SetAttention, _('Use the up/down buttons to move the bed and adjust your Z endstop.'))
1279 wx.CallAfter(self.upButton.Enable, True)
1280 wx.CallAfter(self.downButton.Enable, True)
1281 wx.CallAfter(self.upButton2.Enable, True)
1282 wx.CallAfter(self.downButton2.Enable, True)
1283 wx.CallAfter(self.resumeButton.Enable, True)
1284 self._wizardState = -1
1285 elif self._wizardState == 11 and not self.comm.isPrinting():
1286 self.comm.sendCommand('G1 Z15 F%d' % (profile.getProfileSettingFloat('print_speed') * 60))
1287 self.comm.sendCommand('G92 E0')
1288 self.comm.sendCommand('G1 E-10 F%d' % (profile.getProfileSettingFloat('retraction_speed') * 60))
1289 self.comm.sendCommand('M104 S0')
1290 wx.CallAfter(self.infoBox.SetInfo, _('Calibration finished.\nThe squares on the bed should slightly touch each other.'))
1291 wx.CallAfter(self.infoBox.SetReadyIndicator)
1292 wx.CallAfter(self.GetParent().FindWindowById(wx.ID_FORWARD).Enable)
1293 wx.CallAfter(self.connectButton.Enable, True)
1294 self._wizardState = 12
1295 elif self.comm.isError():
1296 wx.CallAfter(self.infoBox.SetError, _('Failed to establish connection with the printer.'), 'http://wiki.ultimaker.com/Cura:_Connection_problems')
1298 def mcMessage(self, message):
1301 def mcProgress(self, lineNr):
1304 def mcZChange(self, newZ):
1307 class headOffsetCalibrationPage(InfoPage):
1308 def __init__(self, parent):
1309 super(headOffsetCalibrationPage, self).__init__(parent, "Printer head offset calibration")
1311 self.AddText(_('This wizard will help you in calibrating the printer head offsets of your dual extrusion machine'))
1314 self.connectButton = self.AddButton(_('Connect to printer'))
1317 self.infoBox = self.AddInfoBox()
1318 self.textEntry = self.AddTextCtrl('')
1319 self.textEntry.Enable(False)
1320 self.resumeButton = self.AddButton(_('Resume'))
1321 self.resumeButton.Enable(False)
1323 self.Bind(wx.EVT_BUTTON, self.OnConnect, self.connectButton)
1324 self.Bind(wx.EVT_BUTTON, self.OnResume, self.resumeButton)
1326 def AllowBack(self):
1329 def OnConnect(self, e = None):
1330 if self.comm is not None:
1334 wx.CallAfter(self.OnConnect)
1336 self.connectButton.Enable(False)
1337 self.comm = machineCom.MachineCom(callbackObject=self)
1338 self.infoBox.SetBusy(_('Connecting to machine.'))
1339 self._wizardState = 0
1341 def OnResume(self, e):
1342 if self._wizardState == 2:
1343 self._wizardState = 3
1344 wx.CallAfter(self.infoBox.SetBusy, _('Printing initial calibration cross'))
1346 w = profile.getMachineSettingFloat('machine_width')
1347 d = profile.getMachineSettingFloat('machine_depth')
1349 gcode = gcodeGenerator.gcodeGenerator()
1350 gcode.setExtrusionRate(profile.getProfileSettingFloat('nozzle_size') * 1.5, 0.2)
1351 gcode.setPrintSpeed(profile.getProfileSettingFloat('bottom_layer_speed'))
1358 gcode.addMove(w/2, 5)
1359 gcode.addMove(z=0.2)
1361 gcode.addExtrude(w/2, d-5.0)
1363 gcode.addMove(5, d/2)
1365 gcode.addExtrude(w-5.0, d/2)
1366 gcode.addRetract(15)
1369 gcode.addMove(w/2, 5)
1371 gcode.addExtrude(w/2, d-5.0)
1373 gcode.addMove(5, d/2)
1375 gcode.addExtrude(w-5.0, d/2)
1376 gcode.addRetract(15)
1381 gcode.addCmd('M400')
1383 self.comm.printGCode(gcode.list())
1384 self.resumeButton.Enable(False)
1385 elif self._wizardState == 4:
1387 float(self.textEntry.GetValue())
1390 profile.putPreference('extruder_offset_x1', self.textEntry.GetValue())
1391 self._wizardState = 5
1392 self.infoBox.SetAttention(_('Please measure the distance between the horizontal lines in millimeters.'))
1393 self.textEntry.SetValue('0.0')
1394 self.textEntry.Enable(True)
1395 elif self._wizardState == 5:
1397 float(self.textEntry.GetValue())
1400 profile.putPreference('extruder_offset_y1', self.textEntry.GetValue())
1401 self._wizardState = 6
1402 self.infoBox.SetBusy(_('Printing the fine calibration lines.'))
1403 self.textEntry.SetValue('')
1404 self.textEntry.Enable(False)
1405 self.resumeButton.Enable(False)
1407 x = profile.getMachineSettingFloat('extruder_offset_x1')
1408 y = profile.getMachineSettingFloat('extruder_offset_y1')
1409 gcode = gcodeGenerator.gcodeGenerator()
1410 gcode.setExtrusionRate(profile.getProfileSettingFloat('nozzle_size') * 1.5, 0.2)
1411 gcode.setPrintSpeed(25)
1414 gcode.addMove(50, 40, 0.2)
1416 for n in xrange(0, 10):
1417 gcode.addExtrude(50 + n * 10, 150)
1418 gcode.addExtrude(50 + n * 10 + 5, 150)
1419 gcode.addExtrude(50 + n * 10 + 5, 40)
1420 gcode.addExtrude(50 + n * 10 + 10, 40)
1421 gcode.addMove(40, 50)
1422 for n in xrange(0, 10):
1423 gcode.addExtrude(150, 50 + n * 10)
1424 gcode.addExtrude(150, 50 + n * 10 + 5)
1425 gcode.addExtrude(40, 50 + n * 10 + 5)
1426 gcode.addExtrude(40, 50 + n * 10 + 10)
1427 gcode.addRetract(15)
1430 gcode.addMove(50 - x, 30 - y, 0.2)
1432 for n in xrange(0, 10):
1433 gcode.addExtrude(50 + n * 10.2 - 1.0 - x, 140 - y)
1434 gcode.addExtrude(50 + n * 10.2 - 1.0 + 5.1 - x, 140 - y)
1435 gcode.addExtrude(50 + n * 10.2 - 1.0 + 5.1 - x, 30 - y)
1436 gcode.addExtrude(50 + n * 10.2 - 1.0 + 10 - x, 30 - y)
1437 gcode.addMove(30 - x, 50 - y, 0.2)
1438 for n in xrange(0, 10):
1439 gcode.addExtrude(160 - x, 50 + n * 10.2 - 1.0 - y)
1440 gcode.addExtrude(160 - x, 50 + n * 10.2 - 1.0 + 5.1 - y)
1441 gcode.addExtrude(30 - x, 50 + n * 10.2 - 1.0 + 5.1 - y)
1442 gcode.addExtrude(30 - x, 50 + n * 10.2 - 1.0 + 10 - y)
1443 gcode.addRetract(15)
1445 gcode.addCmd('M400')
1446 gcode.addCmd('M104 T0 S0')
1447 gcode.addCmd('M104 T1 S0')
1448 self.comm.printGCode(gcode.list())
1449 elif self._wizardState == 7:
1451 n = int(self.textEntry.GetValue()) - 1
1454 x = profile.getMachineSettingFloat('extruder_offset_x1')
1456 profile.putPreference('extruder_offset_x1', '%0.2f' % (x))
1457 self.infoBox.SetAttention(_('Which horizontal line number lays perfect on top of each other? Front most line is zero.'))
1458 self.textEntry.SetValue('10')
1459 self._wizardState = 8
1460 elif self._wizardState == 8:
1462 n = int(self.textEntry.GetValue()) - 1
1465 y = profile.getMachineSettingFloat('extruder_offset_y1')
1467 profile.putPreference('extruder_offset_y1', '%0.2f' % (y))
1468 self.infoBox.SetInfo(_('Calibration finished. Offsets are: %s %s') % (profile.getMachineSettingFloat('extruder_offset_x1'), profile.getMachineSettingFloat('extruder_offset_y1')))
1469 self.infoBox.SetReadyIndicator()
1470 self._wizardState = 8
1472 self.resumeButton.Enable(False)
1474 def mcLog(self, message):
1475 print 'Log:', message
1477 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
1478 if self._wizardState == 1:
1479 if temp[0] >= 210 and temp[1] >= 210:
1480 self._wizardState = 2
1481 wx.CallAfter(self.infoBox.SetAttention, _('Please load both extruders with PLA.'))
1482 wx.CallAfter(self.resumeButton.Enable, True)
1483 wx.CallAfter(self.resumeButton.SetFocus)
1485 def mcStateChange(self, state):
1486 if self.comm is None:
1488 if self.comm.isOperational():
1489 if self._wizardState == 0:
1490 wx.CallAfter(self.infoBox.SetInfo, _('Homing printer and heating up both extruders.'))
1491 self.comm.sendCommand('M105')
1492 self.comm.sendCommand('M104 S220 T0')
1493 self.comm.sendCommand('M104 S220 T1')
1494 self.comm.sendCommand('G28')
1495 self.comm.sendCommand('G1 Z15 F%d' % (profile.getProfileSettingFloat('print_speed') * 60))
1496 self._wizardState = 1
1497 if not self.comm.isPrinting():
1498 if self._wizardState == 3:
1499 self._wizardState = 4
1500 wx.CallAfter(self.infoBox.SetAttention, _('Please measure the distance between the vertical lines in millimeters.'))
1501 wx.CallAfter(self.textEntry.SetValue, '0.0')
1502 wx.CallAfter(self.textEntry.Enable, True)
1503 wx.CallAfter(self.resumeButton.Enable, True)
1504 wx.CallAfter(self.resumeButton.SetFocus)
1505 elif self._wizardState == 6:
1506 self._wizardState = 7
1507 wx.CallAfter(self.infoBox.SetAttention, _('Which vertical line number lays perfect on top of each other? Leftmost line is zero.'))
1508 wx.CallAfter(self.textEntry.SetValue, '10')
1509 wx.CallAfter(self.textEntry.Enable, True)
1510 wx.CallAfter(self.resumeButton.Enable, True)
1511 wx.CallAfter(self.resumeButton.SetFocus)
1513 elif self.comm.isError():
1514 wx.CallAfter(self.infoBox.SetError, _('Failed to establish connection with the printer.'), 'http://wiki.ultimaker.com/Cura:_Connection_problems')
1516 def mcMessage(self, message):
1519 def mcProgress(self, lineNr):
1522 def mcZChange(self, newZ):
1525 class bedLevelWizard(wx.wizard.Wizard):
1527 super(bedLevelWizard, self).__init__(None, -1, _("Bed leveling wizard"))
1529 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
1530 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
1532 self.mainPage = bedLevelWizardMain(self)
1533 self.headOffsetCalibration = None
1535 self.FitToPage(self.mainPage)
1536 self.GetPageAreaSizer().Add(self.mainPage)
1538 self.RunWizard(self.mainPage)
1541 def OnPageChanging(self, e):
1542 e.GetPage().StoreData()
1544 def OnPageChanged(self, e):
1545 if e.GetPage().AllowNext():
1546 self.FindWindowById(wx.ID_FORWARD).Enable()
1548 self.FindWindowById(wx.ID_FORWARD).Disable()
1549 if e.GetPage().AllowBack():
1550 self.FindWindowById(wx.ID_BACKWARD).Enable()
1552 self.FindWindowById(wx.ID_BACKWARD).Disable()
1554 class headOffsetWizard(wx.wizard.Wizard):
1556 super(headOffsetWizard, self).__init__(None, -1, _("Head offset wizard"))
1558 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
1559 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
1561 self.mainPage = headOffsetCalibrationPage(self)
1563 self.FitToPage(self.mainPage)
1564 self.GetPageAreaSizer().Add(self.mainPage)
1566 self.RunWizard(self.mainPage)
1569 def OnPageChanging(self, e):
1570 e.GetPage().StoreData()
1572 def OnPageChanged(self, e):
1573 if e.GetPage().AllowNext():
1574 self.FindWindowById(wx.ID_FORWARD).Enable()
1576 self.FindWindowById(wx.ID_FORWARD).Disable()
1577 if e.GetPage().AllowBack():
1578 self.FindWindowById(wx.ID_BACKWARD).Enable()
1580 self.FindWindowById(wx.ID_BACKWARD).Disable()