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