chiark / gitweb /
Speedup GCode drawing a lot by using VBOs.
authordaid303 <daid303@gmail.com>
Thu, 18 Apr 2013 13:43:40 +0000 (15:43 +0200)
committerdaid303 <daid303@gmail.com>
Thu, 18 Apr 2013 13:43:40 +0000 (15:43 +0200)
Cura/gui/sceneView.py
Cura/gui/util/opengl.py
Cura/util/sliceEngine.py

index c50b6091577d5bda1a86ec43bfb3cf616d0d04e7..59ee0e09469d2f8107bdce6b32e5454b08eb4349 100644 (file)
@@ -34,6 +34,7 @@ class SceneView(openglGui.glGuiPanel):
                self._zoom = 300
                self._scene = objectScene.Scene()
                self._gcode = None
+               self._gcodeVBOs = []
                self._objectShader = None
                self._focusObj = None
                self._selectedObj = None
@@ -309,11 +310,15 @@ class SceneView(openglGui.glGuiPanel):
        def _updateSliceProgress(self, progressValue, ready):
                self.printButton.setDisabled(not ready)
                self.printButton.setProgressBar(progressValue)
+               if self._gcode is not None:
+                       self._gcode = None
+                       for layerVBOlist in self._gcodeVBOs:
+                               for vbo in layerVBOlist:
+                                       self.glReleaseList.append(vbo)
+                       self._gcodeVBOs = []
                if ready:
                        self._gcode = gcodeInterpreter.gcode()
                        self._gcode.load(self._slicer.getGCodeFilename())
-               else:
-                       self._gcode = None
                self.QueueRefresh()
 
        def loadScene(self, fileList):
@@ -658,8 +663,23 @@ void main(void)
 
                                glPushMatrix()
                                glTranslate(-self._machineSize[0] / 2, -self._machineSize[1] / 2, 0)
+                               t = time.time()
                                for n in xrange(0, self.layerSelect.getValue() + 1):
-                                       opengl.DrawGCodeLayer(self._gcode.layerList[n])
+                                       if len(self._gcodeVBOs) < n + 1:
+                                               self._gcodeVBOs.append(self._generateGCodeVBOs(self._gcode.layerList[n]))
+                                               if time.time() - t > 0.5:
+                                                       self.QueueRefresh()
+                                                       break
+                                       #['WALL-OUTER', 'WALL-INNER', 'FILL', 'SUPPORT', 'SKIRT']
+                                       glColor3f(1, 0, 0)
+                                       self._gcodeVBOs[n][0].render(GL_LINES)
+                                       glColor3f(0, 1, 0)
+                                       self._gcodeVBOs[n][1].render(GL_LINES)
+                                       glColor3f(0.5, 0.5, 0.0)
+                                       self._gcodeVBOs[n][2].render(GL_LINES)
+                                       glColor3f(0, 1, 1)
+                                       self._gcodeVBOs[n][3].render(GL_LINES)
+                                       self._gcodeVBOs[n][4].render(GL_LINES)
                                glPopMatrix()
                else:
                        glStencilFunc(GL_ALWAYS, 1, 1)
@@ -829,6 +849,19 @@ void main(void)
                glDisable(GL_BLEND)
                glDisable(GL_CULL_FACE)
 
+       def _generateGCodeVBOs(self, layer):
+               ret = []
+               for extrudeType in ['WALL-OUTER', 'WALL-INNER', 'FILL', 'SUPPORT', 'SKIRT']:
+                       pointList = numpy.zeros((0,3), numpy.float32)
+                       for path in layer:
+                               if path.type == 'extrude' and path.pathType == extrudeType:
+                                       a = numpy.array(path.points, numpy.float32)
+                                       a = numpy.concatenate((a[:-1], a[1:]), 1)
+                                       a = a.reshape((len(a) * 2, 3))
+                                       pointList = numpy.concatenate((pointList, a))
+                       ret.append(opengl.GLVBO(pointList))
+               return ret
+
        def getObjectCenterPos(self):
                if self._selectedObj is None:
                        return [0.0, 0.0, 0.0]
