chiark / gitweb /
Add temperature for simple mode, #192
[cura.git] / Cura / gui / simpleMode.py
1 from __future__ import absolute_import
2 import __init__
3
4 import wx, os, platform, types, webbrowser
5
6 from gui import configBase
7 from gui import preview3d
8 from gui import sliceProgessPanel
9 from gui import preferencesDialog
10 from gui import configWizard
11 from gui import firmwareInstall
12 from gui import printWindow
13 from gui import icon
14 from util import validators
15 from util import profile
16 from util import version
17 from util import sliceRun
18
19 class simpleModeWindow(configBase.configWindowBase):
20         "Main user interface window for Quickprint mode"
21         def __init__(self):
22                 super(simpleModeWindow, self).__init__(title='Cura - Quickprint - ' + version.getVersion())
23                 
24                 wx.EVT_CLOSE(self, self.OnClose)
25                 #self.SetIcon(icon.getMainIcon())
26                 
27                 menubar = wx.MenuBar()
28                 fileMenu = wx.Menu()
29                 i = fileMenu.Append(-1, 'Load model file...')
30                 self.Bind(wx.EVT_MENU, self.OnLoadModel, i)
31                 fileMenu.AppendSeparator()
32                 i = fileMenu.Append(-1, 'Preferences...')
33                 self.Bind(wx.EVT_MENU, self.OnPreferences, i)
34                 fileMenu.AppendSeparator()
35                 i = fileMenu.Append(wx.ID_EXIT, 'Quit')
36                 self.Bind(wx.EVT_MENU, self.OnQuit, i)
37                 menubar.Append(fileMenu, '&File')
38                 
39                 expertMenu = wx.Menu()
40                 i = expertMenu.Append(-1, 'Switch to Normal mode...')
41                 self.Bind(wx.EVT_MENU, self.OnNormalSwitch, i)
42                 expertMenu.AppendSeparator()
43                 i = expertMenu.Append(-1, 'ReRun first run wizard...')
44                 self.Bind(wx.EVT_MENU, self.OnFirstRunWizard, i)
45                 menubar.Append(expertMenu, 'Expert')
46                 
47                 helpMenu = wx.Menu()
48                 i = helpMenu.Append(-1, 'Online documentation...')
49                 self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://github.com/daid/Cura/wiki'), i)
50                 i = helpMenu.Append(-1, 'Report a problem...')
51                 self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://github.com/daid/Cura/issues'), i)
52                 menubar.Append(helpMenu, 'Help')
53                 self.SetMenuBar(menubar)
54                 
55                 if profile.getPreference('lastFile') != '':
56                         self.filelist = profile.getPreference('lastFile').split(';')
57                         self.SetTitle(self.filelist[-1] + ' - Cura - ' + version.getVersion())
58                 else:
59                         self.filelist = []
60                 self.progressPanelList = []
61
62                 #Preview window
63                 self.preview3d = preview3d.previewPanel(self)
64
65                 configPanel = wx.Panel(self)
66                 self.printTypeNormal = wx.RadioButton(configPanel, -1, 'Normal quality print', style=wx.RB_GROUP)
67                 self.printTypeLow = wx.RadioButton(configPanel, -1, 'Fast low quality print')
68                 self.printTypeHigh = wx.RadioButton(configPanel, -1, 'High quality print')
69                 self.printTypeJoris = wx.RadioButton(configPanel, -1, 'Thin walled cup or vase')
70
71                 self.printMaterialPLA = wx.RadioButton(configPanel, -1, 'PLA', style=wx.RB_GROUP)
72                 self.printMaterialABS = wx.RadioButton(configPanel, -1, 'ABS')
73                 self.printMaterialDiameter = wx.TextCtrl(configPanel, -1, profile.getProfileSetting('filament_diameter'))
74                 
75                 self.printSupport = wx.CheckBox(configPanel, -1, 'Print support structure')
76                 
77                 sizer = wx.GridBagSizer()
78                 configPanel.SetSizer(sizer)
79
80                 sb = wx.StaticBox(configPanel, label="Select a print type:")
81                 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
82                 boxsizer.Add(self.printTypeNormal)
83                 boxsizer.Add(self.printTypeLow)
84                 boxsizer.Add(self.printTypeHigh)
85                 boxsizer.Add(self.printTypeJoris)
86                 sizer.Add(boxsizer, (0,0), flag=wx.EXPAND)
87
88                 sb = wx.StaticBox(configPanel, label="Material:")
89                 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
90                 boxsizer.Add(self.printMaterialPLA)
91                 boxsizer.Add(self.printMaterialABS)
92                 boxsizer.Add(wx.StaticText(configPanel, -1, 'Diameter:'))
93                 boxsizer.Add(self.printMaterialDiameter)
94                 sizer.Add(boxsizer, (1,0), flag=wx.EXPAND)
95
96                 sb = wx.StaticBox(configPanel, label="Other:")
97                 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
98                 boxsizer.Add(self.printSupport)
99                 sizer.Add(boxsizer, (2,0), flag=wx.EXPAND)
100
101                 # load and slice buttons.
102                 loadButton = wx.Button(self, -1, 'Load Model')
103                 sliceButton = wx.Button(self, -1, 'Prepare print')
104                 printButton = wx.Button(self, -1, 'Print')
105                 self.Bind(wx.EVT_BUTTON, self.OnLoadModel, loadButton)
106                 self.Bind(wx.EVT_BUTTON, self.OnSlice, sliceButton)
107                 self.Bind(wx.EVT_BUTTON, self.OnPrint, printButton)
108                 #Also bind double clicking the 3D preview to load an STL file.
109                 self.preview3d.glCanvas.Bind(wx.EVT_LEFT_DCLICK, self.OnLoadModel, self.preview3d.glCanvas)
110
111                 #Main sizer, to position the preview window, buttons and tab control
112                 sizer = wx.GridBagSizer()
113                 self.SetSizer(sizer)
114                 sizer.Add(configPanel, (0,0), span=(1,1), flag=wx.EXPAND)
115                 sizer.Add(self.preview3d, (0,1), span=(1,3), flag=wx.EXPAND)
116                 sizer.AddGrowableCol(2)
117                 sizer.AddGrowableRow(0)
118                 sizer.Add(loadButton, (1,1), flag=wx.RIGHT, border=5)
119                 sizer.Add(sliceButton, (1,2), flag=wx.RIGHT, border=5)
120                 sizer.Add(printButton, (1,3), flag=wx.RIGHT, border=5)
121                 self.sizer = sizer
122
123                 if len(self.filelist) > 0:
124                         self.preview3d.loadModelFiles(self.filelist)
125
126                 self.updateProfileToControls()
127
128                 self.Fit()
129                 self.SetMinSize(self.GetSize())
130                 self.Centre()
131                 self.Show(True)
132         
133         def OnPreferences(self, e):
134                 prefDialog = preferencesDialog.preferencesDialog(self)
135                 prefDialog.Centre()
136                 prefDialog.Show(True)
137         
138         def OnDefaultMarlinFirmware(self, e):
139                 firmwareInstall.InstallFirmware()
140
141         def OnCustomFirmware(self, e):
142                 dlg=wx.FileDialog(self, "Open firmware to upload", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
143                 dlg.SetWildcard("HEX file (*.hex)|*.hex;*.HEX")
144                 if dlg.ShowModal() == wx.ID_OK:
145                         filename = dlg.GetPath()
146                         if not(os.path.exists(filename)):
147                                 return
148                         #For some reason my Ubuntu 10.10 crashes here.
149                         firmwareInstall.InstallFirmware(filename)
150
151         def OnFirstRunWizard(self, e):
152                 configWizard.configWizard()
153                 self.updateProfileToControls()
154
155         def OnLoadModel(self, e):
156                 dlg=wx.FileDialog(self, "Open file to print", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
157                 dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL")
158                 if dlg.ShowModal() == wx.ID_OK:
159                         self.filelist = [dlg.GetPath()]
160                         profile.putPreference('lastFile', ';'.join(self.filelist))
161                         self.preview3d.loadModelFiles(self.filelist, True)
162                         self.preview3d.setViewMode("Normal")
163                 dlg.Destroy()
164         
165         def OnSlice(self, e):
166                 if len(self.filelist) < 1:
167                         wx.MessageBox('You need to load a file before you can slice it.', 'Print error', wx.OK | wx.ICON_INFORMATION)
168                         return
169                 #save the current profile so we can put it back latter
170                 oldProfile = profile.getGlobalProfileString()
171                 
172                 put = profile.putProfileSetting
173                 get = profile.getProfileSetting
174
175                 put('layer_height', '0.2')
176                 put('wall_thickness', '0.8')
177                 put('solid_layer_thickness', '0.6')
178                 put('fill_density', '20')
179                 put('skirt_line_count', '1')
180                 put('skirt_gap', '6.0')
181                 put('print_speed', '50')
182                 put('print_temperature', '230')
183                 put('support', 'None')
184                 #put('machine_center_x', '100')
185                 #put('machine_center_y', '100')
186                 #put('retraction_min_travel', '5.0')
187                 #put('retraction_speed', '13.5')
188                 #put('retraction_amount', '0.0')
189                 #put('retraction_extra', '0.0')
190                 put('travel_speed', '150')
191                 put('max_z_speed', '3.0')
192                 put('bottom_layer_speed', '25')
193                 put('cool_min_layer_time', '10')
194                 put('fan_enabled', 'True')
195                 put('fan_layer', '1')
196                 put('fan_speed', '100')
197                 #put('model_scale', '1.0')
198                 #put('flip_x', 'False')
199                 #put('flip_y', 'False')
200                 #put('flip_z', 'False')
201                 #put('model_rotate_base', '0')
202                 #put('model_multiply_x', '1')
203                 #put('model_multiply_y', '1')
204                 put('extra_base_wall_thickness', '0.0')
205                 put('sequence', 'Loops > Perimeter > Infill')
206                 put('force_first_layer_sequence', 'True')
207                 put('infill_type', 'Line')
208                 put('solid_top', 'True')
209                 put('fill_overlap', '15')
210                 put('support_rate', '50')
211                 put('support_distance', '0.5')
212                 put('joris', 'False')
213                 put('cool_min_feedrate', '5')
214                 put('bridge_speed', '100')
215                 put('raft_margin', '5')
216                 put('raft_base_material_amount', '100')
217                 put('raft_interface_material_amount', '100')
218                 put('bottom_thickness', '0.0')
219
220                 if self.printSupport.GetValue():
221                         put('support', 'Exterior Only')
222
223                 nozzle_size = float(get('nozzle_size'))
224                 if self.printTypeNormal.GetValue():
225                         put('wall_thickness', nozzle_size * 2.0)
226                         put('layer_height', '0.2')
227                         put('fill_density', '20')
228                 elif self.printTypeLow.GetValue():
229                         put('wall_thickness', nozzle_size * 1.0)
230                         put('layer_height', '0.3')
231                         put('fill_density', '10')
232                         put('print_speed', '80')
233                         put('bottom_layer_speed', '40')
234                 elif self.printTypeHigh.GetValue():
235                         put('wall_thickness', nozzle_size * 3.0)
236                         put('layer_height', '0.1')
237                         put('fill_density', '30')
238                         put('bottom_layer_speed', '15')
239                         put('bottom_thickness', '0.2')
240                 elif self.printTypeJoris.GetValue():
241                         put('wall_thickness', nozzle_size * 1.5)
242                         put('layer_height', '0.3')
243                         put('fill_density', '0')
244                         put('joris', 'True')
245                         put('extra_base_wall_thickness', '15.0')
246                         put('sequence', 'Infill > Loops > Perimeter')
247                         put('force_first_layer_sequence', 'False')
248                         put('solid_top', 'False')
249                         put('support', 'None')
250                         put('cool_min_layer_time', '3')
251
252                 put('filament_diameter', self.printMaterialDiameter.GetValue())
253                 if self.printMaterialPLA.GetValue():
254                         put('filament_density', '1.00')
255                         put('enable_raft', 'False')
256                         put('skirt_line_count', '1')
257                 if self.printMaterialABS.GetValue():
258                         put('filament_density', '0.85')
259                         put('enable_raft', 'True')
260                         put('skirt_line_count', '0')
261                         put('fan_layer', '1')
262                         put('bottom_thickness', '0.0')
263                         put('print_temperature', '260')
264                 
265                 #Create a progress panel and add it to the window. The progress panel will start the Skein operation.
266                 spp = sliceProgessPanel.sliceProgessPanel(self, self, self.filelist)
267                 self.sizer.Add(spp, (len(self.progressPanelList)+2,0), span=(1,4), flag=wx.EXPAND)
268                 self.sizer.Layout()
269                 newSize = self.GetSize();
270                 newSize.IncBy(0, spp.GetSize().GetHeight())
271                 self.SetSize(newSize)
272                 self.progressPanelList.append(spp)
273                 
274                 #Restore the old profile.
275                 profile.loadGlobalProfileFromString(oldProfile)
276         
277         def OnPrint(self, e):
278                 if len(self.filelist) < 1:
279                         wx.MessageBox('You need to load a file and slice it before you can print it.', 'Print error', wx.OK | wx.ICON_INFORMATION)
280                         return
281                 if not os.path.exists(sliceRun.getExportFilename(self.filelist[0])):
282                         wx.MessageBox('You need to slice the file to GCode before you can print it.', 'Print error', wx.OK | wx.ICON_INFORMATION)
283                         return
284                 printWindow.printFile(sliceRun.getExportFilename(self.filelist[0]))
285
286         def OnNormalSwitch(self, e):
287                 from gui import mainWindow
288                 profile.putPreference('startMode', 'Normal')
289                 mainWindow.mainWindow()
290                 self.Close()
291
292         def removeSliceProgress(self, spp):
293                 self.progressPanelList.remove(spp)
294                 newSize = self.GetSize();
295                 newSize.IncBy(0, -spp.GetSize().GetHeight())
296                 self.SetSize(newSize)
297                 self.sizer.Remove(spp)
298                 spp.Destroy()
299                 for spp in self.progressPanelList:
300                         self.sizer.Remove(spp)
301                 i = 2
302                 for spp in self.progressPanelList:
303                         self.sizer.Add(spp, (i,0), span=(1,4), flag=wx.EXPAND)
304                         i += 1
305                 self.sizer.Layout()
306
307         def OnQuit(self, e):
308                 self.Close()
309         
310         def OnClose(self, e):
311                 self.Destroy()
312
313         def updateProfileToControls(self):
314                 super(simpleModeWindow, self).updateProfileToControls()
315                 self.preview3d.updateProfileToControls()
316