276 fieldsizer = wx.GridBagSizer(10, 10) |
275 fieldsizer = wx.GridBagSizer(10, 10) |
277 |
276 |
278 # Left Column |
277 # Left Column |
279 |
278 |
280 fieldsizer.Add(wx.StaticText(self.panel, -1, "Layer (mm):"), pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
279 fieldsizer.Add(wx.StaticText(self.panel, -1, "Layer (mm):"), pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
281 self.thickness = wx.TextCtrl(self.panel, -1, str(self._get_setting("project_layer", "0.1")), size = (80, -1)) |
280 self.thickness = wx.TextCtrl(self.panel, -1, str(self._get_setting("project_layer", "0.1")), size = (125, -1)) |
282 self.thickness.Bind(wx.EVT_TEXT, self.update_thickness) |
281 self.thickness.Bind(wx.EVT_TEXT, self.update_thickness) |
283 self.thickness.SetHelpText("The thickness of each slice. Should match the value used to slice the model. SVG files update this value automatically, 3dlp.zip files have to be manually entered.") |
282 self.thickness.SetHelpText("The thickness of each slice. Should match the value used to slice the model. SVG files update this value automatically, 3dlp.zip files have to be manually entered.") |
284 fieldsizer.Add(self.thickness, pos = (0, 1)) |
283 fieldsizer.Add(self.thickness, pos = (0, 1)) |
285 |
284 |
286 fieldsizer.Add(wx.StaticText(self.panel, -1, "Exposure (s):"), pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
285 fieldsizer.Add(wx.StaticText(self.panel, -1, "Exposure (s):"), pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
287 self.interval = wx.TextCtrl(self.panel, -1, str(self._get_setting("project_interval", "0.5")), size = (80, -1)) |
286 self.interval = wx.TextCtrl(self.panel, -1, str(self._get_setting("project_interval", "0.5")), size = (125, -1)) |
288 self.interval.Bind(wx.EVT_TEXT, self.update_interval) |
287 self.interval.Bind(wx.EVT_TEXT, self.update_interval) |
289 self.interval.SetHelpText("How long each slice should be displayed.") |
288 self.interval.SetHelpText("How long each slice should be displayed.") |
290 fieldsizer.Add(self.interval, pos = (1, 1)) |
289 fieldsizer.Add(self.interval, pos = (1, 1)) |
291 |
290 |
292 fieldsizer.Add(wx.StaticText(self.panel, -1, "Blank (s):"), pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
291 fieldsizer.Add(wx.StaticText(self.panel, -1, "Blank (s):"), pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
293 self.pause = wx.TextCtrl(self.panel, -1, str(self._get_setting("project_pause", "0.5")), size = (80, -1)) |
292 self.pause = wx.TextCtrl(self.panel, -1, str(self._get_setting("project_pause", "0.5")), size = (125, -1)) |
294 self.pause.Bind(wx.EVT_TEXT, self.update_pause) |
293 self.pause.Bind(wx.EVT_TEXT, self.update_pause) |
295 self.pause.SetHelpText("The pause length between slices. This should take into account any movement of the Z axis, plus time to prepare the resin surface (sliding, tilting, sweeping, etc).") |
294 self.pause.SetHelpText("The pause length between slices. This should take into account any movement of the Z axis, plus time to prepare the resin surface (sliding, tilting, sweeping, etc).") |
296 fieldsizer.Add(self.pause, pos = (2, 1)) |
295 fieldsizer.Add(self.pause, pos = (2, 1)) |
297 |
296 |
298 fieldsizer.Add(wx.StaticText(self.panel, -1, "Scale:"), pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
297 fieldsizer.Add(wx.StaticText(self.panel, -1, "Scale:"), pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
299 self.scale = floatspin.FloatSpin(self.panel, -1, value = self._get_setting('project_scale', 1.0), increment = 0.1, digits = 3, size = (80, -1)) |
298 self.scale = wx.SpinCtrlDouble(self.panel, -1, initial = self._get_setting('project_scale', 1.0), inc = 0.1, size = (125, -1)) |
300 self.scale.Bind(floatspin.EVT_FLOATSPIN, self.update_scale) |
299 self.scale.SetDigits(3) |
|
300 self.scale.Bind(wx.EVT_SPINCTRLDOUBLE, self.update_scale) |
301 self.scale.SetHelpText("The additional scaling of each slice.") |
301 self.scale.SetHelpText("The additional scaling of each slice.") |
302 fieldsizer.Add(self.scale, pos = (3, 1)) |
302 fieldsizer.Add(self.scale, pos = (3, 1)) |
303 |
303 |
304 fieldsizer.Add(wx.StaticText(self.panel, -1, "Direction:"), pos = (4, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
304 fieldsizer.Add(wx.StaticText(self.panel, -1, "Direction:"), pos = (4, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
305 self.direction = wx.ComboBox(self.panel, -1, choices = ["Top Down", "Bottom Up"], value = self._get_setting('project_direction', "Top Down"), size = (80, -1)) |
305 self.direction = wx.ComboBox(self.panel, -1, choices = ["Top Down", "Bottom Up"], value = self._get_setting('project_direction', "Top Down"), size = (125, -1)) |
306 self.direction.Bind(wx.EVT_COMBOBOX, self.update_direction) |
306 self.direction.Bind(wx.EVT_COMBOBOX, self.update_direction) |
307 self.direction.SetHelpText("The direction the Z axis should move. Top Down is where the projector is above the model, Bottom up is where the projector is below the model.") |
307 self.direction.SetHelpText("The direction the Z axis should move. Top Down is where the projector is above the model, Bottom up is where the projector is below the model.") |
308 fieldsizer.Add(self.direction, pos = (4, 1), flag = wx.ALIGN_CENTER_VERTICAL) |
308 fieldsizer.Add(self.direction, pos = (4, 1), flag = wx.ALIGN_CENTER_VERTICAL) |
309 |
309 |
310 fieldsizer.Add(wx.StaticText(self.panel, -1, "Overshoot (mm):"), pos = (5, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
310 fieldsizer.Add(wx.StaticText(self.panel, -1, "Overshoot (mm):"), pos = (5, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
311 self.overshoot = floatspin.FloatSpin(self.panel, -1, value = self._get_setting('project_overshoot', 3.0), increment = 0.1, digits = 1, min_val = 0, size = (80, -1)) |
311 self.overshoot = wx.SpinCtrlDouble(self.panel, -1, initial = self._get_setting('project_overshoot', 3.0), inc = 0.1, min = 0, size = (125, -1)) |
312 self.overshoot.Bind(floatspin.EVT_FLOATSPIN, self.update_overshoot) |
312 self.overshoot.SetDigits(1) |
|
313 self.overshoot.Bind(wx.EVT_SPINCTRLDOUBLE, self.update_overshoot) |
313 self.overshoot.SetHelpText("How far the axis should move beyond the next slice position for each slice. For Top Down printers this would dunk the model under the resi and then return. For Bottom Up printers this would raise the base away from the vat and then return.") |
314 self.overshoot.SetHelpText("How far the axis should move beyond the next slice position for each slice. For Top Down printers this would dunk the model under the resi and then return. For Bottom Up printers this would raise the base away from the vat and then return.") |
314 fieldsizer.Add(self.overshoot, pos = (5, 1)) |
315 fieldsizer.Add(self.overshoot, pos = (5, 1)) |
315 |
316 |
316 fieldsizer.Add(wx.StaticText(self.panel, -1, "Pre-lift Gcode:"), pos = (6, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
317 fieldsizer.Add(wx.StaticText(self.panel, -1, "Pre-lift Gcode:"), pos = (6, 0), flag = wx.ALIGN_CENTER_VERTICAL) |
317 self.prelift_gcode = wx.TextCtrl(self.panel, -1, str(self._get_setting("project_prelift_gcode", "").replace("\\n", '\n')), size = (-1, 35), style = wx.TE_MULTILINE) |
318 self.prelift_gcode = wx.TextCtrl(self.panel, -1, str(self._get_setting("project_prelift_gcode", "").replace("\\n", '\n')), size = (-1, 35), style = wx.TE_MULTILINE) |
327 |
328 |
328 # Right Column |
329 # Right Column |
329 |
330 |
330 fieldsizer.Add(wx.StaticText(self.panel, -1, "X (px):"), pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
331 fieldsizer.Add(wx.StaticText(self.panel, -1, "X (px):"), pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
331 projectX = int(math.floor(float(self._get_setting("project_x", 1920)))) |
332 projectX = int(math.floor(float(self._get_setting("project_x", 1920)))) |
332 self.X = wx.SpinCtrl(self.panel, -1, str(projectX), max = 999999, size = (80, -1)) |
333 self.X = wx.SpinCtrl(self.panel, -1, str(projectX), max = 999999, size = (125, -1)) |
333 self.X.Bind(wx.EVT_SPINCTRL, self.update_resolution) |
334 self.X.Bind(wx.EVT_SPINCTRL, self.update_resolution) |
334 self.X.SetHelpText("The projector resolution in the X axis.") |
335 self.X.SetHelpText("The projector resolution in the X axis.") |
335 fieldsizer.Add(self.X, pos = (0, 3)) |
336 fieldsizer.Add(self.X, pos = (0, 3)) |
336 |
337 |
337 fieldsizer.Add(wx.StaticText(self.panel, -1, "Y (px):"), pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
338 fieldsizer.Add(wx.StaticText(self.panel, -1, "Y (px):"), pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
338 projectY = int(math.floor(float(self._get_setting("project_y", 1200)))) |
339 projectY = int(math.floor(float(self._get_setting("project_y", 1200)))) |
339 self.Y = wx.SpinCtrl(self.panel, -1, str(projectY), max = 999999, size = (80, -1)) |
340 self.Y = wx.SpinCtrl(self.panel, -1, str(projectY), max = 999999, size = (125, -1)) |
340 self.Y.Bind(wx.EVT_SPINCTRL, self.update_resolution) |
341 self.Y.Bind(wx.EVT_SPINCTRL, self.update_resolution) |
341 self.Y.SetHelpText("The projector resolution in the Y axis.") |
342 self.Y.SetHelpText("The projector resolution in the Y axis.") |
342 fieldsizer.Add(self.Y, pos = (1, 3)) |
343 fieldsizer.Add(self.Y, pos = (1, 3)) |
343 |
344 |
344 fieldsizer.Add(wx.StaticText(self.panel, -1, "OffsetX (mm):"), pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
345 fieldsizer.Add(wx.StaticText(self.panel, -1, "OffsetX (mm):"), pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
345 self.offset_X = floatspin.FloatSpin(self.panel, -1, value = self._get_setting("project_offset_x", 0.0), increment = 1, digits = 1, size = (80, -1)) |
346 self.offset_X = wx.SpinCtrlDouble(self.panel, -1, initial = self._get_setting("project_offset_x", 0.0), inc = 1, size = (125, -1)) |
346 self.offset_X.Bind(floatspin.EVT_FLOATSPIN, self.update_offset) |
347 self.offset_X.SetDigits(1) |
|
348 self.offset_X.Bind(wx.EVT_SPINCTRLDOUBLE, self.update_offset) |
347 self.offset_X.SetHelpText("How far the slice should be offset from the edge in the X axis.") |
349 self.offset_X.SetHelpText("How far the slice should be offset from the edge in the X axis.") |
348 fieldsizer.Add(self.offset_X, pos = (2, 3)) |
350 fieldsizer.Add(self.offset_X, pos = (2, 3)) |
349 |
351 |
350 fieldsizer.Add(wx.StaticText(self.panel, -1, "OffsetY (mm):"), pos = (3, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
352 fieldsizer.Add(wx.StaticText(self.panel, -1, "OffsetY (mm):"), pos = (3, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
351 self.offset_Y = floatspin.FloatSpin(self.panel, -1, value = self._get_setting("project_offset_y", 0.0), increment = 1, digits = 1, size = (80, -1)) |
353 self.offset_Y = wx.SpinCtrlDouble(self.panel, -1, initial = self._get_setting("project_offset_y", 0.0), inc = 1, size = (125, -1)) |
352 self.offset_Y.Bind(floatspin.EVT_FLOATSPIN, self.update_offset) |
354 self.offset_Y.SetDigits(1) |
|
355 self.offset_Y.Bind(wx.EVT_SPINCTRLDOUBLE, self.update_offset) |
353 self.offset_Y.SetHelpText("How far the slice should be offset from the edge in the Y axis.") |
356 self.offset_Y.SetHelpText("How far the slice should be offset from the edge in the Y axis.") |
354 fieldsizer.Add(self.offset_Y, pos = (3, 3)) |
357 fieldsizer.Add(self.offset_Y, pos = (3, 3)) |
355 |
358 |
356 fieldsizer.Add(wx.StaticText(self.panel, -1, "ProjectedX (mm):"), pos = (4, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
359 fieldsizer.Add(wx.StaticText(self.panel, -1, "ProjectedX (mm):"), pos = (4, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
357 self.projected_X_mm = floatspin.FloatSpin(self.panel, -1, value = self._get_setting("project_projected_x", 505.0), increment = 1, digits = 1, size = (80, -1)) |
360 self.projected_X_mm = wx.SpinCtrlDouble(self.panel, -1, initial = self._get_setting("project_projected_x", 505.0), inc = 1, size = (125, -1)) |
358 self.projected_X_mm.Bind(floatspin.EVT_FLOATSPIN, self.update_projected_Xmm) |
361 self.projected_X_mm.SetDigits(1) |
|
362 self.projected_X_mm.Bind(wx.EVT_SPINCTRLDOUBLE, self.update_projected_Xmm) |
359 self.projected_X_mm.SetHelpText("The actual width of the entire projected image. Use the Calibrate grid to show the full size of the projected image, and measure the width at the same level where the slice will be projected onto the resin.") |
363 self.projected_X_mm.SetHelpText("The actual width of the entire projected image. Use the Calibrate grid to show the full size of the projected image, and measure the width at the same level where the slice will be projected onto the resin.") |
360 fieldsizer.Add(self.projected_X_mm, pos = (4, 3)) |
364 fieldsizer.Add(self.projected_X_mm, pos = (4, 3)) |
361 |
365 |
362 fieldsizer.Add(wx.StaticText(self.panel, -1, "Z Axis Speed (mm/min):"), pos = (5, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
366 fieldsizer.Add(wx.StaticText(self.panel, -1, "Z Axis Speed (mm/min):"), pos = (5, 2), flag = wx.ALIGN_CENTER_VERTICAL) |
363 self.z_axis_rate = wx.SpinCtrl(self.panel, -1, str(self._get_setting("project_z_axis_rate", 200)), max = 9999, size = (80, -1)) |
367 self.z_axis_rate = wx.SpinCtrl(self.panel, -1, str(self._get_setting("project_z_axis_rate", 200)), max = 9999, size = (125, -1)) |
364 self.z_axis_rate.Bind(wx.EVT_SPINCTRL, self.update_z_axis_rate) |
368 self.z_axis_rate.Bind(wx.EVT_SPINCTRL, self.update_z_axis_rate) |
365 self.z_axis_rate.SetHelpText("Speed of the Z axis in mm/minute. Take into account that slower rates may require a longer pause value.") |
369 self.z_axis_rate.SetHelpText("Speed of the Z axis in mm/minute. Take into account that slower rates may require a longer pause value.") |
366 fieldsizer.Add(self.z_axis_rate, pos = (5, 3)) |
370 fieldsizer.Add(self.z_axis_rate, pos = (5, 3)) |
367 |
371 |
368 fieldboxsizer.Add(fieldsizer) |
372 fieldboxsizer.Add(fieldsizer) |
392 self.first_layer.SetHelpText("Displays the first layer of the model. Use this to project the first layer for longer so it holds to the base. Note: this value does not affect the first layer when the \"Present\" run is started, it should be used manually.") |
396 self.first_layer.SetHelpText("Displays the first layer of the model. Use this to project the first layer for longer so it holds to the base. Note: this value does not affect the first layer when the \"Present\" run is started, it should be used manually.") |
393 |
397 |
394 first_layer_boxer.Add(self.first_layer, flag = wx.ALIGN_CENTER_VERTICAL) |
398 first_layer_boxer.Add(self.first_layer, flag = wx.ALIGN_CENTER_VERTICAL) |
395 |
399 |
396 first_layer_boxer.Add(wx.StaticText(self.panel, -1, " (s):"), flag = wx.ALIGN_CENTER_VERTICAL) |
400 first_layer_boxer.Add(wx.StaticText(self.panel, -1, " (s):"), flag = wx.ALIGN_CENTER_VERTICAL) |
397 self.show_first_layer_timer = floatspin.FloatSpin(self.panel, -1, value=-1, increment = 1, digits = 1, size = (55, -1)) |
401 self.show_first_layer_timer = wx.SpinCtrlDouble(self.panel, -1, initial = -1, inc = 1, size = (125, -1)) |
|
402 self.show_first_layer_timer.SetDigits(1) |
398 self.show_first_layer_timer.SetHelpText("How long to display the first layer for. -1 = unlimited.") |
403 self.show_first_layer_timer.SetHelpText("How long to display the first layer for. -1 = unlimited.") |
399 first_layer_boxer.Add(self.show_first_layer_timer, flag = wx.ALIGN_CENTER_VERTICAL) |
404 first_layer_boxer.Add(self.show_first_layer_timer, flag = wx.ALIGN_CENTER_VERTICAL) |
400 displaysizer.Add(first_layer_boxer, pos = (0, 6), flag = wx.ALIGN_CENTER_VERTICAL) |
405 displaysizer.Add(first_layer_boxer, pos = (0, 6), flag = wx.ALIGN_CENTER_VERTICAL) |
401 |
406 |
402 displaysizer.Add(wx.StaticText(self.panel, -1, "Red:"), pos = (0, 7), flag = wx.ALIGN_CENTER_VERTICAL) |
407 displaysizer.Add(wx.StaticText(self.panel, -1, "Red:"), pos = (0, 7), flag = wx.ALIGN_CENTER_VERTICAL) |
646 pixelsYPerMM = resolution_y_pixels / projectedYmm |
651 pixelsYPerMM = resolution_y_pixels / projectedYmm |
647 |
652 |
648 gridCountX = int(projectedXmm / 10) |
653 gridCountX = int(projectedXmm / 10) |
649 gridCountY = int(projectedYmm / 10) |
654 gridCountY = int(projectedYmm / 10) |
650 |
655 |
651 for y in xrange(0, gridCountY + 1): |
656 for y in range(0, gridCountY + 1): |
652 for x in xrange(0, gridCountX + 1): |
657 for x in range(0, gridCountX + 1): |
653 dc.DrawLine(0, y * (pixelsYPerMM * 10), resolution_x_pixels, y * (pixelsYPerMM * 10)) |
658 dc.DrawLine(0, y * (pixelsYPerMM * 10), resolution_x_pixels, y * (pixelsYPerMM * 10)) |
654 dc.DrawLine(x * (pixelsXPerMM * 10), 0, x * (pixelsXPerMM * 10), resolution_y_pixels) |
659 dc.DrawLine(x * (pixelsXPerMM * 10), 0, x * (pixelsXPerMM * 10), resolution_y_pixels) |
655 |
660 |
656 self.first_layer.SetValue(False) |
661 self.first_layer.SetValue(False) |
657 self.display_frame.slicer = 'bitmap' |
662 self.display_frame.slicer = 'bitmap' |
658 self.display_frame.draw_layer(gridBitmap.ConvertToImage()) |
663 self.display_frame.draw_layer(gridBitmap.ConvertToImage()) |
659 |
664 |
660 def present_first_layer(self, event): |
665 def present_first_layer(self, event): |
661 if (self.first_layer.GetValue()): |
666 if (self.first_layer.GetValue()): |
662 if not hasattr(self, "layers"): |
667 if not hasattr(self, "layers"): |
663 print "No model loaded!" |
668 print("No model loaded!") |
664 self.first_layer.SetValue(False) |
669 self.first_layer.SetValue(False) |
665 return |
670 return |
666 self.display_frame.offset = (float(self.offset_X.GetValue()), float(self.offset_Y.GetValue())) |
671 self.display_frame.offset = (float(self.offset_X.GetValue()), float(self.offset_Y.GetValue())) |
667 self.display_frame.scale = float(self.scale.GetValue()) |
672 self.display_frame.scale = float(self.scale.GetValue()) |
668 |
673 |