index 4b5d0c538bbbb6056e70921a1829a7f1c8898707..ae9b64f17c04f6106c7d38d65ad4f959b83099bb 100644 (file)
@@ -78,22 +78,30 @@ class GLShader(GLReferenceCounter):
                        print "Shader was not properly released!"
 
 class GLVBO(GLReferenceCounter):
-       def __init__(self, vertexArray, normalArray):
+       def __init__(self, vertexArray, normalArray = None):
                super(GLVBO, self).__init__()
                self._buffer = glGenBuffers(1)
                self._size = len(vertexArray)
+               self._hasNormals = normalArray is not None
                glBindBuffer(GL_ARRAY_BUFFER, self._buffer)
-               glBufferData(GL_ARRAY_BUFFER, numpy.concatenate((vertexArray, normalArray), 1), GL_STATIC_DRAW)
+               if self._hasNormals:
+                       glBufferData(GL_ARRAY_BUFFER, numpy.concatenate((vertexArray, normalArray), 1), GL_STATIC_DRAW)
+               else:
+                       glBufferData(GL_ARRAY_BUFFER, vertexArray, GL_STATIC_DRAW)
                glBindBuffer(GL_ARRAY_BUFFER, 0)
 
        def render(self, render_type = GL_TRIANGLES):
                glEnableClientState(GL_VERTEX_ARRAY)
-               glEnableClientState(GL_NORMAL_ARRAY)
                glBindBuffer(GL_ARRAY_BUFFER, self._buffer)
-               glVertexPointer(3, GL_FLOAT, 2*3*4, c_void_p(0))
-               glNormalPointer(GL_FLOAT, 2*3*4, c_void_p(3 * 4))
 
-               batchSize = 999    #Warning, batchSize needs to be dividable by 3
+               if self._hasNormals:
+                       glEnableClientState(GL_NORMAL_ARRAY)
+                       glVertexPointer(3, GL_FLOAT, 2*3*4, c_void_p(0))
+                       glNormalPointer(GL_FLOAT, 2*3*4, c_void_p(3 * 4))
+               else:
+                       glVertexPointer(3, GL_FLOAT, 3*4, c_void_p(0))
+
+               batchSize = 1002    #Warning, batchSize needs to be dividable by 3 and 2
                extraStartPos = int(self._size / batchSize) * batchSize
                extraCount = self._size - extraStartPos
 
@@ -101,8 +109,10 @@ class GLVBO(GLReferenceCounter):
                        glDrawArrays(render_type, i * batchSize, batchSize)
                glDrawArrays(render_type, extraStartPos, extraCount)
                glBindBuffer(GL_ARRAY_BUFFER, 0)
+
                glDisableClientState(GL_VERTEX_ARRAY)
-               glDisableClientState(GL_NORMAL_ARRAY)
+               if self._hasNormals:
+                       glDisableClientState(GL_NORMAL_ARRAY)
 
        def release(self):
                if self._buffer is not None:
@@ -672,11 +682,12 @@ def DrawGCodeLayer(layer, drawQuick = True):
                                prevVv1 = vv1
                                prevVv3 = vv3
                else:
-                       glBegin(GL_LINE_STRIP)
                        glColor4fv(c)
+                       glBegin(GL_TRIANGLES)
                        for v in path.points:
                                glVertex3f(v[0], v[1], v[2])
                        glEnd()
+
                if not path.type == 'move':
                        prevPathWasRetract = False
                #if path.type == 'retract' and path.points[0].almostEqual(path.points[-1]):
index 6dd73514e357f5d52542291f62e6fce405b6c133..75a1f81c30c458ca0f05233ba2de2c648a275926 100644 (file)
@@ -91,7 +91,7 @@ class Slicer(object):
                                line = line.split(':')
                                if line[1] == 'process':
                                        objectNr += 1
-                               else:
+                               elif line[1] in self._progressSteps:
                                        progressValue = float(line[2]) / float(line[3])
                                        progressValue /= len(self._progressSteps)
                                        progressValue += 1.0 / len(self._progressSteps) * self._progressSteps.index(line[1])