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