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 printWindow
14 from util import validators
15 from util import profile
16 from util import version
17 from util import sliceRun
19 class simpleModeWindow(configBase.configWindowBase):
20 "Main user interface window for Quickprint mode"
22 super(simpleModeWindow, self).__init__(title='Cura - Quickprint - ' + version.getVersion())
24 wx.EVT_CLOSE(self, self.OnClose)
25 #self.SetIcon(icon.getMainIcon())
27 menubar = wx.MenuBar()
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')
40 i = toolsMenu.Append(-1, 'Switch to Normal mode...')
41 self.Bind(wx.EVT_MENU, self.OnNormalSwitch, i)
42 menubar.Append(toolsMenu, 'Normal mode')
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)
52 if profile.getPreference('lastFile') != '':
53 self.filelist = profile.getPreference('lastFile').split(';')
54 self.SetTitle(self.filelist[-1] + ' - Cura - ' + version.getVersion())
57 self.progressPanelList = []
60 self.preview3d = preview3d.previewPanel(self)
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')
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'))
72 self.printSupport = wx.CheckBox(configPanel, -1, 'Print support structure')
74 sizer = wx.GridBagSizer()
75 configPanel.SetSizer(sizer)
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)
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)
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)
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)
108 #Main sizer, to position the preview window, buttons and tab control
109 sizer = wx.GridBagSizer()
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)
120 if len(self.filelist) > 0:
121 self.preview3d.loadModelFiles(self.filelist)
123 self.updateProfileToControls()
126 self.SetMinSize(self.GetSize())
130 def OnPreferences(self, e):
131 prefDialog = preferencesDialog.preferencesDialog(self)
133 prefDialog.Show(True)
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")
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)
149 #save the current profile so we can put it back latter
150 oldProfile = profile.getGlobalProfileString()
152 put = profile.putProfileSetting
153 get = profile.getProfileSetting
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')
201 if self.printSupport.GetValue():
202 put('support', 'Exterior Only')
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')
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')
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')
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)
252 newSize = self.GetSize();
253 newSize.IncBy(0, spp.GetSize().GetHeight())
254 self.SetSize(newSize)
255 self.progressPanelList.append(spp)
257 #Restore the old profile.
258 profile.loadGlobalProfileFromString(oldProfile)
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)
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)
267 printWindow.printFile(sliceRun.getExportFilename(self.filelist[0]))
269 def OnNormalSwitch(self, e):
270 from gui import mainWindow
271 profile.putPreference('startMode', 'Normal')
272 mainWindow.mainWindow()
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)
282 for spp in self.progressPanelList:
283 self.sizer.Remove(spp)
285 for spp in self.progressPanelList:
286 self.sizer.Add(spp, (i,0), span=(1,4), flag=wx.EXPAND)
293 def OnClose(self, e):
296 def updateProfileToControls(self):
297 super(simpleModeWindow, self).updateProfileToControls()
298 self.preview3d.updateProfileToControls()