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)
227 class PrintrbotPage(InfoPage):
228 def __init__(self, parent):
229 self._printer_info = [
230 # X, Y, Z, Nozzle Size, Filament Diameter, PrintTemperature, Print Speed, Travel Speed, Retract speed, Retract amount, use bed level sensor
231 ("Simple Metal", 150, 150, 150, 0.4, 1.75, 208, 40, 70, 30, 1, True),
232 ("Metal Plus", 250, 250, 250, 0.4, 1.75, 208, 40, 70, 30, 1, True),
233 ("Simple Makers Kit", 100, 100, 100, 0.4, 1.75, 208, 40, 70, 30, 1, True),
234 (":" + _("Older models"),),
235 ("Original", 130, 130, 130, 0.5, 2.95, 208, 40, 70, 30, 1, False),
236 ("Simple Maker's Edition v1", 100, 100, 100, 0.5, 1.75, 208, 40, 70, 30, 1, False),
237 ("Simple Maker's Edition v2 (2013 Printrbot Simple)", 100, 100, 100, 0.5, 1.75, 208, 40, 70, 30, 1, False),
238 ("Simple Maker's Edition v3 (2014 Printrbot Simple)", 100, 100, 100, 0.5, 1.75, 208, 40, 70, 30, 1, False),
239 ("Simple Maker's Edition v4 (Model 1405)", 100, 100, 100, 0.5, 1.75, 208, 40, 70, 30, 1, False),
240 ("Jr v1", 150, 100, 80, 0.5, 1.75, 208, 40, 70, 30, 1, False),
241 ("Jr v2", 150, 150, 150, 0.5, 1.75, 208, 40, 70, 30, 1, False),
242 ("LC v2", 150, 150, 150, 0.5, 1.75, 208, 40, 70, 30, 1, False),
243 ("Plus v2", 200, 200, 200, 0.5, 1.75, 208, 40, 70, 30, 1, False),
244 ("Plus v2.1", 200, 200, 200, 0.5, 1.75, 208, 40, 70, 30, 1, False),
245 ("Plus v2.2 (Model 1404/140422)", 250, 250, 250, 0.5, 1.75, 208, 40, 70, 30, 1, False),
246 ("Plus v2.3 (Model 140501)", 250, 250, 250, 0.5, 1.75, 208, 40, 70, 30, 1, False),
247 ("Plus v2.4 (Model 140507)", 250, 250, 250, 0.5, 1.75, 208, 40, 70, 30, 1, False),
248 ("Go v2 Large", 609, 305, 305, 0.5, 1.75, 208, 35, 70, 30, 1, False),
251 super(PrintrbotPage, self).__init__(parent, _("Printrbot Selection"))
252 self.AddBitmap(wx.Bitmap(resources.getPathForImage('Printrbot_logo.png')))
253 self.AddText(_("Select which Printrbot machine you have:"))
255 for printer in self._printer_info:
256 if printer[0].startswith(":"):
258 self.AddText(printer[0][1:])
260 item = self.AddRadioButton(printer[0])
261 item.data = printer[1:]
262 self._items.append(item)
265 profile.putMachineSetting('machine_name', 'Printrbot ???')
266 for item in self._items:
269 profile.putMachineSetting('machine_name', 'Printrbot ' + item.GetLabel())
270 profile.putMachineSetting('machine_width', data[0])
271 profile.putMachineSetting('machine_depth', data[1])
272 profile.putMachineSetting('machine_height', data[2])
273 profile.putProfileSetting('nozzle_size', data[3])
274 profile.putProfileSetting('filament_diameter', data[4])
275 profile.putProfileSetting('print_temperature', data[5])
276 profile.putProfileSetting('print_speed', data[6])
277 profile.putProfileSetting('travel_speed', data[7])
278 profile.putProfileSetting('retraction_speed', data[8])
279 profile.putProfileSetting('retraction_amount', data[9])
280 profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
281 profile.putMachineSetting('has_heated_bed', 'False')
282 profile.putMachineSetting('machine_center_is_zero', 'False')
283 profile.putMachineSetting('extruder_head_size_min_x', '0')
284 profile.putMachineSetting('extruder_head_size_min_y', '0')
285 profile.putMachineSetting('extruder_head_size_max_x', '0')
286 profile.putMachineSetting('extruder_head_size_max_y', '0')
287 profile.putMachineSetting('extruder_head_size_height', '0')
289 profile.setAlterationFile('start.gcode', """;Sliced at: {day} {date} {time}
290 ;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {fill_density}
291 ;Print time: {print_time}
292 ;Filament used: {filament_amount}m {filament_weight}g
293 ;Filament cost: {filament_cost}
294 ;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line
295 ;M109 S{print_temperature} ;Uncomment to add your own temperature line
297 G90 ;absolute positioning
298 M82 ;set extruder to absolute mode
299 M107 ;start with the fan off
301 G28 X0 Y0 ;move X/Y to min endstops
302 G28 Z0 ;move Z to min endstops
303 G29 ;Run the auto bed leveling
305 G1 Z15.0 F{travel_speed} ;move the platform down 15mm
307 G92 E0 ;zero the extruded length
308 G1 F200 E3 ;extrude 3mm of feed stock
309 G92 E0 ;zero the extruded length again
311 ;Put printing message on LCD screen
315 class OtherMachineSelectPage(InfoPage):
316 def __init__(self, parent):
317 super(OtherMachineSelectPage, self).__init__(parent, _("Other machine information"))
318 self.AddText(_("The following pre-defined machine profiles are available"))
319 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."))
321 machines = resources.getDefaultMachineProfiles()
323 for filename in machines:
324 name = os.path.splitext(os.path.basename(filename))[0]
325 item = self.AddRadioButton(name)
326 item.filename = filename
327 item.Bind(wx.EVT_RADIOBUTTON, self.OnProfileSelect)
328 self.options.append(item)
330 item = self.AddRadioButton(_('Custom...'))
332 item.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)
334 def OnProfileSelect(self, e):
335 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().otherMachineInfoPage)
337 def OnOtherSelect(self, e):
338 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().customRepRapInfoPage)
341 for option in self.options:
342 if option.GetValue():
343 profile.loadProfile(option.filename)
344 profile.loadMachineSettings(option.filename)
346 class OtherMachineInfoPage(InfoPage):
347 def __init__(self, parent):
348 super(OtherMachineInfoPage, self).__init__(parent, _("Cura Ready!"))
349 self.AddText(_("Cura is now ready to be used!"))
351 class CustomRepRapInfoPage(InfoPage):
352 def __init__(self, parent):
353 super(CustomRepRapInfoPage, self).__init__(parent, _("Custom RepRap information"))
354 self.AddText(_("RepRap machines can be vastly different, so here you can set your own settings."))
355 self.AddText(_("Be sure to review the default profile before running it on your machine."))
356 self.AddText(_("If you like a default profile for your machine added,\nthen make an issue on github."))
358 self.AddText(_("You will have to manually install Marlin or Sprinter firmware."))
360 self.machineName = self.AddLabelTextCtrl(_("Machine name"), "RepRap")
361 self.machineWidth = self.AddLabelTextCtrl(_("Machine width (mm)"), "80")
362 self.machineDepth = self.AddLabelTextCtrl(_("Machine depth (mm)"), "80")
363 self.machineHeight = self.AddLabelTextCtrl(_("Machine height (mm)"), "55")
364 self.nozzleSize = self.AddLabelTextCtrl(_("Nozzle size (mm)"), "0.5")
365 self.heatedBed = self.AddCheckbox(_("Heated bed"))
366 self.HomeAtCenter = self.AddCheckbox(_("Bed center is 0,0,0 (RoStock)"))
369 profile.putMachineSetting('machine_name', self.machineName.GetValue())
370 profile.putMachineSetting('machine_width', self.machineWidth.GetValue())
371 profile.putMachineSetting('machine_depth', self.machineDepth.GetValue())
372 profile.putMachineSetting('machine_height', self.machineHeight.GetValue())
373 profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
374 profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
375 profile.putMachineSetting('has_heated_bed', str(self.heatedBed.GetValue()))
376 profile.putMachineSetting('machine_center_is_zero', str(self.HomeAtCenter.GetValue()))
377 profile.putMachineSetting('extruder_head_size_min_x', '0')
378 profile.putMachineSetting('extruder_head_size_min_y', '0')
379 profile.putMachineSetting('extruder_head_size_max_x', '0')
380 profile.putMachineSetting('extruder_head_size_max_y', '0')
381 profile.putMachineSetting('extruder_head_size_height', '0')
382 profile.checkAndUpdateMachineName()
384 class MachineSelectPage(InfoPage):
385 def __init__(self, parent):
386 super(MachineSelectPage, self).__init__(parent, _("Select your machine"))
387 self.AddText(_("What kind of machine do you have:"))
389 self.LulzbotMiniRadio = self.AddRadioButton("LulzBot Mini", style=wx.RB_GROUP)
390 self.LulzbotMiniRadio.Bind(wx.EVT_RADIOBUTTON, self.OnLulzbotSelect)
391 self.LulzbotMiniRadio.SetValue(True)
392 self.LulzbotTaz5Radio = self.AddRadioButton("LulzBot TAZ 5")
393 self.LulzbotTaz5Radio.Bind(wx.EVT_RADIOBUTTON, self.OnLulzbotSelect)
394 self.LulzbotTaz4Radio = self.AddRadioButton("LulzBot TAZ 4")
395 self.LulzbotTaz4Radio.Bind(wx.EVT_RADIOBUTTON, self.OnLulzbotSelect)
396 self.Ultimaker2Radio = self.AddRadioButton("Ultimaker2")
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.OtherRadio = self.AddRadioButton(_("Other (Ex: RepRap, MakerBot, Witbox)"))
405 self.OtherRadio.Bind(wx.EVT_RADIOBUTTON, self.OnOtherSelect)
407 def OnUltimaker2Select(self, e):
408 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimaker2ReadyPage)
410 def OnUltimakerSelect(self, e):
411 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerSelectParts)
413 def OnUltimakerOPSelect(self, e):
414 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().ultimakerFirmwareUpgradePage)
416 def OnPrintrbotSelect(self, e):
417 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().printrbotSelectType)
419 def OnLulzbotSelect(self, e):
420 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().lulzbotReadyPage)
422 def OnOtherSelect(self, e):
423 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().otherMachineSelectPage)
426 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().lulzbotReadyPage)
430 profile.putProfileSetting('retraction_enable', 'True')
431 if self.Ultimaker2Radio.GetValue():
432 profile.putMachineSetting('machine_width', '230')
433 profile.putMachineSetting('machine_depth', '225')
434 profile.putMachineSetting('machine_height', '205')
435 profile.putMachineSetting('machine_name', 'ultimaker2')
436 profile.putMachineSetting('machine_type', 'ultimaker2')
437 profile.putMachineSetting('machine_center_is_zero', 'False')
438 profile.putMachineSetting('has_heated_bed', 'True')
439 profile.putMachineSetting('gcode_flavor', 'UltiGCode')
440 profile.putMachineSetting('extruder_head_size_min_x', '40.0')
441 profile.putMachineSetting('extruder_head_size_min_y', '10.0')
442 profile.putMachineSetting('extruder_head_size_max_x', '60.0')
443 profile.putMachineSetting('extruder_head_size_max_y', '30.0')
444 profile.putMachineSetting('extruder_head_size_height', '48.0')
445 profile.putProfileSetting('nozzle_size', '0.4')
446 profile.putProfileSetting('fan_full_height', '5.0')
447 profile.putMachineSetting('extruder_offset_x1', '18.0')
448 profile.putMachineSetting('extruder_offset_y1', '0.0')
449 elif self.UltimakerRadio.GetValue():
450 profile.putMachineSetting('machine_width', '205')
451 profile.putMachineSetting('machine_depth', '205')
452 profile.putMachineSetting('machine_height', '200')
453 profile.putMachineSetting('machine_name', 'ultimaker original')
454 profile.putMachineSetting('machine_type', 'ultimaker')
455 profile.putMachineSetting('machine_center_is_zero', 'False')
456 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
457 profile.putProfileSetting('nozzle_size', '0.4')
458 profile.putMachineSetting('extruder_head_size_min_x', '75.0')
459 profile.putMachineSetting('extruder_head_size_min_y', '18.0')
460 profile.putMachineSetting('extruder_head_size_max_x', '18.0')
461 profile.putMachineSetting('extruder_head_size_max_y', '35.0')
462 profile.putMachineSetting('extruder_head_size_height', '55.0')
463 elif self.UltimakerOPRadio.GetValue():
464 profile.putMachineSetting('machine_width', '205')
465 profile.putMachineSetting('machine_depth', '205')
466 profile.putMachineSetting('machine_height', '200')
467 profile.putMachineSetting('machine_name', 'ultimaker original+')
468 profile.putMachineSetting('machine_type', 'ultimaker_plus')
469 profile.putMachineSetting('machine_center_is_zero', 'False')
470 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
471 profile.putProfileSetting('nozzle_size', '0.4')
472 profile.putMachineSetting('extruder_head_size_min_x', '75.0')
473 profile.putMachineSetting('extruder_head_size_min_y', '18.0')
474 profile.putMachineSetting('extruder_head_size_max_x', '18.0')
475 profile.putMachineSetting('extruder_head_size_max_y', '35.0')
476 profile.putMachineSetting('extruder_head_size_height', '55.0')
477 profile.putMachineSetting('has_heated_bed', 'True')
478 profile.putMachineSetting('extruder_amount', '1')
479 profile.putProfileSetting('retraction_enable', 'True')
480 elif self.LulzbotTaz4Radio.GetValue() or self.LulzbotTaz5Radio.GetValue() or self.LulzbotMiniRadio.GetValue():
481 if self.LulzbotTaz4Radio.GetValue():
482 profile.putMachineSetting('machine_width', '298')
483 profile.putMachineSetting('machine_depth', '275')
484 profile.putMachineSetting('machine_height', '250')
485 profile.putProfileSetting('nozzle_size', '0.35')
486 profile.putMachineSetting('machine_name', 'LulzBot TAZ 4')
487 profile.putMachineSetting('machine_type', 'lulzbot_TAZ_4')
488 profile.putMachineSetting('serial_baud', '115200')
489 elif self.LulzbotTaz5Radio.GetValue():
490 profile.putMachineSetting('machine_width', '298')
491 profile.putMachineSetting('machine_depth', '275')
492 profile.putMachineSetting('machine_height', '250')
493 profile.putProfileSetting('nozzle_size', '0.35')
494 profile.putMachineSetting('machine_name', 'LulzBot TAZ 5')
495 profile.putMachineSetting('machine_type', 'lulzbot_TAZ_5')
496 profile.putMachineSetting('serial_baud', '115200')
498 profile.putMachineSetting('machine_width', '155')
499 profile.putMachineSetting('machine_depth', '155')
500 profile.putMachineSetting('machine_height', '163')
501 profile.putProfileSetting('nozzle_size', '0.5')
502 profile.putMachineSetting('machine_name', 'LulzBot Mini')
503 profile.putMachineSetting('machine_type', 'lulzbot_mini')
504 profile.putMachineSetting('serial_baud', '115200')
505 profile.putMachineSetting('machine_center_is_zero', 'False')
506 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
507 profile.putMachineSetting('has_heated_bed', 'True')
508 profile.putMachineSetting('extruder_head_size_min_x', '0.0')
509 profile.putMachineSetting('extruder_head_size_min_y', '0.0')
510 profile.putMachineSetting('extruder_head_size_max_x', '0.0')
511 profile.putMachineSetting('extruder_head_size_max_y', '0.0')
512 profile.putMachineSetting('extruder_head_size_height', '0.0')
513 profile.putPreference('startMode', 'Simple')
515 profile.putMachineSetting('machine_width', '80')
516 profile.putMachineSetting('machine_depth', '80')
517 profile.putMachineSetting('machine_height', '60')
518 profile.putMachineSetting('machine_name', 'reprap')
519 profile.putMachineSetting('machine_type', 'reprap')
520 profile.putMachineSetting('gcode_flavor', 'RepRap (Marlin/Sprinter)')
521 profile.putPreference('startMode', 'Normal')
522 profile.putProfileSetting('nozzle_size', '0.5')
523 profile.checkAndUpdateMachineName()
524 profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2)
526 class SelectParts(InfoPage):
527 def __init__(self, parent):
528 super(SelectParts, self).__init__(parent, _("Select upgraded parts you have"))
529 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."))
531 self.springExtruder = self.AddCheckbox(_("Extruder drive upgrade"))
532 self.heatedBedKit = self.AddCheckbox(_("Heated printer bed (kit)"))
533 self.heatedBed = self.AddCheckbox(_("Heated printer bed (self built)"))
534 self.dualExtrusion = self.AddCheckbox(_("Dual extrusion (experimental)"))
536 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."))
537 self.AddText(_("This upgrade can be bought from the Ultimaker webshop\nor found on thingiverse as thing:26094"))
538 self.springExtruder.SetValue(True)
541 profile.putMachineSetting('ultimaker_extruder_upgrade', str(self.springExtruder.GetValue()))
542 if self.heatedBed.GetValue() or self.heatedBedKit.GetValue():
543 profile.putMachineSetting('has_heated_bed', 'True')
545 profile.putMachineSetting('has_heated_bed', 'False')
546 if self.dualExtrusion.GetValue():
547 profile.putMachineSetting('extruder_amount', '2')
548 profile.putMachineSetting('machine_depth', '195')
550 profile.putMachineSetting('extruder_amount', '1')
551 if profile.getMachineSetting('ultimaker_extruder_upgrade') == 'True':
552 profile.putProfileSetting('retraction_enable', 'True')
554 profile.putProfileSetting('retraction_enable', 'False')
557 class UltimakerFirmwareUpgradePage(InfoPage):
558 def __init__(self, parent):
559 super(UltimakerFirmwareUpgradePage, self).__init__(parent, _("Upgrade Ultimaker Firmware"))
560 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."))
561 self.AddHiddenSeperator()
562 self.AddText(_("The firmware shipping with new Ultimakers works, but upgrades\nhave been made to make better prints, and make calibration easier."))
563 self.AddHiddenSeperator()
564 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."))
565 upgradeButton, skipUpgradeButton = self.AddDualButton(_('Upgrade to Marlin firmware'), _('Skip upgrade'))
566 upgradeButton.Bind(wx.EVT_BUTTON, self.OnUpgradeClick)
567 skipUpgradeButton.Bind(wx.EVT_BUTTON, self.OnSkipClick)
568 self.AddHiddenSeperator()
569 if profile.getMachineSetting('machine_type') == 'ultimaker':
570 self.AddText(_("Do not upgrade to this firmware if:"))
571 self.AddText(_("* You have an older machine based on ATMega1280 (Rev 1 machine)"))
572 self.AddText(_("* Build your own heated bed"))
573 self.AddText(_("* Have other changes in the firmware"))
574 # button = self.AddButton('Goto this page for a custom firmware')
575 # button.Bind(wx.EVT_BUTTON, self.OnUrlClick)
580 def OnUpgradeClick(self, e):
581 if firmwareInstall.InstallFirmware():
582 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
584 def OnSkipClick(self, e):
585 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
586 self.GetParent().ShowPage(self.GetNext())
588 def OnUrlClick(self, e):
589 webbrowser.open('http://marlinbuilder.robotfuzz.com/')
591 class UltimakerCheckupPage(InfoPage):
592 def __init__(self, parent):
593 super(UltimakerCheckupPage, self).__init__(parent, _("Ultimaker Checkup"))
595 self.checkBitmap = wx.Bitmap(resources.getPathForImage('checkmark.png'))
596 self.crossBitmap = wx.Bitmap(resources.getPathForImage('cross.png'))
597 self.unknownBitmap = wx.Bitmap(resources.getPathForImage('question.png'))
598 self.endStopNoneBitmap = wx.Bitmap(resources.getPathForImage('endstop_none.png'))
599 self.endStopXMinBitmap = wx.Bitmap(resources.getPathForImage('endstop_xmin.png'))
600 self.endStopXMaxBitmap = wx.Bitmap(resources.getPathForImage('endstop_xmax.png'))
601 self.endStopYMinBitmap = wx.Bitmap(resources.getPathForImage('endstop_ymin.png'))
602 self.endStopYMaxBitmap = wx.Bitmap(resources.getPathForImage('endstop_ymax.png'))
603 self.endStopZMinBitmap = wx.Bitmap(resources.getPathForImage('endstop_zmin.png'))
604 self.endStopZMaxBitmap = wx.Bitmap(resources.getPathForImage('endstop_zmax.png'))
607 _("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."))
608 b1, b2 = self.AddDualButton(_("Run checks"), _("Skip checks"))
609 b1.Bind(wx.EVT_BUTTON, self.OnCheckClick)
610 b2.Bind(wx.EVT_BUTTON, self.OnSkipClick)
612 self.commState = self.AddCheckmark(_("Communication:"), self.unknownBitmap)
613 self.tempState = self.AddCheckmark(_("Temperature:"), self.unknownBitmap)
614 self.stopState = self.AddCheckmark(_("Endstops:"), self.unknownBitmap)
616 self.infoBox = self.AddInfoBox()
617 self.machineState = self.AddText("")
618 self.temperatureLabel = self.AddText("")
619 self.errorLogButton = self.AddButton(_("Show error log"))
620 self.errorLogButton.Show(False)
622 self.endstopBitmap = self.AddBitmap(self.endStopNoneBitmap)
624 self.xMinStop = False
625 self.xMaxStop = False
626 self.yMinStop = False
627 self.yMaxStop = False
628 self.zMinStop = False
629 self.zMaxStop = False
631 self.Bind(wx.EVT_BUTTON, self.OnErrorLog, self.errorLogButton)
634 if self.comm is not None:
638 self.endstopBitmap.Show(False)
641 def OnSkipClick(self, e):
642 self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
643 self.GetParent().ShowPage(self.GetNext())
645 def OnCheckClick(self, e=None):
646 self.errorLogButton.Show(False)
647 if self.comm is not None:
651 wx.CallAfter(self.OnCheckClick)
653 self.infoBox.SetBusy(_("Connecting to machine."))
654 self.commState.SetBitmap(self.unknownBitmap)
655 self.tempState.SetBitmap(self.unknownBitmap)
656 self.stopState.SetBitmap(self.unknownBitmap)
657 self.checkupState = 0
658 self.checkExtruderNr = 0
659 self.comm = machineCom.MachineCom(callbackObject=self)
661 def OnErrorLog(self, e):
662 printWindow.LogWindow('\n'.join(self.comm.getLog()))
664 def mcLog(self, message):
667 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
668 if not self.comm.isOperational():
670 if self.checkupState == 0:
671 self.tempCheckTimeout = 20
672 if temp[self.checkExtruderNr] > 70:
673 self.checkupState = 1
674 wx.CallAfter(self.infoBox.SetInfo, _("Cooldown before temperature check."))
675 self.comm.sendCommand("M104 S0 T%d" % (self.checkExtruderNr))
676 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
678 self.startTemp = temp[self.checkExtruderNr]
679 self.checkupState = 2
680 wx.CallAfter(self.infoBox.SetInfo, _("Checking the heater and temperature sensor."))
681 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
682 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
683 elif self.checkupState == 1:
684 if temp[self.checkExtruderNr] < 60:
685 self.startTemp = temp[self.checkExtruderNr]
686 self.checkupState = 2
687 wx.CallAfter(self.infoBox.SetInfo, _("Checking the heater and temperature sensor."))
688 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
689 self.comm.sendCommand('M104 S200 T%d' % (self.checkExtruderNr))
690 elif self.checkupState == 2:
691 #print "WARNING, TEMPERATURE TEST DISABLED FOR TESTING!"
692 if temp[self.checkExtruderNr] > self.startTemp + 40:
693 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
694 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
695 if self.checkExtruderNr < int(profile.getMachineSetting('extruder_amount')):
696 self.checkExtruderNr = 0
697 self.checkupState = 3
698 wx.CallAfter(self.infoBox.SetAttention, _("Please make sure none of the endstops are pressed."))
699 wx.CallAfter(self.endstopBitmap.Show, True)
700 wx.CallAfter(self.Layout)
701 self.comm.sendCommand('M119')
702 wx.CallAfter(self.tempState.SetBitmap, self.checkBitmap)
704 self.checkupState = 0
705 self.checkExtruderNr += 1
707 self.tempCheckTimeout -= 1
708 if self.tempCheckTimeout < 1:
709 self.checkupState = -1
710 wx.CallAfter(self.tempState.SetBitmap, self.crossBitmap)
711 wx.CallAfter(self.infoBox.SetError, _("Temperature measurement FAILED!"), 'http://wiki.ultimaker.com/Cura:_Temperature_measurement_problems')
712 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
713 self.comm.sendCommand('M104 S0 T%d' % (self.checkExtruderNr))
714 elif self.checkupState >= 3 and self.checkupState < 10:
715 self.comm.sendCommand('M119')
716 wx.CallAfter(self.temperatureLabel.SetLabel, _("Head temperature: %d") % (temp[self.checkExtruderNr]))
718 def mcStateChange(self, state):
719 if self.comm is None:
721 if self.comm.isOperational():
722 wx.CallAfter(self.commState.SetBitmap, self.checkBitmap)
723 wx.CallAfter(self.machineState.SetLabel, _("Communication State: %s") % (self.comm.getStateString()))
724 elif self.comm.isError():
725 wx.CallAfter(self.commState.SetBitmap, self.crossBitmap)
726 wx.CallAfter(self.infoBox.SetError, _("Failed to establish connection with the printer."), 'http://wiki.ultimaker.com/Cura:_Connection_problems')
727 wx.CallAfter(self.endstopBitmap.Show, False)
728 wx.CallAfter(self.machineState.SetLabel, '%s' % (self.comm.getErrorString()))
729 wx.CallAfter(self.errorLogButton.Show, True)
730 wx.CallAfter(self.Layout)
732 wx.CallAfter(self.machineState.SetLabel, _("Communication State: %s") % (self.comm.getStateString()))
734 def mcMessage(self, message):
735 if self.checkupState >= 3 and self.checkupState < 10 and ('_min' in message or '_max' in message):
736 for data in message.split(' '):
738 tag, value = data.split(':', 1)
740 self.xMinStop = (value == 'H' or value == 'TRIGGERED')
742 self.xMaxStop = (value == 'H' or value == 'TRIGGERED')
744 self.yMinStop = (value == 'H' or value == 'TRIGGERED')
746 self.yMaxStop = (value == 'H' or value == 'TRIGGERED')
748 self.zMinStop = (value == 'H' or value == 'TRIGGERED')
750 self.zMaxStop = (value == 'H' or value == 'TRIGGERED')
752 tag, value = map(str.strip, message.split(':', 1))
754 self.xMinStop = (value == 'H' or value == 'TRIGGERED')
756 self.xMaxStop = (value == 'H' or value == 'TRIGGERED')
758 self.yMinStop = (value == 'H' or value == 'TRIGGERED')
760 self.yMaxStop = (value == 'H' or value == 'TRIGGERED')
762 self.zMinStop = (value == 'H' or value == 'TRIGGERED')
764 self.zMaxStop = (value == 'H' or value == 'TRIGGERED')
765 if 'z_max' in message:
766 self.comm.sendCommand('M119')
768 if self.checkupState == 3:
769 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
770 if profile.getMachineSetting('machine_type') == 'ultimaker_plus':
771 self.checkupState = 5
772 wx.CallAfter(self.infoBox.SetAttention, _("Please press the left X endstop."))
773 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMinBitmap)
775 self.checkupState = 4
776 wx.CallAfter(self.infoBox.SetAttention, _("Please press the right X endstop."))
777 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMaxBitmap)
778 elif self.checkupState == 4:
779 if not self.xMinStop and self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
780 self.checkupState = 5
781 wx.CallAfter(self.infoBox.SetAttention, _("Please press the left X endstop."))
782 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopXMinBitmap)
783 elif self.checkupState == 5:
784 if self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
785 self.checkupState = 6
786 wx.CallAfter(self.infoBox.SetAttention, _("Please press the front Y endstop."))
787 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopYMinBitmap)
788 elif self.checkupState == 6:
789 if not self.xMinStop and not self.xMaxStop and self.yMinStop and not self.yMaxStop and not self.zMinStop and not self.zMaxStop:
790 if profile.getMachineSetting('machine_type') == 'ultimaker_plus':
791 self.checkupState = 8
792 wx.CallAfter(self.infoBox.SetAttention, _("Please press the top Z endstop."))
793 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMinBitmap)
795 self.checkupState = 7
796 wx.CallAfter(self.infoBox.SetAttention, _("Please press the back Y endstop."))
797 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopYMaxBitmap)
798 elif self.checkupState == 7:
799 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and self.yMaxStop and not self.zMinStop and not self.zMaxStop:
800 self.checkupState = 8
801 wx.CallAfter(self.infoBox.SetAttention, _("Please press the top Z endstop."))
802 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMinBitmap)
803 elif self.checkupState == 8:
804 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and self.zMinStop and not self.zMaxStop:
805 if profile.getMachineSetting('machine_type') == 'ultimaker_plus':
806 self.checkupState = 10
808 wx.CallAfter(self.infoBox.SetInfo, _("Checkup finished"))
809 wx.CallAfter(self.infoBox.SetReadyIndicator)
810 wx.CallAfter(self.endstopBitmap.Show, False)
811 wx.CallAfter(self.stopState.SetBitmap, self.checkBitmap)
812 wx.CallAfter(self.OnSkipClick, None)
814 self.checkupState = 9
815 wx.CallAfter(self.infoBox.SetAttention, _("Please press the bottom Z endstop."))
816 wx.CallAfter(self.endstopBitmap.SetBitmap, self.endStopZMaxBitmap)
817 elif self.checkupState == 9:
818 if not self.xMinStop and not self.xMaxStop and not self.yMinStop and not self.yMaxStop and not self.zMinStop and self.zMaxStop:
819 self.checkupState = 10
821 wx.CallAfter(self.infoBox.SetInfo, _("Checkup finished"))
822 wx.CallAfter(self.infoBox.SetReadyIndicator)
823 wx.CallAfter(self.endstopBitmap.Show, False)
824 wx.CallAfter(self.stopState.SetBitmap, self.checkBitmap)
825 wx.CallAfter(self.OnSkipClick, None)
827 def mcProgress(self, lineNr):
830 def mcZChange(self, newZ):
834 class UltimakerCalibrationPage(InfoPage):
835 def __init__(self, parent):
836 super(UltimakerCalibrationPage, self).__init__(parent, _("Ultimaker Calibration"))
838 self.AddText("Your Ultimaker requires some calibration.")
839 self.AddText("This calibration is needed for a proper extrusion amount.")
841 self.AddText("The following values are needed:")
842 self.AddText("* Diameter of filament")
843 self.AddText("* Number of steps per mm of filament extrusion")
845 self.AddText("The better you have calibrated these values, the better your prints\nwill become.")
847 self.AddText("First we need the diameter of your filament:")
848 self.filamentDiameter = self.AddTextCtrl(profile.getProfileSetting('filament_diameter'))
850 "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.")
851 self.AddText("Note: This value can be changed later at any time.")
854 profile.putProfileSetting('filament_diameter', self.filamentDiameter.GetValue())
857 class UltimakerCalibrateStepsPerEPage(InfoPage):
858 def __init__(self, parent):
859 super(UltimakerCalibrateStepsPerEPage, self).__init__(parent, _("Ultimaker Calibration"))
861 #if profile.getMachineSetting('steps_per_e') == '0':
862 # profile.putMachineSetting('steps_per_e', '865.888')
864 self.AddText(_("Calibrating the Steps Per E requires some manual actions."))
865 self.AddText(_("First remove any filament from your machine."))
866 self.AddText(_("Next put in your filament so the tip is aligned with the\ntop of the extruder drive."))
867 self.AddText(_("We'll push the filament 100mm"))
868 self.extrudeButton = self.AddButton(_("Extrude 100mm filament"))
869 self.AddText(_("Now measure the amount of extruded filament:\n(this can be more or less then 100mm)"))
870 self.lengthInput, self.saveLengthButton = self.AddTextCtrlButton("100", _("Save"))
871 self.AddText(_("This results in the following steps per E:"))
872 self.stepsPerEInput = self.AddTextCtrl(profile.getMachineSetting('steps_per_e'))
873 self.AddText(_("You can repeat these steps to get better calibration."))
876 _("If you still have filament in your printer which needs\nheat to remove, press the heat up button below:"))
877 self.heatButton = self.AddButton(_("Heatup for filament removal"))
879 self.saveLengthButton.Bind(wx.EVT_BUTTON, self.OnSaveLengthClick)
880 self.extrudeButton.Bind(wx.EVT_BUTTON, self.OnExtrudeClick)
881 self.heatButton.Bind(wx.EVT_BUTTON, self.OnHeatClick)
883 def OnSaveLengthClick(self, e):
884 currentEValue = float(self.stepsPerEInput.GetValue())
885 realExtrudeLength = float(self.lengthInput.GetValue())
886 newEValue = currentEValue * 100 / realExtrudeLength
887 self.stepsPerEInput.SetValue(str(newEValue))
888 self.lengthInput.SetValue("100")
890 def OnExtrudeClick(self, e):
891 t = threading.Thread(target=self.OnExtrudeRun)
895 def OnExtrudeRun(self):
896 self.heatButton.Enable(False)
897 self.extrudeButton.Enable(False)
898 currentEValue = float(self.stepsPerEInput.GetValue())
899 self.comm = machineCom.MachineCom()
900 if not self.comm.isOpen():
902 _("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable"),
903 'Printer error', wx.OK | wx.ICON_INFORMATION)
904 self.heatButton.Enable(True)
905 self.extrudeButton.Enable(True)
908 line = self.comm.readline()
913 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
916 self.sendGCommand('M302') #Disable cold extrusion protection
917 self.sendGCommand("M92 E%f" % (currentEValue))
918 self.sendGCommand("G92 E0")
919 self.sendGCommand("G1 E100 F600")
922 self.extrudeButton.Enable()
923 self.heatButton.Enable()
925 def OnHeatClick(self, e):
926 t = threading.Thread(target=self.OnHeatRun)
931 self.heatButton.Enable(False)
932 self.extrudeButton.Enable(False)
933 self.comm = machineCom.MachineCom()
934 if not self.comm.isOpen():
936 _("Error: Failed to open serial port to machine\nIf this keeps happening, try disconnecting and reconnecting the USB cable"),
937 'Printer error', wx.OK | wx.ICON_INFORMATION)
938 self.heatButton.Enable(True)
939 self.extrudeButton.Enable(True)
942 line = self.comm.readline()
944 self.heatButton.Enable(True)
945 self.extrudeButton.Enable(True)
949 #Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
952 self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out.
954 'Wait till you can remove the filament from the machine, and press OK.\n(Temperature is set to 200C)',
955 'Machine heatup', wx.OK | wx.ICON_INFORMATION)
956 self.sendGCommand('M104 S0')
959 self.heatButton.Enable(True)
960 self.extrudeButton.Enable(True)
962 def sendGCommand(self, cmd):
963 self.comm.sendCommand(cmd) #Disable cold extrusion protection
965 line = self.comm.readline()
968 if line.startswith('ok'):
972 profile.putPreference('steps_per_e', self.stepsPerEInput.GetValue())
974 class Ultimaker2ReadyPage(InfoPage):
975 def __init__(self, parent):
976 super(Ultimaker2ReadyPage, self).__init__(parent, _("Ultimaker2"))
977 self.AddText(_('Congratulations on your the purchase of your brand new Ultimaker2.'))
978 self.AddText(_('Cura is now ready to be used with your Ultimaker2.'))
981 class LulzbotReadyPage(InfoPage):
982 def __init__(self, parent):
983 super(LulzbotReadyPage, self).__init__(parent, _("LulzBot TAZ/Mini"))
984 self.AddText(_('Cura is now ready to be used with your LulzBot 3D printer.'))
986 self.AddText(_('For more information about using Cura with your LulzBot'))
987 self.AddText(_('3D printer, please visit www.LulzBot.com/cura'))
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.machineSelectPage = MachineSelectPage(self)
1003 self.ultimakerSelectParts = SelectParts(self)
1004 self.ultimakerFirmwareUpgradePage = UltimakerFirmwareUpgradePage(self)
1005 self.ultimakerCheckupPage = UltimakerCheckupPage(self)
1006 self.ultimakerCalibrationPage = UltimakerCalibrationPage(self)
1007 self.ultimakerCalibrateStepsPerEPage = UltimakerCalibrateStepsPerEPage(self)
1008 self.bedLevelPage = bedLevelWizardMain(self)
1009 self.headOffsetCalibration = headOffsetCalibrationPage(self)
1010 self.printrbotSelectType = PrintrbotPage(self)
1011 self.otherMachineSelectPage = OtherMachineSelectPage(self)
1012 self.customRepRapInfoPage = CustomRepRapInfoPage(self)
1013 self.otherMachineInfoPage = OtherMachineInfoPage(self)
1015 self.ultimaker2ReadyPage = Ultimaker2ReadyPage(self)
1016 self.lulzbotReadyPage = LulzbotReadyPage(self)
1018 #wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimaker2ReadyPage)
1019 wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerSelectParts)
1020 wx.wizard.WizardPageSimple.Chain(self.ultimakerSelectParts, self.ultimakerFirmwareUpgradePage)
1021 wx.wizard.WizardPageSimple.Chain(self.ultimakerFirmwareUpgradePage, self.ultimakerCheckupPage)
1022 wx.wizard.WizardPageSimple.Chain(self.ultimakerCheckupPage, self.bedLevelPage)
1023 #wx.wizard.WizardPageSimple.Chain(self.ultimakerCalibrationPage, self.ultimakerCalibrateStepsPerEPage)
1024 wx.wizard.WizardPageSimple.Chain(self.printrbotSelectType, self.otherMachineInfoPage)
1025 wx.wizard.WizardPageSimple.Chain(self.otherMachineSelectPage, self.customRepRapInfoPage)
1027 self.FitToPage(self.machineSelectPage)
1028 self.GetPageAreaSizer().Add(self.machineSelectPage)
1030 self.RunWizard(self.machineSelectPage)
1033 def OnPageChanging(self, e):
1034 e.GetPage().StoreData()
1036 def OnPageChanged(self, e):
1037 if e.GetPage().AllowNext():
1038 self.FindWindowById(wx.ID_FORWARD).Enable()
1040 self.FindWindowById(wx.ID_FORWARD).Disable()
1041 if e.GetPage().AllowBack():
1042 self.FindWindowById(wx.ID_BACKWARD).Enable()
1044 self.FindWindowById(wx.ID_BACKWARD).Disable()
1046 def OnCancel(self, e):
1047 profile.setActiveMachine(self._old_machine_index)
1049 class bedLevelWizardMain(InfoPage):
1050 def __init__(self, parent):
1051 super(bedLevelWizardMain, self).__init__(parent, _("Bed leveling wizard"))
1053 self.AddText(_('This wizard will help you in leveling your printer bed'))
1055 self.AddText(_('It will do the following steps'))
1056 self.AddText(_('* Move the printer head to each corner'))
1057 self.AddText(_(' and let you adjust the height of the bed to the nozzle'))
1058 self.AddText(_('* Print a line around the bed to check if it is level'))
1061 self.connectButton = self.AddButton(_('Connect to printer'))
1064 self.infoBox = self.AddInfoBox()
1065 self.resumeButton = self.AddButton(_('Resume'))
1066 self.upButton, self.downButton = self.AddDualButton(_('Up 0.2mm'), _('Down 0.2mm'))
1067 self.upButton2, self.downButton2 = self.AddDualButton(_('Up 10mm'), _('Down 10mm'))
1068 self.resumeButton.Enable(False)
1070 self.upButton.Enable(False)
1071 self.downButton.Enable(False)
1072 self.upButton2.Enable(False)
1073 self.downButton2.Enable(False)
1075 self.Bind(wx.EVT_BUTTON, self.OnConnect, self.connectButton)
1076 self.Bind(wx.EVT_BUTTON, self.OnResume, self.resumeButton)
1077 self.Bind(wx.EVT_BUTTON, self.OnBedUp, self.upButton)
1078 self.Bind(wx.EVT_BUTTON, self.OnBedDown, self.downButton)
1079 self.Bind(wx.EVT_BUTTON, self.OnBedUp2, self.upButton2)
1080 self.Bind(wx.EVT_BUTTON, self.OnBedDown2, self.downButton2)
1082 def OnConnect(self, e = None):
1083 if self.comm is not None:
1087 wx.CallAfter(self.OnConnect)
1089 self.connectButton.Enable(False)
1090 self.comm = machineCom.MachineCom(callbackObject=self)
1091 self.infoBox.SetBusy(_('Connecting to machine.'))
1092 self._wizardState = 0
1094 def OnBedUp(self, e):
1095 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1096 self.comm.sendCommand('G92 Z10')
1097 self.comm.sendCommand('G1 Z9.8 F%d' % (feedZ))
1098 self.comm.sendCommand('M400')
1100 def OnBedDown(self, e):
1101 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1102 self.comm.sendCommand('G92 Z10')
1103 self.comm.sendCommand('G1 Z10.2 F%d' % (feedZ))
1104 self.comm.sendCommand('M400')
1106 def OnBedUp2(self, e):
1107 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1108 self.comm.sendCommand('G92 Z10')
1109 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1110 self.comm.sendCommand('M400')
1112 def OnBedDown2(self, e):
1113 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1114 self.comm.sendCommand('G92 Z10')
1115 self.comm.sendCommand('G1 Z20 F%d' % (feedZ))
1116 self.comm.sendCommand('M400')
1118 def AllowNext(self):
1119 if self.GetParent().headOffsetCalibration is not None and int(profile.getMachineSetting('extruder_amount')) > 1:
1120 wx.wizard.WizardPageSimple.Chain(self, self.GetParent().headOffsetCalibration)
1123 def OnResume(self, e):
1124 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1125 feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
1126 if self._wizardState == -1:
1127 wx.CallAfter(self.infoBox.SetInfo, _('Homing printer...'))
1128 wx.CallAfter(self.upButton.Enable, False)
1129 wx.CallAfter(self.downButton.Enable, False)
1130 wx.CallAfter(self.upButton2.Enable, False)
1131 wx.CallAfter(self.downButton2.Enable, False)
1132 self.comm.sendCommand('M105')
1133 self.comm.sendCommand('G28')
1134 self._wizardState = 1
1135 elif self._wizardState == 2:
1136 if profile.getMachineSetting('has_heated_bed') == 'True':
1137 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to back center...'))
1138 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1139 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') / 2.0, profile.getMachineSettingFloat('machine_depth'), feedTravel))
1140 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1141 self.comm.sendCommand('M400')
1142 self._wizardState = 3
1144 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to back left corner...'))
1145 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1146 self.comm.sendCommand('G1 X%d Y%d F%d' % (0, profile.getMachineSettingFloat('machine_depth'), feedTravel))
1147 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1148 self.comm.sendCommand('M400')
1149 self._wizardState = 3
1150 elif self._wizardState == 4:
1151 if profile.getMachineSetting('has_heated_bed') == 'True':
1152 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to front right corner...'))
1153 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1154 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, 5, feedTravel))
1155 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1156 self.comm.sendCommand('M400')
1157 self._wizardState = 7
1159 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to back right corner...'))
1160 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1161 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, profile.getMachineSettingFloat('machine_depth') - 25, feedTravel))
1162 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1163 self.comm.sendCommand('M400')
1164 self._wizardState = 5
1165 elif self._wizardState == 6:
1166 wx.CallAfter(self.infoBox.SetBusy, _('Moving head to front right corner...'))
1167 self.comm.sendCommand('G1 Z3 F%d' % (feedZ))
1168 self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, 20, feedTravel))
1169 self.comm.sendCommand('G1 Z0 F%d' % (feedZ))
1170 self.comm.sendCommand('M400')
1171 self._wizardState = 7
1172 elif self._wizardState == 8:
1173 wx.CallAfter(self.infoBox.SetBusy, _('Heating up printer...'))
1174 self.comm.sendCommand('G1 Z15 F%d' % (feedZ))
1175 self.comm.sendCommand('M104 S%d' % (profile.getProfileSettingFloat('print_temperature')))
1176 self.comm.sendCommand('G1 X%d Y%d F%d' % (0, 0, feedTravel))
1177 self._wizardState = 9
1178 elif self._wizardState == 10:
1179 self._wizardState = 11
1180 wx.CallAfter(self.infoBox.SetInfo, _('Printing a square on the printer bed at 0.3mm height.'))
1181 feedZ = profile.getProfileSettingFloat('print_speed') * 60
1182 feedPrint = profile.getProfileSettingFloat('print_speed') * 60
1183 feedTravel = profile.getProfileSettingFloat('travel_speed') * 60
1184 w = profile.getMachineSettingFloat('machine_width') - 10
1185 d = profile.getMachineSettingFloat('machine_depth')
1186 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
1187 filamentArea = math.pi * filamentRadius * filamentRadius
1188 ePerMM = (profile.calculateEdgeWidth() * 0.3) / filamentArea
1192 'G1 Z2 F%d' % (feedZ),
1194 'G1 X%d Y%d F%d' % (5, 5, feedTravel),
1195 'G1 Z0.3 F%d' % (feedZ)]
1197 gcodeList.append('G1 E%f F%d' % (eValue, profile.getProfileSettingFloat('retraction_speed') * 60))
1199 for i in xrange(0, 3):
1200 dist = 5.0 + 0.4 * float(i)
1201 eValue += (d - 2.0*dist) * ePerMM
1202 gcodeList.append('G1 X%f Y%f E%f F%d' % (dist, d - dist, eValue, feedPrint))
1203 eValue += (w - 2.0*dist) * ePerMM
1204 gcodeList.append('G1 X%f Y%f E%f F%d' % (w - dist, d - dist, eValue, feedPrint))
1205 eValue += (d - 2.0*dist) * ePerMM
1206 gcodeList.append('G1 X%f Y%f E%f F%d' % (w - dist, dist, eValue, feedPrint))
1207 eValue += (w - 2.0*dist) * ePerMM
1208 gcodeList.append('G1 X%f Y%f E%f F%d' % (dist, dist, eValue, feedPrint))
1210 gcodeList.append('M400')
1211 self.comm.printGCode(gcodeList)
1212 self.resumeButton.Enable(False)
1214 def mcLog(self, message):
1215 print 'Log:', message
1217 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
1218 if self._wizardState == 1:
1219 self._wizardState = 2
1220 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the front left screw of your printer bed\nSo the nozzle just hits the bed.'))
1221 wx.CallAfter(self.resumeButton.Enable, True)
1222 elif self._wizardState == 3:
1223 self._wizardState = 4
1224 if profile.getMachineSetting('has_heated_bed') == 'True':
1225 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the back screw of your printer bed\nSo the nozzle just hits the bed.'))
1227 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the back left screw of your printer bed\nSo the nozzle just hits the bed.'))
1228 wx.CallAfter(self.resumeButton.Enable, True)
1229 elif self._wizardState == 5:
1230 self._wizardState = 6
1231 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the back right screw of your printer bed\nSo the nozzle just hits the bed.'))
1232 wx.CallAfter(self.resumeButton.Enable, True)
1233 elif self._wizardState == 7:
1234 self._wizardState = 8
1235 wx.CallAfter(self.infoBox.SetAttention, _('Adjust the front right screw of your printer bed\nSo the nozzle just hits the bed.'))
1236 wx.CallAfter(self.resumeButton.Enable, True)
1237 elif self._wizardState == 9:
1238 if temp[0] < profile.getProfileSettingFloat('print_temperature') - 5:
1239 wx.CallAfter(self.infoBox.SetInfo, _('Heating up printer: %d/%d') % (temp[0], profile.getProfileSettingFloat('print_temperature')))
1241 wx.CallAfter(self.infoBox.SetAttention, _('The printer is hot now. Please insert some PLA filament into the printer.'))
1242 wx.CallAfter(self.resumeButton.Enable, True)
1243 self._wizardState = 10
1245 def mcStateChange(self, state):
1246 if self.comm is None:
1248 if self.comm.isOperational():
1249 if self._wizardState == 0:
1250 wx.CallAfter(self.infoBox.SetAttention, _('Use the up/down buttons to move the bed and adjust your Z endstop.'))
1251 wx.CallAfter(self.upButton.Enable, True)
1252 wx.CallAfter(self.downButton.Enable, True)
1253 wx.CallAfter(self.upButton2.Enable, True)
1254 wx.CallAfter(self.downButton2.Enable, True)
1255 wx.CallAfter(self.resumeButton.Enable, True)
1256 self._wizardState = -1
1257 elif self._wizardState == 11 and not self.comm.isPrinting():
1258 self.comm.sendCommand('G1 Z15 F%d' % (profile.getProfileSettingFloat('print_speed') * 60))
1259 self.comm.sendCommand('G92 E0')
1260 self.comm.sendCommand('G1 E-10 F%d' % (profile.getProfileSettingFloat('retraction_speed') * 60))
1261 self.comm.sendCommand('M104 S0')
1262 wx.CallAfter(self.infoBox.SetInfo, _('Calibration finished.\nThe squares on the bed should slightly touch each other.'))
1263 wx.CallAfter(self.infoBox.SetReadyIndicator)
1264 wx.CallAfter(self.GetParent().FindWindowById(wx.ID_FORWARD).Enable)
1265 wx.CallAfter(self.connectButton.Enable, True)
1266 self._wizardState = 12
1267 elif self.comm.isError():
1268 wx.CallAfter(self.infoBox.SetError, _('Failed to establish connection with the printer.'), 'http://wiki.ultimaker.com/Cura:_Connection_problems')
1270 def mcMessage(self, message):
1273 def mcProgress(self, lineNr):
1276 def mcZChange(self, newZ):
1279 class headOffsetCalibrationPage(InfoPage):
1280 def __init__(self, parent):
1281 super(headOffsetCalibrationPage, self).__init__(parent, _("Printer head offset calibration"))
1283 self.AddText(_('This wizard will help you in calibrating the printer head offsets of your dual extrusion machine'))
1286 self.connectButton = self.AddButton(_('Connect to printer'))
1289 self.infoBox = self.AddInfoBox()
1290 self.textEntry = self.AddTextCtrl('')
1291 self.textEntry.Enable(False)
1292 self.resumeButton = self.AddButton(_('Resume'))
1293 self.resumeButton.Enable(False)
1295 self.Bind(wx.EVT_BUTTON, self.OnConnect, self.connectButton)
1296 self.Bind(wx.EVT_BUTTON, self.OnResume, self.resumeButton)
1298 def AllowBack(self):
1301 def OnConnect(self, e = None):
1302 if self.comm is not None:
1306 wx.CallAfter(self.OnConnect)
1308 self.connectButton.Enable(False)
1309 self.comm = machineCom.MachineCom(callbackObject=self)
1310 self.infoBox.SetBusy(_('Connecting to machine.'))
1311 self._wizardState = 0
1313 def OnResume(self, e):
1314 if self._wizardState == 2:
1315 self._wizardState = 3
1316 wx.CallAfter(self.infoBox.SetBusy, _('Printing initial calibration cross'))
1318 w = profile.getMachineSettingFloat('machine_width')
1319 d = profile.getMachineSettingFloat('machine_depth')
1321 gcode = gcodeGenerator.gcodeGenerator()
1322 gcode.setExtrusionRate(profile.getProfileSettingFloat('nozzle_size') * 1.5, 0.2)
1323 gcode.setPrintSpeed(profile.getProfileSettingFloat('bottom_layer_speed'))
1330 gcode.addMove(w/2, 5)
1331 gcode.addMove(z=0.2)
1333 gcode.addExtrude(w/2, d-5.0)
1335 gcode.addMove(5, d/2)
1337 gcode.addExtrude(w-5.0, d/2)
1338 gcode.addRetract(15)
1341 gcode.addMove(w/2, 5)
1343 gcode.addExtrude(w/2, d-5.0)
1345 gcode.addMove(5, d/2)
1347 gcode.addExtrude(w-5.0, d/2)
1348 gcode.addRetract(15)
1353 gcode.addCmd('M400')
1355 self.comm.printGCode(gcode.list())
1356 self.resumeButton.Enable(False)
1357 elif self._wizardState == 4:
1359 float(self.textEntry.GetValue())
1362 profile.putPreference('extruder_offset_x1', self.textEntry.GetValue())
1363 self._wizardState = 5
1364 self.infoBox.SetAttention(_('Please measure the distance between the horizontal lines in millimeters.'))
1365 self.textEntry.SetValue('0.0')
1366 self.textEntry.Enable(True)
1367 elif self._wizardState == 5:
1369 float(self.textEntry.GetValue())
1372 profile.putPreference('extruder_offset_y1', self.textEntry.GetValue())
1373 self._wizardState = 6
1374 self.infoBox.SetBusy(_('Printing the fine calibration lines.'))
1375 self.textEntry.SetValue('')
1376 self.textEntry.Enable(False)
1377 self.resumeButton.Enable(False)
1379 x = profile.getMachineSettingFloat('extruder_offset_x1')
1380 y = profile.getMachineSettingFloat('extruder_offset_y1')
1381 gcode = gcodeGenerator.gcodeGenerator()
1382 gcode.setExtrusionRate(profile.getProfileSettingFloat('nozzle_size') * 1.5, 0.2)
1383 gcode.setPrintSpeed(25)
1386 gcode.addMove(50, 40, 0.2)
1388 for n in xrange(0, 10):
1389 gcode.addExtrude(50 + n * 10, 150)
1390 gcode.addExtrude(50 + n * 10 + 5, 150)
1391 gcode.addExtrude(50 + n * 10 + 5, 40)
1392 gcode.addExtrude(50 + n * 10 + 10, 40)
1393 gcode.addMove(40, 50)
1394 for n in xrange(0, 10):
1395 gcode.addExtrude(150, 50 + n * 10)
1396 gcode.addExtrude(150, 50 + n * 10 + 5)
1397 gcode.addExtrude(40, 50 + n * 10 + 5)
1398 gcode.addExtrude(40, 50 + n * 10 + 10)
1399 gcode.addRetract(15)
1402 gcode.addMove(50 - x, 30 - y, 0.2)
1404 for n in xrange(0, 10):
1405 gcode.addExtrude(50 + n * 10.2 - 1.0 - x, 140 - y)
1406 gcode.addExtrude(50 + n * 10.2 - 1.0 + 5.1 - x, 140 - y)
1407 gcode.addExtrude(50 + n * 10.2 - 1.0 + 5.1 - x, 30 - y)
1408 gcode.addExtrude(50 + n * 10.2 - 1.0 + 10 - x, 30 - y)
1409 gcode.addMove(30 - x, 50 - y, 0.2)
1410 for n in xrange(0, 10):
1411 gcode.addExtrude(160 - x, 50 + n * 10.2 - 1.0 - y)
1412 gcode.addExtrude(160 - x, 50 + n * 10.2 - 1.0 + 5.1 - y)
1413 gcode.addExtrude(30 - x, 50 + n * 10.2 - 1.0 + 5.1 - y)
1414 gcode.addExtrude(30 - x, 50 + n * 10.2 - 1.0 + 10 - y)
1415 gcode.addRetract(15)
1417 gcode.addCmd('M400')
1418 gcode.addCmd('M104 T0 S0')
1419 gcode.addCmd('M104 T1 S0')
1420 self.comm.printGCode(gcode.list())
1421 elif self._wizardState == 7:
1423 n = int(self.textEntry.GetValue()) - 1
1426 x = profile.getMachineSettingFloat('extruder_offset_x1')
1428 profile.putPreference('extruder_offset_x1', '%0.2f' % (x))
1429 self.infoBox.SetAttention(_('Which horizontal line number lays perfect on top of each other? Front most line is zero.'))
1430 self.textEntry.SetValue('10')
1431 self._wizardState = 8
1432 elif self._wizardState == 8:
1434 n = int(self.textEntry.GetValue()) - 1
1437 y = profile.getMachineSettingFloat('extruder_offset_y1')
1439 profile.putPreference('extruder_offset_y1', '%0.2f' % (y))
1440 self.infoBox.SetInfo(_('Calibration finished. Offsets are: %s %s') % (profile.getMachineSettingFloat('extruder_offset_x1'), profile.getMachineSettingFloat('extruder_offset_y1')))
1441 self.infoBox.SetReadyIndicator()
1442 self._wizardState = 8
1444 self.resumeButton.Enable(False)
1446 def mcLog(self, message):
1447 print 'Log:', message
1449 def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
1450 if self._wizardState == 1:
1451 if temp[0] >= 210 and temp[1] >= 210:
1452 self._wizardState = 2
1453 wx.CallAfter(self.infoBox.SetAttention, _('Please load both extruders with PLA.'))
1454 wx.CallAfter(self.resumeButton.Enable, True)
1455 wx.CallAfter(self.resumeButton.SetFocus)
1457 def mcStateChange(self, state):
1458 if self.comm is None:
1460 if self.comm.isOperational():
1461 if self._wizardState == 0:
1462 wx.CallAfter(self.infoBox.SetInfo, _('Homing printer and heating up both extruders.'))
1463 self.comm.sendCommand('M105')
1464 self.comm.sendCommand('M104 S220 T0')
1465 self.comm.sendCommand('M104 S220 T1')
1466 self.comm.sendCommand('G28')
1467 self.comm.sendCommand('G1 Z15 F%d' % (profile.getProfileSettingFloat('print_speed') * 60))
1468 self._wizardState = 1
1469 if not self.comm.isPrinting():
1470 if self._wizardState == 3:
1471 self._wizardState = 4
1472 wx.CallAfter(self.infoBox.SetAttention, _('Please measure the distance between the vertical lines in millimeters.'))
1473 wx.CallAfter(self.textEntry.SetValue, '0.0')
1474 wx.CallAfter(self.textEntry.Enable, True)
1475 wx.CallAfter(self.resumeButton.Enable, True)
1476 wx.CallAfter(self.resumeButton.SetFocus)
1477 elif self._wizardState == 6:
1478 self._wizardState = 7
1479 wx.CallAfter(self.infoBox.SetAttention, _('Which vertical line number lays perfect on top of each other? Leftmost line is zero.'))
1480 wx.CallAfter(self.textEntry.SetValue, '10')
1481 wx.CallAfter(self.textEntry.Enable, True)
1482 wx.CallAfter(self.resumeButton.Enable, True)
1483 wx.CallAfter(self.resumeButton.SetFocus)
1485 elif self.comm.isError():
1486 wx.CallAfter(self.infoBox.SetError, _('Failed to establish connection with the printer.'), 'http://wiki.ultimaker.com/Cura:_Connection_problems')
1488 def mcMessage(self, message):
1491 def mcProgress(self, lineNr):
1494 def mcZChange(self, newZ):
1497 class bedLevelWizard(wx.wizard.Wizard):
1499 super(bedLevelWizard, self).__init__(None, -1, _("Bed leveling wizard"))
1501 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
1502 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
1504 self.mainPage = bedLevelWizardMain(self)
1505 self.headOffsetCalibration = None
1507 self.FitToPage(self.mainPage)
1508 self.GetPageAreaSizer().Add(self.mainPage)
1510 self.RunWizard(self.mainPage)
1513 def OnPageChanging(self, e):
1514 e.GetPage().StoreData()
1516 def OnPageChanged(self, e):
1517 if e.GetPage().AllowNext():
1518 self.FindWindowById(wx.ID_FORWARD).Enable()
1520 self.FindWindowById(wx.ID_FORWARD).Disable()
1521 if e.GetPage().AllowBack():
1522 self.FindWindowById(wx.ID_BACKWARD).Enable()
1524 self.FindWindowById(wx.ID_BACKWARD).Disable()
1526 class headOffsetWizard(wx.wizard.Wizard):
1528 super(headOffsetWizard, self).__init__(None, -1, _("Head offset wizard"))
1530 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
1531 self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)
1533 self.mainPage = headOffsetCalibrationPage(self)
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()