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