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, Filament Diameter, PrintTemperature, Print Speed, Travel Speed, Retract speed, Retract amount
263 ("Simple Metal", 150, 150, 150, 1.75, 208, 40, 70, 30, 1),
264 ("Metal Plus", 250, 250, 250, 1.75, 208, 40, 70, 30, 1),
265 ("Simple Makers Kit", 100, 100, 100, 1.75, 208, 40, 70, 30, 1),
266 (":" + _("Older models"),),
267 ("Original", 130, 130, 130, 2.95, 208, 40, 70, 30, 1),
268 ("Simple Maker's Edition v1", 100, 100, 100, 1.75, 208, 40, 70, 30, 1),
269 ("Simple Maker's Edition v2 (2013 Printrbot Simple)", 100, 100, 100, 1.75, 208, 40, 70, 30, 1),
270 ("Simple Maker's Edition v3 (2014 Printrbot Simple)", 100, 100, 100, 1.75, 208, 40, 70, 30, 1),
271 ("Simple Maker's Edition v4 (Model 1405)", 100, 100, 100, 1.75, 208, 40, 70, 30, 1),
272 ("Jr v1", 150, 100, 80, 1.75, 208, 40, 70, 30, 1),
273 ("Jr v2", 150, 150, 150, 1.75, 208, 40, 70, 30, 1),
274 ("LC v2", 150, 150, 150, 1.75, 208, 40, 70, 30, 1),
275 ("Plus v2", 200, 200, 200, 1.75, 208, 40, 70, 30, 1),
276 ("Plus v2.1", 200, 200, 200, 1.75, 208, 40, 70, 30, 1),
277 ("Plus v2.2 (Model 1404/140422)", 250, 250, 250, 1.75, 208, 40, 70, 30, 1),
278 ("Plus v2.3 (Model 140501)", 250, 250, 250, 1.75, 208, 40, 70, 30, 1),
279 ("Plus v2.4 (Model 140507)", 250, 250, 250, 1.75, 208, 40, 70, 30, 1),
280 ("Go v2 Large", 609, 305, 305, 1.75, 208, 35, 70, 30, 1),
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', '0.5')
306 profile.putProfileSetting('filament_diameter', data[3])
307 profile.putProfileSetting('print_temperature', data[4])
308 profile.putProfileSetting('print_speed', data[5])
309 profile.putProfileSetting('travel_speed', data[6])
310 profile.putProfileSetting('retraction_speed', data[7])
311 profile.putProfileSetting('retraction_amount', data[8])
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 class OtherMachineSelectPage(InfoPage):
322 def __init__(self, parent):
323 super(OtherMachineSelectPage, self).__init__(parent, _("Other machine information"))
324 self.AddText(_("The following pre-defined machine profiles are available"))
325 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."))
327 machines = resources.getDefaultMachineProfiles()
329 for filename in machines:
330 name = os.path.splitext(os.path.basename(filename))[0]
331 item = self.AddRadioButton(name)
332 item.filename = filename
333 item.Bind(wx.EVT_RADIOBUTTON, self.OnProfileSelect)
334 self.options.append(item)
336 item = self.AddRadioButton(_('Custom...'))
338 item.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)
340 def OnProfileSelect(self, e):
341 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().otherMachineInfoPage)
343 def OnOtherSelect(self, e):
344 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().customRepRapInfoPage)
347 for option in self.options:
348 if option.GetValue():
349 profile.loadProfile(option.filename)
350 profile.loadMachineSettings(option.filename)
352 class OtherMachineInfoPage(InfoPage):
353 def __init__(self, parent):
354 super(OtherMachineInfoPage, self).__init__(parent, _("Cura Ready!"))
355 self.AddText(_("Cura is now ready to be used!"))
357 class CustomRepRapInfoPage(InfoPage):
358 def __init__(self, parent):
359 super(CustomRepRapInfoPage, self).__init__(parent, _("Custom RepRap information"))
360 self.AddText(_("RepRap machines can be vastly different, so here you can set your own settings."))
361 self.AddText(_("Be sure to review the default profile before running it on your machine."))
362 self.AddText(_("If you like a default profile for your machine added,\nthen make an issue on github."))
364 self.AddText(_("You will have to manually install Marlin or Sprinter firmware."))
366 self.machineName = self.AddLabelTextCtrl(_("Machine name"), "RepRap")
367 self.machineWidth = self.AddLabelTextCtrl(_("Machine width (mm)"), "80")
368 self.machineDepth = self.AddLabelTextCtrl(_("Machine depth (mm)"), "80")
369 self.machineHeight = self.AddLabelTextCtrl(_("Machine height (mm)"), "55")
370 self.nozzleSize = self.AddLabelTextCtrl(_("Nozzle size (mm)"), "0.5")
371 self.heatedBed = self.AddCheckbox(_("Heated bed"))
372 self.HomeAtCenter = self.AddCheckbox(_("Bed center is 0,0,0 (RoStock)"))
375 profile.putMachineSetting('machine_name', self.machineName.GetValue())
376 profile.putMachineSetting('machine_width', self.machineWidth.GetValue())
377 profile.putMachineSetting('machine_depth', self.machineDepth.GetValue())
378 profile.putMachineSetting('machine_height', self.machineHeight.GetValue())
379 profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
380 profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
381 profile.putMachineSetting('has_heated_bed', str(self.heatedBed.GetValue()))
382 profile.putMachineSetting('machine_center_is_zero', str(self.HomeAtCenter.GetValue()))
383 profile.putMachineSetting('extruder_head_size_min_x', '0')
384 profile.putMachineSetting('extruder_head_size_min_y', '0')
385 profile.putMachineSetting('extruder_head_size_max_x', '0')
386 profile.putMachineSetting('extruder_head_size_max_y', '0')
387 profile.putMachineSetting('extruder_head_size_height', '0')
388 profile.checkAndUpdateMachineName()
390 class MachineSelectPage(InfoPage):
391 def __init__(self, parent):
392 super(MachineSelectPage, self).__init__(parent, _("Select your machine"))
393 self.AddText(_("What kind of machine do you have:"))
395 self.Ultimaker2Radio = self.AddRadioButton("Ultimaker2", style=wx.RB_GROUP)
396 self.Ultimaker2Radio.SetValue(True)
397 self.Ultimaker2Radio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimaker2Select)
398 self.UltimakerRadio = self.AddRadioButton("Ultimaker Original")
399 self.UltimakerRadio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimakerSelect)
400 self.UltimakerOPRadio = self.AddRadioButton("Ultimaker Original+")
401 self.UltimakerOPRadio.Bind(wx.EVT_RADIOBUTTON, self.OnUltimakerOPSelect)
402 self.PrintrbotRadio = self.AddRadioButton("Printrbot")
403 self.PrintrbotRadio.Bind(wx.EVT_RADIOBUTTON, self.OnPrintrbotSelect)
404 self.LulzbotTazRadio = self.AddRadioButton("Lulzbot TAZ")
405 self.LulzbotTazRadio.Bind(wx.EVT_RADIOBUTTON, self.OnLulzbotSelect)
406 self.LulzbotMiniRadio = self.AddRadioButton("Lulzbot Mini")
407 self.LulzbotMiniRadio.Bind(wx.EVT_RADIOBUTTON, self.OnLulzbotSelect)
408 self.OtherRadio = self.AddRadioButton(_("Other (Ex: RepRap, MakerBot, Witbox)"))
409 self.OtherRadio.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)
411 self.AddText(_("The collection of anonymous usage information helps with the continued improvement of Cura."))
412 self.AddText(_("This does NOT submit your models online nor gathers any privacy related information."))
413 self.SubmitUserStats = self.AddCheckbox(_("Submit anonymous usage information:"))
414 self.AddText(_("For full details see: http://wiki.ultimaker.com/Cura:stats"))
415 self.SubmitUserStats.SetValue(True)
417 def OnUltimaker2Select(self, e):
418 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimaker2ReadyPage)
420 def OnUltimakerSelect(self, e):
421 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerSelectParts)
423 def OnUltimakerOPSelect(self, e):
424 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerFirmwareUpgradePage)
426 def OnPrintrbotSelect(self, e):
427 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().printrbotSelectType)
429 def OnLulzbotSelect(self, e):
430 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().lulzbotReadyPage)
432 def OnOtherSelect(self, e):
433 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().otherMachineSelectPage)
436 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimaker2ReadyPage)
440 profile.putProfileSetting('retraction_enable', 'True')
441 if self.Ultimaker2Radio.GetValue():
442 profile.putMachineSetting('machine_width', '230')
443 profile.putMachineSetting('machine_depth', '225')
444 profile.putMachineSetting('machine_height', '205')
445 profile.putMachineSetting('machine_name', 'ultimaker2')
446 profile.putMachineSetting('machine_type', 'ultimaker2')
447 profile.putMachineSetting('machine_center_is_zero', 'False')
448 profile.putMachineSetting('has_heated_bed', 'True')
449 profile.putMachineSetting('gcode_flavor', 'UltiGCode')
450 profile.putMachineSetting('extruder_head_size_min_x', '40.0')
451 profile.putMachineSetting('extruder_head_size_min_y', '10.0')
452 profile.putMachineSetting('extruder_head_size_max_x', '60.0')
453 profile.putMachineSetting('extruder_head_size_max_y', '30.0')
454 profile.putMachineSetting('extruder_head_size_height', '48.0')
455 profile.putProfileSetting('nozzle_size', '0.4')
456 profile.putProfileSetting('fan_full_height', '5.0')
457 profile.putMachineSetting('extruder_offset_x1', '18.0')
458 profile.putMachineSetting('extruder_offset_y1', '0.0')
459 elif self.UltimakerRadio.GetValue():
460 profile.putMachineSetting('machine_width', '205')
461 profile.putMachineSetting('machine_depth', '205')
462 profile.putMachineSetting('machine_height', '200')
463 profile.putMachineSetting('machine_name', 'ultimaker original')
464 profile.putMachineSetting('machine_type', 'ultimaker')
465 profile.putMachineSetting('machine_center_is_zero', 'False')
466 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
467 profile.putProfileSetting('nozzle_size', '0.4')
468 profile.putMachineSetting('extruder_head_size_min_x', '75.0')
469 profile.putMachineSetting('extruder_head_size_min_y', '18.0')
470 profile.putMachineSetting('extruder_head_size_max_x', '18.0')
471 profile.putMachineSetting('extruder_head_size_max_y', '35.0')
472 profile.putMachineSetting('extruder_head_size_height', '55.0')
473 elif self.UltimakerOPRadio.GetValue():
474 profile.putMachineSetting('machine_width', '205')
475 profile.putMachineSetting('machine_depth', '205')
476 profile.putMachineSetting('machine_height', '200')
477 profile.putMachineSetting('machine_name', 'ultimaker original+')
478 profile.putMachineSetting('machine_type', 'ultimaker_plus')
479 profile.putMachineSetting('machine_center_is_zero', 'False')
480 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
481 profile.putProfileSetting('nozzle_size', '0.4')
482 profile.putMachineSetting('extruder_head_size_min_x', '75.0')
483 profile.putMachineSetting('extruder_head_size_min_y', '18.0')
484 profile.putMachineSetting('extruder_head_size_max_x', '18.0')
485 profile.putMachineSetting('extruder_head_size_max_y', '35.0')
486 profile.putMachineSetting('extruder_head_size_height', '55.0')
487 profile.putMachineSetting('has_heated_bed', 'True')
488 profile.putMachineSetting('extruder_amount', '1')
489 profile.putProfileSetting('retraction_enable', 'True')
490 elif self.LulzbotTazRadio.GetValue() or self.LulzbotMiniRadio.GetValue():
491 if self.LulzbotTazRadio.GetValue():
492 profile.putMachineSetting('machine_width', '298')
493 profile.putMachineSetting('machine_depth', '275')
494 profile.putMachineSetting('machine_height', '250')
495 profile.putProfileSetting('nozzle_size', '0.35')
496 profile.putMachineSetting('machine_name', 'Lulzbot TAZ')
498 profile.putMachineSetting('machine_width', '160')
499 profile.putMachineSetting('machine_depth', '160')
500 profile.putMachineSetting('machine_height', '160')
501 profile.putProfileSetting('nozzle_size', '0.5')
502 profile.putMachineSetting('machine_name', 'Lulzbot Mini')
503 profile.putMachineSetting('machine_type', 'Aleph Objects')
504 profile.putMachineSetting('machine_center_is_zero', 'False')
505 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
506 profile.putMachineSetting('has_heated_bed', 'True')
507 profile.putMachineSetting('extruder_head_size_min_x', '0.0')
508 profile.putMachineSetting('extruder_head_size_min_y', '0.0')
509 profile.putMachineSetting('extruder_head_size_max_x', '0.0')
510 profile.putMachineSetting('extruder_head_size_max_y', '0.0')
511 profile.putMachineSetting('extruder_head_size_height', '0.0')
513 profile.putMachineSetting('machine_width', '80')
514 profile.putMachineSetting('machine_depth', '80')
515 profile.putMachineSetting('machine_height', '60')
516 profile.putMachineSetting('machine_name', 'reprap')
517 profile.putMachineSetting('machine_type', 'reprap')
518 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
519 profile.putPreference('startMode', 'Normal')
520 profile.putProfileSetting('nozzle_size', '0.5')
521 profile.checkAndUpdateMachineName()
522 profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)
523 if self.SubmitUserStats.GetValue():
524 profile.putPreference('submit_slice_information', 'True')
526 profile.putPreference('submit_slice_information', 'False')
529 class SelectParts(InfoPage):
530 def __init__(self, parent):
531 super(SelectParts, self).__init__(parent, _("Select upgraded parts you have"))
532 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."))
534 self.springExtruder = self.AddCheckbox(_("Extruder drive upgrade"))
535 self.heatedBedKit = self.AddCheckbox(_("Heated printer bed (kit)"))
536 self.heatedBed = self.AddCheckbox(_("Heated printer bed (self built)"))
537 self.dualExtrusion = self.AddCheckbox(_("Dual extrusion (experimental)"))
539 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."))
540 self.AddText(_("This upgrade can be bought from the Ultimaker webshop\nor found on thingiverse as thing:26094"))
541 self.springExtruder.SetValue(True)
544 profile.putMachineSetting('ultimaker_extruder_upgrade', str(self.springExtruder.GetValue()))
545 if self.heatedBed.GetValue() or self.heatedBedKit.GetValue():
546 profile.putMachineSetting('has_heated_bed', 'True')
548 profile.putMachineSetting('has_heated_bed', 'False')
549 if self.dualExtrusion.GetValue():
550 profile.putMachineSetting('extruder_amount', '2')
551 profile.putMachineSetting('machine_depth', '195')
553 profile.putMachineSetting('extruder_amount', '1')
554 if profile.getMachineSetting('ultimaker_extruder_upgrade') == 'True':
555 profile.putProfileSetting('retraction_enable', 'True')
557 profile.putProfileSetting('retraction_enable', 'False')
560 class UltimakerFirmwareUpgradePage(InfoPage):
561 def __init__(self, parent):
562 super(UltimakerFirmwareUpgradePage, self).__init__(parent, _("Upgrade Ultimaker Firmware"))
563 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."))
564 self.AddHiddenSeperator()
565 self.AddText(_("The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier."))
566 self.AddHiddenSeperator()
567 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."))
568 upgradeButton, skipUpgradeButton = self.AddDualButton('Upgrade to Marlin firmware', 'Skip upgrade')
569 upgradeButton.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)
570 skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick)
571 self.AddHiddenSeperator()
572 if profile.getMachineSetting('machine_type') == 'ultimaker':
573 self.AddText(_("Do not upgrade to this firmware if:"))
574 self.AddText(_("* You have an older machine based on ATMega1280 (Rev 1 machine)"))
575 self.AddText(_("* Build your own heated bed"))
576 self.AddText(_("* Have other changes in the firmware"))
577 # button = self.AddButton('Goto this page for a custom firmware')
578 # button.Bind(wx.EVT_BUTTON, self.OnUrlClick)
583 def OnUpgradeClick(self, e):
584 if firmwareInstall.InstallFirmware():
585 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
587 def OnSkipClick(self, e):
588 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
589 self.GetParent().ShowPage(self.GetNext())
591 def OnUrlClick(self, e):
592 webbrowser.open('http://marlinbuilder.robotfuzz.com/')
594 class UltimakerCheckupPage(InfoPage):
595 def __init__(self, parent):
596 super(UltimakerCheckupPage, self).__init__(parent, _("Ultimaker Checkup"))
598 self.checkBitmap = wx.Bitmap(resources.getPathForImage('checkmark.png'))
599 self.crossBitmap = wx.Bitmap(resources.getPathForImage('cross.png'))
600 self.unknownBitmap = wx.Bitmap(resources.getPathForImage('question.png'))
601 self.endStopNoneBitmap = wx.Bitmap(resources.getPathForImage('endstop_none.png'))
602 self.endStopXMinBitmap = wx.Bitmap(resources.getPathForImage('endstop_xmin.png'))
603 self.endStopXMaxBitmap = wx.Bitmap(resources.getPathForImage('endstop_xmax.png'))
604 self.endStopYMinBitmap = wx.Bitmap(resources.getPathForImage('endstop_ymin.png'))
605 self.endStopYMaxBitmap = wx.Bitmap(resources.getPathForImage('endstop_ymax.png'))
606 self.endStopZMinBitmap = wx.Bitmap(resources.getPathForImage('endstop_zmin.png'))
607 self.endStopZMaxBitmap = wx.Bitmap(resources.getPathForImage('endstop_zmax.png'))
610 _("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."))
611 b1, b2 = self.AddDualButton(_("Run checks"), _("Skip checks"))
612 b1.Bind(wx.EVT_BUTTON, self.OnCheckClick)
613 b2.Bind(wx.EVT_BUTTON, self.OnSkipClick)
615 self.commState = self.AddCheckmark(_("Communication:"), self.unknownBitmap)
616 self.tempState = self.AddCheckmark(_("Temperature:"), self.unknownBitmap)
617 self.stopState = self.AddCheckmark(_("Endstops:"), self.unknownBitmap)
619 self.infoBox = self.AddInfoBox()
620 self.machineState = self.AddText("")
621 self.temperatureLabel = self.AddText("")
622 self.errorLogButton = self.AddButton(_("Show error log"))
623 self.errorLogButton.Show(False)
625 self.endstopBitmap = self.AddBitmap(self.endStopNoneBitmap)
627 self.xMinStop = False
628 self.xMaxStop = False
629 self.yMinStop = False
630 self.yMaxStop = False
631 self.zMinStop = False
632 self.zMaxStop = False
634 self.Bind(wx.EVT_BUTTON, self.OnErrorLog, self.errorLogButton)
637 if self.comm is not None:
641 self.endstopBitmap.Show(False)
644 def OnSkipClick(self, e):
645 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
646 self.GetParent().ShowPage(self.GetNext())
648 def OnCheckClick(self, e=None):
649 self.errorLogButton.Show(False)
650 if self.comm is not None:
654 wx.CallAfter(self.OnCheckClick)
656 self.infoBox.SetBusy(_("Connecting to machine."))
657 self.commState.SetBitmap(self.unknownBitmap)
658 self.tempState.SetBitmap(self.unknownBitmap)
659 self.stopState.SetBitmap(self.unknownBitmap)
660 self.checkupState = 0
661 self.checkExtruderNr = 0
662 self.comm = machineCom.MachineCom(callbackObject=self)
664 def OnErrorLog(self, e):
665 printWindow.LogWindow('\n'.join(self.comm.getLog()))
667 def mcLog(self, message):
670 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
671 if not self.comm.isOperational():
673 if self.checkupState == 0:
674 self.tempCheckTimeout = 20
675 if temp[self.checkExtruderNr] > 70:
676 self.checkupState = 1
677 wx.CallAfter(self.infoBox.SetInfo, _("Cooldown before temperature check."))
678 self.comm.sendCommand("M104 S0 T%d" % (self.checkExtruderNr))
679 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
681 self.startTemp = temp[self.checkExtruderNr]
682 self.checkupState = 2
683 wx.CallAfter(self.infoBox.SetInfo, _("Checking the heater and temperature sensor."))
684 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
685 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
686 elif self.checkupState == 1:
687 if temp[self.checkExtruderNr] < 60:
688 self.startTemp = temp[self.checkExtruderNr]
689 self.checkupState = 2
690 wx.CallAfter(self.infoBox.SetInfo, _("Checking the heater and temperature sensor."))
691 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
692 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
693 elif self.checkupState == 2:
694 #print "WARNING, TEMPERATURE TEST DISABLED FOR TESTING!"
695 if temp[self.checkExtruderNr] > self.startTemp + 40:
696 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
697 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
698 if self.checkExtruderNr < int(profile.getMachineSetting('extruder_amount')):
699 self.checkExtruderNr = 0
700 self.checkupState = 3
701 wx.CallAfter(self.infoBox.SetAttention, _("Please make sure none of the endstops are pressed."))
702 wx.CallAfter(self.endstopBitmap.Show, True)
703 wx.CallAfter(self.Layout)
704 self.comm.sendCommand('M119')
705 wx.CallAfter(self.tempState.SetBitmap, self.checkBitmap)
707 self.checkupState = 0
708 self.checkExtruderNr += 1
710 self.tempCheckTimeout -= 1
711 if self.tempCheckTimeout < 1:
712 self.checkupState = -1
713 wx.CallAfter(self.tempState.SetBitmap, self.crossBitmap)
714 wx.CallAfter(self.infoBox.SetError, _("Temperature measurement FAILED!"), 'http://wiki.ultimaker.com/Cura:_Temperature_measurement_problems')
715 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
716 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
717 elif self.checkupState >= 3 and self.checkupState < 10:
718 self.comm.sendCommand('M119')
719 wx.CallAfter(self.temperatureLabel.SetLabel, _("Head temperature: %d") % (temp[self.checkExtruderNr]))
721 def mcStateChange(self, state):
722 if self.comm is None:
724 if self.comm.isOperational():
725 wx.CallAfter(self.commState.SetBitmap, self.checkBitmap)
726 wx.CallAfter(self.machineState.SetLabel, _("Communication State: %s") % (self.comm.getStateString()))
727 elif self.comm.isError():
728 wx.CallAfter(self.commState.SetBitmap, self.crossBitmap)
729 wx.CallAfter(self.infoBox.SetError, _("Failed to establish connection with the printer."), 'http://wiki.ultimaker.com/Cura:_Connection_problems')
730 wx.CallAfter(self.endstopBitmap.Show, False)
731 wx.CallAfter(self.machineState.SetLabel, '%s' % (self.comm.getErrorString()))
732 wx.CallAfter(self.errorLogButton.Show, True)
733 wx.CallAfter(self.Layout)
735 wx.CallAfter(self.machineState.SetLabel, _("Communication State: %s") % (self.comm.getStateString()))
737 def mcMessage(self, message):
738 if self.checkupState >= 3 and self.checkupState < 10 and ('_min' in message or '_max' in message):
739 for data in message.split(' '):
741 tag, value = data.split(':', 1)
743 self.xMinStop = (value == 'H' or value == 'TRIGGERED')
745 self.xMaxStop = (value == 'H' or value == 'TRIGGERED')
747 self.yMinStop = (value == 'H' or value == 'TRIGGERED')
749 self.yMaxStop = (value == 'H' or value == 'TRIGGERED')
751 self.zMinStop = (value == 'H' or value == 'TRIGGERED')
753 self.zMaxStop = (value == 'H' or value == 'TRIGGERED')
755 tag, value = map(str.strip, message.split(':', 1))
757 self.xMinStop = (value == 'H' or value == 'TRIGGERED')
759 self.xMaxStop = (value == 'H' or value == 'TRIGGERED')
761 self.yMinStop = (value == 'H' or value == 'TRIGGERED')
763 self.yMaxStop = (value == 'H' or value == 'TRIGGERED')
765 self.zMinStop = (value == 'H' or value == 'TRIGGERED')
767 self.zMaxStop = (value == 'H' or value == 'TRIGGERED')
768 if 'z_max' in message:
769 self.comm.sendCommand('M119')
771 if self.checkupState == 3:
772 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
773 if profile.getMachineSetting('machine_type') == 'ultimaker_plus':
774 self.checkupState = 5
775 wx.CallAfter(self.infoBox.SetAttention, _("Please press the left X endstop."))
776 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMinBitmap)
778 self.checkupState = 4
779 wx.CallAfter(self.infoBox.SetAttention, _("Please press the right X endstop."))
780 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMaxBitmap)
781 elif self.checkupState == 4:
782 if not self.xMinStop and self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
783 self.checkupState = 5
784 wx.CallAfter(self.infoBox.SetAttention, _("Please press the left X endstop."))
785 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMinBitmap)
786 elif self.checkupState == 5:
787 if self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
788 self.checkupState = 6
789 wx.CallAfter(self.infoBox.SetAttention, _("Please press the front Y endstop."))
790 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopYMinBitmap)
791 elif self.checkupState == 6:
792 if not self.xMinStop and not self.xMaxStop and self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
793 if profile.getMachineSetting('machine_type') == 'ultimaker_plus':
794 self.checkupState = 8
795 wx.CallAfter(self.infoBox.SetAttention, _("Please press the top Z endstop."))
796 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMinBitmap)
798 self.checkupState = 7
799 wx.CallAfter(self.infoBox.SetAttention, _("Please press the back Y endstop."))
800 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopYMaxBitmap)
801 elif self.checkupState == 7:
802 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and self.yMaxStop and not self.zMinStop and not self.zMaxStop:
803 self.checkupState = 8
804 wx.CallAfter(self.infoBox.SetAttention, _("Please press the top Z endstop."))
805 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMinBitmap)
806 elif self.checkupState == 8:
807 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and self.zMinStop and not self.zMaxStop:
808 if profile.getMachineSetting('machine_type') == 'ultimaker_plus':
809 self.checkupState = 10
811 wx.CallAfter(self.infoBox.SetInfo, _("Checkup finished"))
812 wx.CallAfter(self.infoBox.SetReadyIndicator)
813 wx.CallAfter(self.endstopBitmap.Show, False)
814 wx.CallAfter(self.stopState.SetBitmap, self.checkBitmap)
815 wx.CallAfter(self.OnSkipClick, None)
817 self.checkupState = 9
818 wx.CallAfter(self.infoBox.SetAttention, _("Please press the bottom Z endstop."))
819 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMaxBitmap)
820 elif self.checkupState == 9:
821 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and self.zMaxStop:
822 self.checkupState = 10
824 wx.CallAfter(self.infoBox.SetInfo, _("Checkup finished"))
825 wx.CallAfter(self.infoBox.SetReadyIndicator)
826 wx.CallAfter(self.endstopBitmap.Show, False)
827 wx.CallAfter(self.stopState.SetBitmap, self.checkBitmap)
828 wx.CallAfter(self.OnSkipClick, None)
830 def mcProgress(self, lineNr):
833 def mcZChange(self, newZ):
837 class UltimakerCalibrationPage(InfoPage):
838 def __init__(self, parent):
839 super(UltimakerCalibrationPage, self).__init__(parent, _("Ultimaker Calibration"))
841 self.AddText("Your Ultimaker requires some calibration.")
842 self.AddText("This calibration is needed for a proper extrusion amount.")
844 self.AddText("The following values are needed:")
845 self.AddText("* Diameter of filament")
846 self.AddText("* Number of steps per mm of filament extrusion")
848 self.AddText("The better you have calibrated these values, the better your prints\nwill become.")
850 self.AddText("First we need the diameter of your filament:")
851 self.filamentDiameter = self.AddTextCtrl(profile.getProfileSetting('filament_diameter'))
853 "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.")
854 self.AddText("Note: This value can be changed later at any time.")
857 profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue())
860 class UltimakerCalibrateStepsPerEPage(InfoPage):
861 def __init__(self, parent):
862 super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, _("Ultimaker Calibration"))
864 #if profile.getMachineSetting('steps_per_e') == '0':
865 # profile.putMachineSetting('steps_per_e', '865.888')
867 self.AddText(_("Calibrating the Steps Per E requires some manual actions."))
868 self.AddText(_("First remove any filament from your machine."))
869 self.AddText(_("Next put in your filament so the tip is aligned with the\ntop of the extruder drive."))
870 self.AddText(_("We'll push the filament 100mm"))
871 self.extrudeButton = self.AddButton(_("Extrude 100mm filament"))
872 self.AddText(_("Now measure the amount of extruded filament:\n(this can be more or less then 100mm)"))
873 self.lengthInput, self.saveLengthButton = self.AddTextCtrlButton("100", _("Save"))
874 self.AddText(_("This results in the following steps per E:"))
875 self.stepsPerEInput = self.AddTextCtrl(profile.getMachineSetting('steps_per_e'))
876 self.AddText(_("You can repeat these steps to get better calibration."))
879 _("If you still have filament in your printer which needs\nheat to remove, press the heat up button below:"))
880 self.heatButton = self.AddButton(_("Heatup for filament removal"))
882 self.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick)
883 self.extrudeButton.Bind(wx.EVT_BUTTON, self.OnExtrudeClick)
884 self.heatButton.Bind(wx.EVT_BUTTON, self.OnHeatClick)
886 def OnSaveLengthClick(self, e):
887 currentEValue = float(self.stepsPerEInput.GetValue())
888 realExtrudeLength = float(self.lengthInput.GetValue())
889 newEValue = currentEValue * 100 / realExtrudeLength
890 self.stepsPerEInput.SetValue(str(newEValue))
891 self.lengthInput.SetValue("100")
893 def OnExtrudeClick(self, e):
894 t = threading.Thread(target=self.OnExtrudeRun)
898 def OnExtrudeRun(self):
899 self.heatButton.Enable(False)
900 self.extrudeButton.Enable(False)
901 currentEValue = float(self.stepsPerEInput.GetValue())
902 self.comm = machineCom.MachineCom()
903 if not self.comm.isOpen():
905 _("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable"),
906 'Printer error', wx.OK | wx.ICON_INFORMATION)
907 self.heatButton.Enable(True)
908 self.extrudeButton.Enable(True)
911 line = self.comm.readline()
916 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
919 self.sendGCommand('M302') #Disable cold extrusion protection
920 self.sendGCommand("M92 E%f" % (currentEValue))
921 self.sendGCommand("G92 E0")
922 self.sendGCommand("G1 E100 F600")
925 self.extrudeButton.Enable()
926 self.heatButton.Enable()
928 def OnHeatClick(self, e):
929 t = threading.Thread(target=self.OnHeatRun)
934 self.heatButton.Enable(False)
935 self.extrudeButton.Enable(False)
936 self.comm = machineCom.MachineCom()
937 if not self.comm.isOpen():
939 _("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable"),
940 'Printer error', wx.OK | wx.ICON_INFORMATION)
941 self.heatButton.Enable(True)
942 self.extrudeButton.Enable(True)
945 line = self.comm.readline()
947 self.heatButton.Enable(True)
948 self.extrudeButton.Enable(True)
952 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
955 self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out.
957 'Wait till you can remove the filament from the machine, and press OK.\n(Temperature is set to 200C)',
958 'Machine heatup', wx.OK | wx.ICON_INFORMATION)
959 self.sendGCommand('M104 S0')
962 self.heatButton.Enable(True)
963 self.extrudeButton.Enable(True)
965 def sendGCommand(self, cmd):
966 self.comm.sendCommand(cmd) #Disable cold extrusion protection
968 line = self.comm.readline()
971 if line.startswith('ok'):
975 profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue())
977 class Ultimaker2ReadyPage(InfoPage):
978 def __init__(self, parent):
979 super(Ultimaker2ReadyPage, self).__init__(parent, _("Ultimaker2"))
980 self.AddText(_('Congratulations on your the purchase of your brand new Ultimaker2.'))
981 self.AddText(_('Cura is now ready to be used with your Ultimaker2.'))
984 class LulzbotReadyPage(InfoPage):
985 def __init__(self, parent):
986 super(LulzbotReadyPage, self).__init__(parent, _("Lulzbot TAZ/Mini"))
987 self.AddText(_('Cura is now ready to be used with your Lulzbot.'))
990 class ConfigWizard(wx.wizard.Wizard):
991 def __init__(self, addNew = False):
992 super(ConfigWizard, self).__init__(None, -1, _("Configuration Wizard"))
994 self._old_machine_index = int(profile.getPreferenceFloat('active_machine'))
996 profile.setActiveMachine(profile.getMachineCount())
998 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
999 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
1000 self.Bind(wx.wizard.EVT_WIZARD_CANCEL, self.OnCancel)
1002 self.firstInfoPage = FirstInfoPage(self, addNew)
1003 self.machineSelectPage = MachineSelectPage(self)
1004 self.ultimakerSelectParts = SelectParts(self)
1005 self.ultimakerFirmwareUpgradePage = UltimakerFirmwareUpgradePage(self)
1006 self.ultimakerCheckupPage = UltimakerCheckupPage(self)
1007 self.ultimakerCalibrationPage = UltimakerCalibrationPage(self)
1008 self.ultimakerCalibrateStepsPerEPage = UltimakerCalibrateStepsPerEPage(self)
1009 self.bedLevelPage = bedLevelWizardMain(self)
1010 self.headOffsetCalibration = headOffsetCalibrationPage(self)
1011 self.printrbotSelectType = PrintrbotPage(self)
1012 self.otherMachineSelectPage = OtherMachineSelectPage(self)
1013 self.customRepRapInfoPage = CustomRepRapInfoPage(self)
1014 self.otherMachineInfoPage = OtherMachineInfoPage(self)
1016 self.ultimaker2ReadyPage = Ultimaker2ReadyPage(self)
1017 self.lulzbotReadyPage = LulzbotReadyPage(self)
1019 wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage)
1020 #wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimaker2ReadyPage)
1021 wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerSelectParts)
1022 wx.wizard.WizardPageSimple.Chain(self.ultimakerSelectParts, self.ultimakerFirmwareUpgradePage)
1023 wx.wizard.WizardPageSimple.Chain(self.ultimakerFirmwareUpgradePage, self.ultimakerCheckupPage)
1024 wx.wizard.WizardPageSimple.Chain(self.ultimakerCheckupPage, self.bedLevelPage)
1025 #wx.wizard.WizardPageSimple.Chain(self.ultimakerCalibrationPage, self.ultimakerCalibrateStepsPerEPage)
1026 wx.wizard.WizardPageSimple.Chain(self.printrbotSelectType, self.otherMachineInfoPage)
1027 wx.wizard.WizardPageSimple.Chain(self.otherMachineSelectPage, self.customRepRapInfoPage)
1029 self.FitToPage(self.firstInfoPage)
1030 self.GetPageAreaSizer().Add(self.firstInfoPage)
1032 self.RunWizard(self.firstInfoPage)
1035 def OnPageChanging(self, e):
1036 e.GetPage().StoreData()
1038 def OnPageChanged(self, e):
1039 if e.GetPage().AllowNext():
1040 self.FindWindowById(wx.ID_FORWARD).Enable()
1042 self.FindWindowById(wx.ID_FORWARD).Disable()
1043 if e.GetPage().AllowBack():
1044 self.FindWindowById(wx.ID_BACKWARD).Enable()
1046 self.FindWindowById(wx.ID_BACKWARD).Disable()
1048 def OnCancel(self, e):
1049 profile.setActiveMachine(self._old_machine_index)
1051 class bedLevelWizardMain(InfoPage):
1052 def __init__(self, parent):
1053 super(bedLevelWizardMain, self).__init__(parent, _("Bed leveling wizard"))
1055 self.AddText(_('This wizard will help you in leveling your printer bed'))
1057 self.AddText(_('It will do the following steps'))
1058 self.AddText(_('* Move the printer head to each corner'))
1059 self.AddText(_(' and let you adjust the height of the bed to the nozzle'))
1060 self.AddText(_('* Print a line around the bed to check if it is level'))
1063 self.connectButton = self.AddButton(_('Connect to printer'))
1066 self.infoBox = self.AddInfoBox()
1067 self.resumeButton = self.AddButton(_('Resume'))
1068 self.upButton, self.downButton = self.AddDualButton(_('Up 0.2mm'), _('Down 0.2mm'))
1069 self.upButton2, self.downButton2 = self.AddDualButton(_('Up 10mm'), _('Down 10mm'))
1070 self.resumeButton.Enable(False)
1072 self.upButton.Enable(False)
1073 self.downButton.Enable(False)
1074 self.upButton2.Enable(False)
1075 self.downButton2.Enable(False)
1077 self.Bind(wx.EVT_BUTTON, self.OnConnect, self.connectButton)
1078 self.Bind(wx.EVT_BUTTON, self.OnResume, self.resumeButton)
1079 self.Bind(wx.EVT_BUTTON, self.OnBedUp, self.upButton)
1080 self.Bind(wx.EVT_BUTTON, self.OnBedDown, self.downButton)
1081 self.Bind(wx.EVT_BUTTON, self.OnBedUp2, self.upButton2)
1082 self.Bind(wx.EVT_BUTTON, self.OnBedDown2, self.downButton2)
1084 def OnConnect(self, e = None):
1085 if self.comm is not None:
1089 wx.CallAfter(self.OnConnect)
1091 self.connectButton.Enable(False)
1092 self.comm = machineCom.MachineCom(callbackObject=self)
1093 self.infoBox.SetBusy(_('Connecting to machine.'))
1094 self._wizardState = 0
1096 def OnBedUp(self, e):
1097 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1098 self.comm.sendCommand('G92 Z10')
1099 self.comm.sendCommand('G1 Z9.8 F%d' % (feedZ))
1100 self.comm.sendCommand('M400')
1102 def OnBedDown(self, e):
1103 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1104 self.comm.sendCommand('G92 Z10')
1105 self.comm.sendCommand('G1 Z10.2 F%d' % (feedZ))
1106 self.comm.sendCommand('M400')
1108 def OnBedUp2(self, e):
1109 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1110 self.comm.sendCommand('G92 Z10')
1111 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1112 self.comm.sendCommand('M400')
1114 def OnBedDown2(self, e):
1115 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1116 self.comm.sendCommand('G92 Z10')
1117 self.comm.sendCommand('G1 Z20 F%d' % (feedZ))
1118 self.comm.sendCommand('M400')
1120 def AllowNext(self):
1121 if self.GetParent().headOffsetCalibration is not None and int(profile.getMachineSetting('extruder_amount')) > 1:
1122 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().headOffsetCalibration)
1125 def OnResume(self, e):
1126 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1127 feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
1128 if self._wizardState == -1:
1129 wx.CallAfter(self.infoBox.SetInfo, _('Homing printer...'))
1130 wx.CallAfter(self.upButton.Enable, False)
1131 wx.CallAfter(self.downButton.Enable, False)
1132 wx.CallAfter(self.upButton2.Enable, False)
1133 wx.CallAfter(self.downButton2.Enable, False)
1134 self.comm.sendCommand('M105')
1135 self.comm.sendCommand('G28')
1136 self._wizardState = 1
1137 elif self._wizardState == 2:
1138 if profile.getMachineSetting('has_heated_bed') == 'True':
1139 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to back center...'))
1140 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1141 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') / 2.0, profile.getMachineSettingFloat('machine_depth'), feedTravel))
1142 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1143 self.comm.sendCommand('M400')
1144 self._wizardState = 3
1146 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to back left corner...'))
1147 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1148 self.comm.sendCommand('G1 X%d Y%d F%d' % (0, profile.getMachineSettingFloat('machine_depth'), feedTravel))
1149 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1150 self.comm.sendCommand('M400')
1151 self._wizardState = 3
1152 elif self._wizardState == 4:
1153 if profile.getMachineSetting('has_heated_bed') == 'True':
1154 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to front right corner...'))
1155 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1156 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, 5, feedTravel))
1157 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1158 self.comm.sendCommand('M400')
1159 self._wizardState = 7
1161 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to back right corner...'))
1162 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1163 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, profile.getMachineSettingFloat('machine_depth') - 25, feedTravel))
1164 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1165 self.comm.sendCommand('M400')
1166 self._wizardState = 5
1167 elif self._wizardState == 6:
1168 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to front right corner...'))
1169 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1170 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, 20, feedTravel))
1171 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1172 self.comm.sendCommand('M400')
1173 self._wizardState = 7
1174 elif self._wizardState == 8:
1175 wx.CallAfter(self.infoBox.SetBusy, _('Heating up printer...'))
1176 self.comm.sendCommand('G1 Z15 F%d' % (feedZ))
1177 self.comm.sendCommand('M104 S%d' % (profile.getProfileSettingFloat('print_temperature')))
1178 self.comm.sendCommand('G1 X%d Y%d F%d' % (0, 0, feedTravel))
1179 self._wizardState = 9
1180 elif self._wizardState == 10:
1181 self._wizardState = 11
1182 wx.CallAfter(self.infoBox.SetInfo, _('Printing a square on the printer bed at 0.3mm height.'))
1183 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1184 feedPrint = profile.getProfileSettingFloat('print_speed') * 60
1185 feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
1186 w = profile.getMachineSettingFloat('machine_width') - 10
1187 d = profile.getMachineSettingFloat('machine_depth')
1188 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
1189 filamentArea = math.pi * filamentRadius * filamentRadius
1190 ePerMM = (profile.calculateEdgeWidth() * 0.3) / filamentArea
1194 'G1 Z2 F%d' % (feedZ),
1196 'G1 X%d Y%d F%d' % (5, 5, feedTravel),
1197 'G1 Z0.3 F%d' % (feedZ)]
1199 gcodeList.append('G1 E%f F%d' % (eValue, profile.getProfileSettingFloat('retraction_speed') * 60))
1201 for i in xrange(0, 3):
1202 dist = 5.0 + 0.4 * float(i)
1203 eValue += (d - 2.0*dist) * ePerMM
1204 gcodeList.append('G1 X%f Y%f E%f F%d' % (dist, d - dist, eValue, feedPrint))
1205 eValue += (w - 2.0*dist) * ePerMM
1206 gcodeList.append('G1 X%f Y%f E%f F%d' % (w - dist, d - dist, eValue, feedPrint))
1207 eValue += (d - 2.0*dist) * ePerMM
1208 gcodeList.append('G1 X%f Y%f E%f F%d' % (w - dist, dist, eValue, feedPrint))
1209 eValue += (w - 2.0*dist) * ePerMM
1210 gcodeList.append('G1 X%f Y%f E%f F%d' % (dist, dist, eValue, feedPrint))
1212 gcodeList.append('M400')
1213 self.comm.printGCode(gcodeList)
1214 self.resumeButton.Enable(False)
1216 def mcLog(self, message):
1217 print 'Log:', message
1219 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
1220 if self._wizardState == 1:
1221 self._wizardState = 2
1222 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the front left screw of your printer bed\nSo the nozzle just hits the bed.'))
1223 wx.CallAfter(self.resumeButton.Enable, True)
1224 elif self._wizardState == 3:
1225 self._wizardState = 4
1226 if profile.getMachineSetting('has_heated_bed') == 'True':
1227 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the back screw of your printer bed\nSo the nozzle just hits the bed.'))
1229 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the back left screw of your printer bed\nSo the nozzle just hits the bed.'))
1230 wx.CallAfter(self.resumeButton.Enable, True)
1231 elif self._wizardState == 5:
1232 self._wizardState = 6
1233 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the back right screw of your printer bed\nSo the nozzle just hits the bed.'))
1234 wx.CallAfter(self.resumeButton.Enable, True)
1235 elif self._wizardState == 7:
1236 self._wizardState = 8
1237 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the front right screw of your printer bed\nSo the nozzle just hits the bed.'))
1238 wx.CallAfter(self.resumeButton.Enable, True)
1239 elif self._wizardState == 9:
1240 if temp[0] < profile.getProfileSettingFloat('print_temperature') - 5:
1241 wx.CallAfter(self.infoBox.SetInfo, _('Heating up printer: %d/%d') % (temp[0], profile.getProfileSettingFloat('print_temperature')))
1243 wx.CallAfter(self.infoBox.SetAttention, _('The printer is hot now. Please insert some PLA filament into the printer.'))
1244 wx.CallAfter(self.resumeButton.Enable, True)
1245 self._wizardState = 10
1247 def mcStateChange(self, state):
1248 if self.comm is None:
1250 if self.comm.isOperational():
1251 if self._wizardState == 0:
1252 wx.CallAfter(self.infoBox.SetAttention, _('Use the up/down buttons to move the bed and adjust your Z endstop.'))
1253 wx.CallAfter(self.upButton.Enable, True)
1254 wx.CallAfter(self.downButton.Enable, True)
1255 wx.CallAfter(self.upButton2.Enable, True)
1256 wx.CallAfter(self.downButton2.Enable, True)
1257 wx.CallAfter(self.resumeButton.Enable, True)
1258 self._wizardState = -1
1259 elif self._wizardState == 11 and not self.comm.isPrinting():
1260 self.comm.sendCommand('G1 Z15 F%d' % (profile.getProfileSettingFloat('print_speed') * 60))
1261 self.comm.sendCommand('G92 E0')
1262 self.comm.sendCommand('G1 E-10 F%d' % (profile.getProfileSettingFloat('retraction_speed') * 60))
1263 self.comm.sendCommand('M104 S0')
1264 wx.CallAfter(self.infoBox.SetInfo, _('Calibration finished.\nThe squares on the bed should slightly touch each other.'))
1265 wx.CallAfter(self.infoBox.SetReadyIndicator)
1266 wx.CallAfter(self.GetParent().FindWindowById(wx.ID_FORWARD).Enable)
1267 wx.CallAfter(self.connectButton.Enable, True)
1268 self._wizardState = 12
1269 elif self.comm.isError():
1270 wx.CallAfter(self.infoBox.SetError, _('Failed to establish connection with the printer.'), 'http://wiki.ultimaker.com/Cura:_Connection_problems')
1272 def mcMessage(self, message):
1275 def mcProgress(self, lineNr):
1278 def mcZChange(self, newZ):
1281 class headOffsetCalibrationPage(InfoPage):
1282 def __init__(self, parent):
1283 super(headOffsetCalibrationPage, self).__init__(parent, "Printer head offset calibration")
1285 self.AddText(_('This wizard will help you in calibrating the printer head offsets of your dual extrusion machine'))
1288 self.connectButton = self.AddButton(_('Connect to printer'))
1291 self.infoBox = self.AddInfoBox()
1292 self.textEntry = self.AddTextCtrl('')
1293 self.textEntry.Enable(False)
1294 self.resumeButton = self.AddButton(_('Resume'))
1295 self.resumeButton.Enable(False)
1297 self.Bind(wx.EVT_BUTTON, self.OnConnect, self.connectButton)
1298 self.Bind(wx.EVT_BUTTON, self.OnResume, self.resumeButton)
1300 def AllowBack(self):
1303 def OnConnect(self, e = None):
1304 if self.comm is not None:
1308 wx.CallAfter(self.OnConnect)
1310 self.connectButton.Enable(False)
1311 self.comm = machineCom.MachineCom(callbackObject=self)
1312 self.infoBox.SetBusy(_('Connecting to machine.'))
1313 self._wizardState = 0
1315 def OnResume(self, e):
1316 if self._wizardState == 2:
1317 self._wizardState = 3
1318 wx.CallAfter(self.infoBox.SetBusy, _('Printing initial calibration cross'))
1320 w = profile.getMachineSettingFloat('machine_width')
1321 d = profile.getMachineSettingFloat('machine_depth')
1323 gcode = gcodeGenerator.gcodeGenerator()
1324 gcode.setExtrusionRate(profile.getProfileSettingFloat('nozzle_size') * 1.5, 0.2)
1325 gcode.setPrintSpeed(profile.getProfileSettingFloat('bottom_layer_speed'))
1332 gcode.addMove(w/2, 5)
1333 gcode.addMove(z=0.2)
1335 gcode.addExtrude(w/2, d-5.0)
1337 gcode.addMove(5, d/2)
1339 gcode.addExtrude(w-5.0, d/2)
1340 gcode.addRetract(15)
1343 gcode.addMove(w/2, 5)
1345 gcode.addExtrude(w/2, d-5.0)
1347 gcode.addMove(5, d/2)
1349 gcode.addExtrude(w-5.0, d/2)
1350 gcode.addRetract(15)
1355 gcode.addCmd('M400')
1357 self.comm.printGCode(gcode.list())
1358 self.resumeButton.Enable(False)
1359 elif self._wizardState == 4:
1361 float(self.textEntry.GetValue())
1364 profile.putPreference('extruder_offset_x1', self.textEntry.GetValue())
1365 self._wizardState = 5
1366 self.infoBox.SetAttention(_('Please measure the distance between the horizontal lines in millimeters.'))
1367 self.textEntry.SetValue('0.0')
1368 self.textEntry.Enable(True)
1369 elif self._wizardState == 5:
1371 float(self.textEntry.GetValue())
1374 profile.putPreference('extruder_offset_y1', self.textEntry.GetValue())
1375 self._wizardState = 6
1376 self.infoBox.SetBusy(_('Printing the fine calibration lines.'))
1377 self.textEntry.SetValue('')
1378 self.textEntry.Enable(False)
1379 self.resumeButton.Enable(False)
1381 x = profile.getMachineSettingFloat('extruder_offset_x1')
1382 y = profile.getMachineSettingFloat('extruder_offset_y1')
1383 gcode = gcodeGenerator.gcodeGenerator()
1384 gcode.setExtrusionRate(profile.getProfileSettingFloat('nozzle_size') * 1.5, 0.2)
1385 gcode.setPrintSpeed(25)
1388 gcode.addMove(50, 40, 0.2)
1390 for n in xrange(0, 10):
1391 gcode.addExtrude(50 + n * 10, 150)
1392 gcode.addExtrude(50 + n * 10 + 5, 150)
1393 gcode.addExtrude(50 + n * 10 + 5, 40)
1394 gcode.addExtrude(50 + n * 10 + 10, 40)
1395 gcode.addMove(40, 50)
1396 for n in xrange(0, 10):
1397 gcode.addExtrude(150, 50 + n * 10)
1398 gcode.addExtrude(150, 50 + n * 10 + 5)
1399 gcode.addExtrude(40, 50 + n * 10 + 5)
1400 gcode.addExtrude(40, 50 + n * 10 + 10)
1401 gcode.addRetract(15)
1404 gcode.addMove(50 - x, 30 - y, 0.2)
1406 for n in xrange(0, 10):
1407 gcode.addExtrude(50 + n * 10.2 - 1.0 - x, 140 - y)
1408 gcode.addExtrude(50 + n * 10.2 - 1.0 + 5.1 - x, 140 - y)
1409 gcode.addExtrude(50 + n * 10.2 - 1.0 + 5.1 - x, 30 - y)
1410 gcode.addExtrude(50 + n * 10.2 - 1.0 + 10 - x, 30 - y)
1411 gcode.addMove(30 - x, 50 - y, 0.2)
1412 for n in xrange(0, 10):
1413 gcode.addExtrude(160 - x, 50 + n * 10.2 - 1.0 - y)
1414 gcode.addExtrude(160 - x, 50 + n * 10.2 - 1.0 + 5.1 - y)
1415 gcode.addExtrude(30 - x, 50 + n * 10.2 - 1.0 + 5.1 - y)
1416 gcode.addExtrude(30 - x, 50 + n * 10.2 - 1.0 + 10 - y)
1417 gcode.addRetract(15)
1419 gcode.addCmd('M400')
1420 gcode.addCmd('M104 T0 S0')
1421 gcode.addCmd('M104 T1 S0')
1422 self.comm.printGCode(gcode.list())
1423 elif self._wizardState == 7:
1425 n = int(self.textEntry.GetValue()) - 1
1428 x = profile.getMachineSettingFloat('extruder_offset_x1')
1430 profile.putPreference('extruder_offset_x1', '%0.2f' % (x))
1431 self.infoBox.SetAttention(_('Which horizontal line number lays perfect on top of each other? Front most line is zero.'))
1432 self.textEntry.SetValue('10')
1433 self._wizardState = 8
1434 elif self._wizardState == 8:
1436 n = int(self.textEntry.GetValue()) - 1
1439 y = profile.getMachineSettingFloat('extruder_offset_y1')
1441 profile.putPreference('extruder_offset_y1', '%0.2f' % (y))
1442 self.infoBox.SetInfo(_('Calibration finished. Offsets are: %s %s') % (profile.getMachineSettingFloat('extruder_offset_x1'), profile.getMachineSettingFloat('extruder_offset_y1')))
1443 self.infoBox.SetReadyIndicator()
1444 self._wizardState = 8
1446 self.resumeButton.Enable(False)
1448 def mcLog(self, message):
1449 print 'Log:', message
1451 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
1452 if self._wizardState == 1:
1453 if temp[0] >= 210 and temp[1] >= 210:
1454 self._wizardState = 2
1455 wx.CallAfter(self.infoBox.SetAttention, _('Please load both extruders with PLA.'))
1456 wx.CallAfter(self.resumeButton.Enable, True)
1457 wx.CallAfter(self.resumeButton.SetFocus)
1459 def mcStateChange(self, state):
1460 if self.comm is None:
1462 if self.comm.isOperational():
1463 if self._wizardState == 0:
1464 wx.CallAfter(self.infoBox.SetInfo, _('Homing printer and heating up both extruders.'))
1465 self.comm.sendCommand('M105')
1466 self.comm.sendCommand('M104 S220 T0')
1467 self.comm.sendCommand('M104 S220 T1')
1468 self.comm.sendCommand('G28')
1469 self.comm.sendCommand('G1 Z15 F%d' % (profile.getProfileSettingFloat('print_speed') * 60))
1470 self._wizardState = 1
1471 if not self.comm.isPrinting():
1472 if self._wizardState == 3:
1473 self._wizardState = 4
1474 wx.CallAfter(self.infoBox.SetAttention, _('Please measure the distance between the vertical lines in millimeters.'))
1475 wx.CallAfter(self.textEntry.SetValue, '0.0')
1476 wx.CallAfter(self.textEntry.Enable, True)
1477 wx.CallAfter(self.resumeButton.Enable, True)
1478 wx.CallAfter(self.resumeButton.SetFocus)
1479 elif self._wizardState == 6:
1480 self._wizardState = 7
1481 wx.CallAfter(self.infoBox.SetAttention, _('Which vertical line number lays perfect on top of each other? Leftmost line is zero.'))
1482 wx.CallAfter(self.textEntry.SetValue, '10')
1483 wx.CallAfter(self.textEntry.Enable, True)
1484 wx.CallAfter(self.resumeButton.Enable, True)
1485 wx.CallAfter(self.resumeButton.SetFocus)
1487 elif self.comm.isError():
1488 wx.CallAfter(self.infoBox.SetError, _('Failed to establish connection with the printer.'), 'http://wiki.ultimaker.com/Cura:_Connection_problems')
1490 def mcMessage(self, message):
1493 def mcProgress(self, lineNr):
1496 def mcZChange(self, newZ):
1499 class bedLevelWizard(wx.wizard.Wizard):
1501 super(bedLevelWizard, self).__init__(None, -1, _("Bed leveling wizard"))
1503 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
1504 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
1506 self.mainPage = bedLevelWizardMain(self)
1507 self.headOffsetCalibration = None
1509 self.FitToPage(self.mainPage)
1510 self.GetPageAreaSizer().Add(self.mainPage)
1512 self.RunWizard(self.mainPage)
1515 def OnPageChanging(self, e):
1516 e.GetPage().StoreData()
1518 def OnPageChanged(self, e):
1519 if e.GetPage().AllowNext():
1520 self.FindWindowById(wx.ID_FORWARD).Enable()
1522 self.FindWindowById(wx.ID_FORWARD).Disable()
1523 if e.GetPage().AllowBack():
1524 self.FindWindowById(wx.ID_BACKWARD).Enable()
1526 self.FindWindowById(wx.ID_BACKWARD).Disable()
1528 class headOffsetWizard(wx.wizard.Wizard):
1530 super(headOffsetWizard, self).__init__(None, -1, _("Head offset wizard"))
1532 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
1533 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
1535 self.mainPage = headOffsetCalibrationPage(self)
1537 self.FitToPage(self.mainPage)
1538 self.GetPageAreaSizer().Add(self.mainPage)
1540 self.RunWizard(self.mainPage)
1543 def OnPageChanging(self, e):
1544 e.GetPage().StoreData()
1546 def OnPageChanged(self, e):
1547 if e.GetPage().AllowNext():
1548 self.FindWindowById(wx.ID_FORWARD).Enable()
1550 self.FindWindowById(wx.ID_FORWARD).Disable()
1551 if e.GetPage().AllowBack():
1552 self.FindWindowById(wx.ID_BACKWARD).Enable()
1554 self.FindWindowById(wx.ID_BACKWARD).Disable()