chiark / gitweb /
Add layer slider. Solve the issue where loading a new file takes a long time and...
authordaid303 <daid303@gmail.com>
Thu, 28 Feb 2013 08:32:58 +0000 (09:32 +0100)
committerdaid303 <daid303@gmail.com>
Thu, 28 Feb 2013 08:32:58 +0000 (09:32 +0100)
Cura/gui/preview3d.py
Cura/gui/util/openglGui.py
Cura/util/gcodeInterpreter.py
Cura/util/profile.py

index 69ab9bebe30b00e424b49a60db55ca1a49884d7e..046f70c9523fe9923797f1916387cd585cc58f0e 100644 (file)
@@ -22,7 +22,6 @@ from Cura.util import util3d
 from Cura.util import sliceRun
 
 from Cura.gui.util import opengl
-from Cura.gui.util import toolbarUtil
 from Cura.gui.util import previewTools
 from Cura.gui.util import openglGui
 
@@ -72,31 +71,7 @@ class previewPanel(wx.Panel):
                parent.Bind(wx.EVT_MOVE, self.OnMove)
                parent.Bind(wx.EVT_SIZE, self.OnMove)
                
-               self.toolbar = toolbarUtil.Toolbar(self)
-
-               group = []
-               toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick)
-               toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick)
-               self.toolbar.AddSeparator()
-
-               self.showBorderButton = toolbarUtil.ToggleButton(self.toolbar, '', 'view-border-on.png', 'view-border-off.png', 'Show model borders', callback=self.OnViewChange)
-               self.showSteepOverhang = toolbarUtil.ToggleButton(self.toolbar, '', 'steepOverhang-on.png', 'steepOverhang-off.png', 'Show steep overhang', callback=self.OnViewChange)
-               self.toolbar.AddSeparator()
-
-               group = []
-               self.normalViewButton = toolbarUtil.RadioButton(self.toolbar, group, 'view-normal-on.png', 'view-normal-off.png', 'Normal model view', callback=self.OnViewChange)
-               self.transparentViewButton = toolbarUtil.RadioButton(self.toolbar, group, 'view-transparent-on.png', 'view-transparent-off.png', 'Transparent model view', callback=self.OnViewChange)
-               self.xrayViewButton = toolbarUtil.RadioButton(self.toolbar, group, 'view-xray-on.png', 'view-xray-off.png', 'X-Ray view', callback=self.OnViewChange)
-               self.gcodeViewButton = toolbarUtil.RadioButton(self.toolbar, group, 'view-gcode-on.png', 'view-gcode-off.png', 'GCode view', callback=self.OnViewChange)
-               self.mixedViewButton = toolbarUtil.RadioButton(self.toolbar, group, 'view-mixed-on.png', 'view-mixed-off.png', 'Mixed model/GCode view', callback=self.OnViewChange)
-               self.toolbar.AddSeparator()
-
-               self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS)
-               self.toolbar.AddControl(self.layerSpin)
-               self.Bind(wx.EVT_SPINCTRL, self.OnLayerNrChange, self.layerSpin)
-
                sizer = wx.BoxSizer(wx.VERTICAL)
-               sizer.Add(self.toolbar, 0, flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, border=1)
                sizer.Add(self.glCanvas, 1, flag=wx.EXPAND)
                self.SetSizer(sizer)
                
@@ -149,6 +124,7 @@ class previewPanel(wx.Panel):
                self.scaleUniform = openglGui.glCheckbox(self.scaleForm, True, (1,8), None)
 
                self.viewSelection = openglGui.glComboButton(self.glCanvas, 'View mode', [0,1,2,3,4], ['3D Model', 'Transparent', 'X-Ray', 'Overhang', 'Layers'], (-1,0), self.OnViewChange)
+               self.layerSelect = openglGui.glSlider(self.glCanvas, 0, 0, 100, (-1,-1), self.OnLayerNrChange)
 
                self.OnViewChange()
                self.OnToolSelect()
