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