From: daid303 Date: Thu, 18 Apr 2013 13:43:40 +0000 (+0200) Subject: Speedup GCode drawing a lot by using VBOs. X-Git-Tag: 13.05~83 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=c8cfcb2b38b9c4af9ecdb5799697ea2dc6426ae9;p=cura.git Speedup GCode drawing a lot by using VBOs. --- diff --git a/Cura/gui/sceneView.py b/Cura/gui/sceneView.py index c50b6091..59ee0e09 100644 --- a/Cura/gui/sceneView.py +++ b/Cura/gui/sceneView.py @@ -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] diff --git a/Cura/gui/util/opengl.py b/Cura/gui/util/opengl.py index 4b5d0c53..ae9b64f1 100644 --- a/Cura/gui/util/opengl.py +++ b/Cura/gui/util/opengl.py @@ -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]): diff --git a/Cura/util/sliceEngine.py b/Cura/util/sliceEngine.py index 6dd73514..75a1f81c 100644 --- a/Cura/util/sliceEngine.py +++ b/Cura/util/sliceEngine.py @@ -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])