@@ -330,15 +306,14 @@ class previewPanel(wx.Panel):
                self.glCanvas.offsetY = 0
                self.glCanvas.Refresh()
 
-       def OnLayerNrChange(self, e):
+       def OnLayerNrChange(self):
                self.glCanvas.Refresh()
        
        def setViewMode(self, mode):
                if mode == "Normal":
-                       self.normalViewButton.SetValue(True)
+                       self.viewSelection.setValue(0)
                if mode == "GCode":
-                       self.gcodeViewButton.SetValue(True)
-               self.glCanvas.viewMode = mode
+                       self.viewSelection.setValue(5)
                wx.CallAfter(self.glCanvas.Refresh)
        
        def loadModelFiles(self, filelist, showWarning = False):
@@ -358,7 +333,9 @@ class previewPanel(wx.Panel):
                self.gcodeFilename = sliceRun.getExportFilename(filelist[0])
                #Do the STL file loading in a background thread so we don't block the UI.
                if self.loadThread is not None and self.loadThread.isAlive():
+                       self.abortLoading = True
                        self.loadThread.join()
+               self.abortLoading = False
                self.loadThread = threading.Thread(target=self.doFileLoadThread)
                self.loadThread.daemon = True
                self.loadThread.start()
@@ -408,7 +385,7 @@ class previewPanel(wx.Panel):
                                obj.steepDirty = True
                                self.updateModelTransform()
                                self.OnScaleMax(True)
-                               self.glCanvas.zoom = numpy.max(self.objectsSize) * 3.5
+                               self.glCanvas.zoom = self.objectsBoundaryCircleSize * 6.0
                                self.errorList = []
                                wx.CallAfter(self.updateToolbar)
                                wx.CallAfter(self.glCanvas.Refresh)
@@ -438,7 +415,7 @@ class previewPanel(wx.Panel):
                wx.CallAfter(self.checkReloadFileTimer.Start, 1000)
        
        def loadProgress(self, progress):
-               pass
+               return self.abortLoading
 
        def OnResetAll(self, e = None):
                profile.putProfileSetting('model_matrix', '1,0,0,0,1,0,0,0,1')
@@ -470,19 +447,15 @@ class previewPanel(wx.Panel):
                self.warningPopup.timer.Stop()
 
        def updateToolbar(self):
-               self.gcodeViewButton.Show(self.gcode is not None)
-               self.mixedViewButton.Show(self.gcode is not None)
-               self.layerSpin.Show(self.glCanvas.viewMode == "GCode" or self.glCanvas.viewMode == "Mixed")
                self.printButton.setDisabled(self.gcode is None)
                if self.gcode is not None:
-                       self.layerSpin.SetRange(1, len(self.gcode.layerList) - 1)
-               self.toolbar.Realize()
+                       self.layerSelect.setRange(1, len(self.gcode.layerList) - 1)
                self.Update()
        
        def OnViewChange(self):
                selection = self.viewSelection.getValue()
                self.glCanvas.drawSteepOverhang = False
-               self.glCanvas.drawBorders = self.showBorderButton.GetValue()
+               self.glCanvas.drawBorders = False
                if selection == 0:
                        self.glCanvas.viewMode = "Normal"
                elif selection == 1:
@@ -493,10 +466,11 @@ class previewPanel(wx.Panel):
                        self.glCanvas.viewMode = "Normal"
                        self.glCanvas.drawSteepOverhang = True
                elif selection == 4:
-                       self.layerSpin.SetValue(self.layerSpin.GetMax())
+                       self.layerSelect.setValue(self.layerSelect.getMaxValue())
                        self.glCanvas.viewMode = "GCode"
                elif selection == 5:
                        self.glCanvas.viewMode = "Mixed"
+               self.layerSelect.setHidden(self.glCanvas.viewMode != "GCode")
                self.updateToolbar()
                self.glCanvas.Refresh()
        
@@ -659,8 +633,8 @@ class PreviewGLCanvas(openglGui.glGuiPanel):
                        glRotate(self.yaw, 0,0,1)
 
                        if self.viewMode == "GCode" or self.viewMode == "Mixed":
-                               if self.parent.gcode is not None and len(self.parent.gcode.layerList) > self.parent.layerSpin.GetValue() and len(self.parent.gcode.layerList[self.parent.layerSpin.GetValue()]) > 0:
-                                       self.viewTarget[2] = self.parent.gcode.layerList[self.parent.layerSpin.GetValue()][0].list[-1].z
+                               if self.parent.gcode is not None and len(self.parent.gcode.layerList) > self.parent.layerSelect.getValue() and len(self.parent.gcode.layerList[self.parent.layerSelect.getValue()]) > 0:
+                                       self.viewTarget[2] = self.parent.gcode.layerList[self.parent.layerSelect.getValue()][0].list[-1].z
                        else:
                                if self.parent.objectsMaxV is not None:
                                        self.viewTarget = self.getObjectCenterPos()
@@ -725,11 +699,11 @@ class PreviewGLCanvas(openglGui.glGuiPanel):
                                glTranslate(self.parent.machineCenter.x, self.parent.machineCenter.y, 0)
                        glEnable(GL_COLOR_MATERIAL)
                        glEnable(GL_LIGHTING)
-                       drawUpToLayer = min(self.gcodeDisplayListMade, self.parent.layerSpin.GetValue() + 1)
+                       drawUpToLayer = min(self.gcodeDisplayListMade, self.parent.layerSelect.getValue() + 1)
                        starttime = time.time()
                        for i in xrange(drawUpToLayer - 1, -1, -1):
                                c = 1.0
-                               if i < self.parent.layerSpin.GetValue():
+                               if i < self.parent.layerSelect.getValue():
                                        c = 0.9 - (drawUpToLayer - i) * 0.1
                                        if c < 0.4:
                                                c = (0.4 + c) / 2
index dd7cf2464ac543d7b53cb1904551d3eefcca2da6..726b6727fabb9068df7e9f74dd007562b15b0893 100644 (file)
@@ -2,6 +2,8 @@ from __future__ import absolute_import
 from __future__ import division
 
 import wx
+import math
+
 from wx import glcanvas
 import OpenGL
 OpenGL.ERROR_CHECKING = False
@@ -51,6 +53,9 @@ class glGuiControl(object):
        def hasFocus(self):
                return self._base._focus == self
 
+       def OnMouseUp(self, x, y):
+               pass
+
        def OnKeyChar(self, key):
                pass
 
@@ -70,6 +75,12 @@ class glGuiContainer(glGuiControl):
                                return True
                return False
 
+       def OnMouseUp(self, x, y):
+               for ctrl in self._glGuiControlList:
+                       if ctrl.OnMouseUp(x, y):
+                               return True
+               return False
+
        def OnMouseMotion(self, x, y):
                handled = False
                for ctrl in self._glGuiControlList:
@@ -103,6 +114,7 @@ class glGuiPanel(glcanvas.GLCanvas):
                wx.EVT_SIZE(self, self._OnSize)
                wx.EVT_ERASE_BACKGROUND(self, self._OnEraseBackground)
                wx.EVT_LEFT_DOWN(self, self._OnGuiMouseLeftDown)
+               wx.EVT_LEFT_UP(self, self._OnGuiMouseLeftUp)
                wx.EVT_MOTION(self, self._OnGuiMouseMotion)
                wx.EVT_CHAR(self, self.OnKeyChar)
                wx.EVT_KILL_FOCUS(self, self.OnFocusLost)
@@ -122,6 +134,11 @@ class glGuiPanel(glcanvas.GLCanvas):
                        self.Refresh()
                        return
                self.OnMouseLeftDown(e)
+       def _OnGuiMouseLeftUp(self, e):
+               if self._container.OnMouseUp(e.GetX(), e.GetY()):
+                       self.Refresh()
+                       return
+               self.OnMouseLeftUp(e)
 
        def _OnGuiMouseMotion(self,e):
                self.Refresh()
@@ -132,9 +149,11 @@ class glGuiPanel(glcanvas.GLCanvas):
                h = self.GetSize().GetHeight()
                w = self.GetSize().GetWidth()
                oldButtonSize = self._buttonSize
-               if h / 3 > w / 4:
+               if h / 3 < w / 4:
                        w = h * 4 / 3
-               if w < 64 * 10:
+               if w < 64 * 8:
+                       self._buttonSize = 32
+               elif w < 64 * 10:
                        self._buttonSize = 48
                elif w < 64 * 15:
                        self._buttonSize = 64
@@ -181,6 +200,8 @@ class glGuiPanel(glcanvas.GLCanvas):
 
        def OnMouseLeftDown(self,e):
                pass
+       def OnMouseLeftUp(self,e):
+               pass
        def OnMouseMotion(self, e):
                pass
        def OnPaint(self, e):
@@ -198,7 +219,7 @@ class glGuiLayoutButtons(object):
        def update(self):
                bs = self._parent._base._buttonSize
                x0, y0, w, h = self._parent.getSize()
-               gridSize = bs * 1.3
+               gridSize = bs * 1.2
                for ctrl in self._parent._glGuiControlList:
                        pos = ctrl._pos
                        if pos[0] < 0:
@@ -426,6 +447,10 @@ class glComboButton(glButton):
        def getValue(self):
                return self._selection
 
+       def setValue(self, value):
+               self._selection = value
+               self._comboCallback()
+
        def OnMouseDown(self, x, y):
                if self._hidden or self._disabled:
                        return False
@@ -731,3 +756,124 @@ class glCheckbox(glGuiControl):
                        self._value = not self._value
                        return True
                return False
+
+class glSlider(glGuiControl):
+       def __init__(self, parent, value, minValue, maxValue, pos, callback):
+               super(glSlider, self).__init__(parent, pos)
+               self._callback = callback
+               self._focus = False
+               self._hidden = False
+               self._value = value
+               self._minValue = minValue
+               self._maxValue = maxValue
+
+       def setValue(self, value):
+               self._value = value
+               self._value = max(self._minValue, self._value)
+               self._value = min(self._maxValue, self._value)
+
+       def getValue(self):
+               return self._value
+
+       def setRange(self, minValue, maxValue):
+               self._minValue = minValue
+               self._maxValue = maxValue
+               self._value = max(minValue, self._value)
+               self._value = min(maxValue, self._value)
+
+       def getMinValue(self):
+               return self._minValue
+
+       def getMaxValue(self):
+               return self._maxValue
+
+       def setHidden(self, value):
+               self._hidden = value
+
+       def getMinSize(self):
+               return self._base._buttonSize, self._base._buttonSize
+
+       def _getPixelPos(self):
+               x0, y0, w, h = self.getSize()
+               return x0 + w / 2, y0
+
+       def draw(self):
+               if self._hidden:
+                       return
+
+               cx = 0
+               cy = 0
+               bs = self._base._buttonSize
+               pos = self._getPixelPos()
+
+               glPushMatrix()
+               glTranslatef(pos[0], pos[1], 0)
+               glDisable(GL_TEXTURE_2D)
+               if self.hasFocus():
+                       glColor4ub(32,32,32,255)
+               else:
+                       glColor4ub(32,32,32,192)
+               glScalef(bs, bs, bs)
+               glBegin(GL_QUADS)
+               glVertex2f( 0.1,-1.0)
+               glVertex2f(-0.1,-1.0)
+               glVertex2f(-0.1, 1.0)
+               glVertex2f( 0.1, 1.0)
+               glEnd()
+               glTranslate(0.0,0.9,0)
+               if self._focus:
+                       glColor4ub(0,0,0,255)
+                       glPushMatrix()
+                       glTranslate(-0.1,0,0)
+                       opengl.glDrawStringRight(str(self._minValue))
+                       glTranslate(0,-1.8,0)
+                       opengl.glDrawStringRight(str(self._maxValue))
+                       glTranslate(0.2,1.8-1.8*((self._value-self._minValue)/(self._maxValue-self._minValue)),0)
+                       opengl.glDrawStringLeft(str(self._value))
+                       glPopMatrix()
+               glColor4ub(255,255,255,240)
+               glTranslate(0.0,-1.8*((self._value-self._minValue)/(self._maxValue-self._minValue)),0)
+               glBegin(GL_QUADS)
+               glVertex2f( 0.1,-0.1)
+               glVertex2f(-0.1,-0.1)
+               glVertex2f(-0.1, 0.1)
+               glVertex2f( 0.1, 0.1)
+               glEnd()
+               glPopMatrix()
+
+       def _checkHit(self, x, y):
+               if self._hidden:
+                       return False
+               bs = self._base._buttonSize
+               pos = self._getPixelPos()
+               return -bs * 0.1 <= x - pos[0] <= bs * 0.1 and -bs * 1.0 <= y - pos[1] <= bs * 1.0
+
+       def setFocus(self):
+               self._base._focus = self
+               return True
+
+       def OnMouseMotion(self, x, y):
+               if self.hasFocus():
+                       bs = self._base._buttonSize
+                       pos = self._getPixelPos()
+                       self.setValue(int(self._minValue + (self._maxValue - self._minValue) * -(y - pos[1] - bs * 0.9) / (bs * 1.8)))
+                       self._callback()
+                       return True
+               if self._checkHit(x, y):
+                       self._focus = True
+                       return True
+               self._focus = False
+               return False
+
+       def OnMouseDown(self, x, y):
+               if self._checkHit(x, y):
+                       self.setFocus()
+                       self.OnMouseMotion(x, y)
+                       return True
+               return False
+
+       def OnMouseUp(self, x, y):
+               if self.hasFocus():
+                       self._base._focus = None
+                       return True
+               return False
index ce0c13ee7bfe8e06c4b5bb8796a2579ad7b4eb5a..32c762a46181e612d8a78a34100578302e8cd9c6 100644 (file)
@@ -75,11 +75,7 @@ class gcode(object):
                for line in gcodeFile:
                        if type(line) is tuple:
                                line = line[0]
-                       if self.progressCallback != None:
-                               if filePos != gcodeFile.tell():
-                                       filePos = gcodeFile.tell()
-                                       self.progressCallback(float(filePos) / float(self._fileSize))
-                       
+
                        #Parse Cura_SF comments
                        if line.startswith(';TYPE:'):
                                pathType = line[6:].strip()
@@ -97,6 +93,13 @@ class gcode(object):
                                        pathType = 'SKIRT'
                                if comment.startswith('LAYER:'):
                                        self.layerList.append(currentLayer)
+                                       if self.progressCallback is not None:
+                                               if filePos != gcodeFile.tell():
+                                                       filePos = gcodeFile.tell()
+                                                       if self.progressCallback(float(filePos) / float(self._fileSize)):
+                                                               #Abort the loading, we can safely return as the results here will be discarded
+                                                               gcodeFile.close()
+                                                               return
                                        currentLayer = []
                                if pathType != "CUSTOM":
                                        startCodeDone = True
index 4e43f9ef2762941ea5980d9cd8a7f0a54a4a7408..259e33a9570bebc03588805e6db71f5848f52849 100644 (file)
@@ -180,7 +180,7 @@ preferencesDefaultSettings = {
        'extruder_head_size_max_y': '35.0',
        'extruder_head_size_height': '60.0',
        
-       'model_colour': '#72CB30',
+       'model_colour': '#7AB645',
        'model_colour2': '#CB3030',
        'model_colour3': '#DDD93C',
        'model_colour4': '#4550D3',