1 from __future__ import absolute_import
2 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
9 from Cura.util import meshLoader
10 from Cura.util import util3d
11 from Cura.util import profile
12 from Cura.util.resources import getPathForMesh, getPathForImage
16 OpenGL.ERROR_CHECKING = False
17 from OpenGL.GLUT import *
18 from OpenGL.GLU import *
19 from OpenGL.GL import *
20 from OpenGL.GL import shaders
25 class GLReferenceCounter(object):
34 return self._refCounter <= 0
36 def hasShaderSupport():
37 return bool(glCreateShader) != False
39 class GLShader(GLReferenceCounter):
40 def __init__(self, vertexProgram, fragmentProgram):
41 super(GLShader, self).__init__()
42 self._vertexString = vertexProgram
43 self._fragmentString = fragmentProgram
45 self._vertexProgram = shaders.compileShader(vertexProgram, GL_VERTEX_SHADER)
46 self._fragmentProgram = shaders.compileShader(fragmentProgram, GL_FRAGMENT_SHADER)
47 self._program = shaders.compileProgram(self._vertexProgram, self._fragmentProgram)
48 except RuntimeError, e:
53 if self._program is not None:
54 shaders.glUseProgram(self._program)
57 shaders.glUseProgram(0)
60 if self._program is not None:
61 shaders.glDeleteShader(self._vertexProgram)
62 shaders.glDeleteShader(self._fragmentProgram)
63 glDeleteProgram(self._program)
66 def setUniform(self, name, value):
67 if self._program is not None:
68 if type(value) is float:
69 glUniform1f(glGetUniformLocation(self._program, name), value)
70 elif type(value) is numpy.matrix:
71 glUniformMatrix3fv(glGetUniformLocation(self._program, name), 1, False, value.getA().astype(numpy.float32))
73 print 'Unknown type for setUniform: %s' % (str(type(value)))
76 return self._program is not None
78 def getVertexShader(self):
79 return self._vertexString
81 def getFragmentShader(self):
82 return self._fragmentString
85 if self._program is not None and bool(glDeleteProgram):
86 print "Shader was not properly released!"
88 #A Class that acts as an OpenGL shader, but in reality is not none.
89 class GLFakeShader(GLReferenceCounter):
91 super(GLFakeShader, self).__init__()
96 glEnable(GL_COLOR_MATERIAL)
97 glLightfv(GL_LIGHT0, GL_DIFFUSE, [1,1,1,1])
98 glLightfv(GL_LIGHT0, GL_AMBIENT, [0,0,0,0])
99 glLightfv(GL_LIGHT0, GL_SPECULAR, [0,0,0,0])
102 glDisable(GL_LIGHTING)
107 def setUniform(self, name, value):
113 def getVertexShader(self):
116 def getFragmentShader(self):
119 class GLVBO(GLReferenceCounter):
120 def __init__(self, vertexArray, normalArray = None):
121 super(GLVBO, self).__init__()
122 if bool(glGenBuffers) == False:
123 self._vertexArray = vertexArray
124 self._normalArray = normalArray
127 self._buffer = glGenBuffers(1)
128 self._size = len(vertexArray)
129 self._hasNormals = normalArray is not None
130 glBindBuffer(GL_ARRAY_BUFFER, self._buffer)
132 glBufferData(GL_ARRAY_BUFFER, numpy.concatenate((vertexArray, normalArray), 1), GL_STATIC_DRAW)
134 glBufferData(GL_ARRAY_BUFFER, vertexArray, GL_STATIC_DRAW)
135 glBindBuffer(GL_ARRAY_BUFFER, 0)
137 def render(self, render_type = GL_TRIANGLES):
138 if self._buffer is None:
139 glEnableClientState(GL_VERTEX_ARRAY)
140 glVertexPointer(3, GL_FLOAT, 0, self._vertexArray)
141 if self._normalArray is not None:
142 glEnableClientState(GL_NORMAL_ARRAY)
143 glNormalPointer(GL_FLOAT, 0, self._normalArray)
144 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
145 batchSize = 999 #Warning, batchSize needs to be dividable by 3
146 extraStartPos = int(len(self._vertexArray) / batchSize) * batchSize
147 extraCount = len(self._vertexArray) - extraStartPos
150 for i in xrange(0, int(len(self._vertexArray) / batchSize)):
151 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
152 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
154 glEnableClientState(GL_VERTEX_ARRAY)
155 glBindBuffer(GL_ARRAY_BUFFER, self._buffer)
158 glEnableClientState(GL_NORMAL_ARRAY)
159 glVertexPointer(3, GL_FLOAT, 2*3*4, c_void_p(0))
160 glNormalPointer(GL_FLOAT, 2*3*4, c_void_p(3 * 4))
162 glVertexPointer(3, GL_FLOAT, 3*4, c_void_p(0))
164 batchSize = 996 #Warning, batchSize needs to be dividable by 4, 3 and 2
165 extraStartPos = int(self._size / batchSize) * batchSize
166 extraCount = self._size - extraStartPos
168 for i in xrange(0, int(self._size / batchSize)):
169 glDrawArrays(render_type, i * batchSize, batchSize)
170 glDrawArrays(render_type, extraStartPos, extraCount)
171 glBindBuffer(GL_ARRAY_BUFFER, 0)
173 glDisableClientState(GL_VERTEX_ARRAY)
175 glDisableClientState(GL_NORMAL_ARRAY)
178 if self._buffer is not None:
179 glBindBuffer(GL_ARRAY_BUFFER, self._buffer)
180 glBufferData(GL_ARRAY_BUFFER, None, GL_STATIC_DRAW)
181 glBindBuffer(GL_ARRAY_BUFFER, 0)
182 glDeleteBuffers(1, [self._buffer])
184 self._vertexArray = None
185 self._normalArray = None
188 if self._buffer is not None and bool(glDeleteBuffers):
189 print "VBO was not properly released!"
191 def DrawMachine(machineSize):
192 glDisable(GL_LIGHTING)
193 glDisable(GL_CULL_FACE)
195 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
199 for x in xrange(-int(sx/20)-1, int(sx / 20) + 1):
200 for y in xrange(-int(sx/20)-1, int(sy / 20) + 1):
205 x1 = max(min(x1, sx), 0)
206 y1 = max(min(y1, sy), 0)
207 x2 = max(min(x2, sx), 0)
208 y2 = max(min(y2, sy), 0)
209 if (x & 1) == (y & 1):
210 glColor4ub(5, 171, 231, 127)
212 glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128)
214 glVertex3f(x1, y1, -0.02)
215 glVertex3f(x2, y1, -0.02)
216 glVertex3f(x2, y2, -0.02)
217 glVertex3f(x1, y2, -0.02)
220 glEnable(GL_CULL_FACE)
222 if profile.getPreference('machine_type') == 'ultimaker':
224 glEnable(GL_LIGHTING)
225 glTranslate(100, 200, -1)
226 glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8])
227 glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5])
229 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR)
232 if platformMesh is None:
234 platformMesh = meshLoader.loadMesh(getPathForMesh('ultimaker_platform.stl'))
239 DrawMesh(platformMesh)
241 glDisable(GL_LIGHTING)
242 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
244 glColor4ub(5, 171, 231, 64)
246 glVertex3f(0, 0, machineSize.z)
247 glVertex3f(0, machineSize.y, machineSize.z)
248 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
249 glVertex3f(machineSize.x, 0, machineSize.z)
252 glColor4ub(5, 171, 231, 96)
255 glVertex3f(0, 0, machineSize.z)
256 glVertex3f(machineSize.x, 0, machineSize.z)
257 glVertex3f(machineSize.x, 0, 0)
259 glVertex3f(0, machineSize.y, machineSize.z)
260 glVertex3f(0, machineSize.y, 0)
261 glVertex3f(machineSize.x, machineSize.y, 0)
262 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
265 glColor4ub(5, 171, 231, 128)
267 glVertex3f(0, 0, machineSize.z)
269 glVertex3f(0, machineSize.y, 0)
270 glVertex3f(0, machineSize.y, machineSize.z)
272 glVertex3f(machineSize.x, 0, 0)
273 glVertex3f(machineSize.x, 0, machineSize.z)
274 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
275 glVertex3f(machineSize.x, machineSize.y, 0)
280 #Draw the X/Y/Z indicator
300 glDisable(GL_DEPTH_TEST)
304 glTranslate(20, 0, 0)
305 noZ = ResetMatrixRotationAndScale()
306 glDrawStringCenter("X")
312 glTranslate(0, 20, 0)
313 glDrawStringCenter("Y")
320 glTranslate(0, 0, 20)
321 glDrawStringCenter("Z")
325 glEnable(GL_DEPTH_TEST)
327 def glDrawStringCenter(s):
329 glBitmap(0,0,0,0, -glGetStringSize(s)[0]/2, 0, None)
331 glutBitmapCharacter(OpenGL.GLUT.GLUT_BITMAP_HELVETICA_18, ord(c))
333 def glGetStringSize(s):
336 width += glutBitmapWidth(OpenGL.GLUT.GLUT_BITMAP_HELVETICA_18, ord(c))
340 def glDrawStringLeft(s):
346 glTranslate(0, 18 * n, 0)
351 glutBitmapCharacter(OpenGL.GLUT.GLUT_BITMAP_HELVETICA_18, ord(c))
353 def glDrawStringRight(s):
355 glBitmap(0,0,0,0, -glGetStringSize(s)[0], 0, None)
357 glutBitmapCharacter(OpenGL.GLUT.GLUT_BITMAP_HELVETICA_18, ord(c))
359 def glDrawQuad(x, y, w, h):
361 glTranslatef(x, y, 0)
362 glDisable(GL_TEXTURE_2D)
371 def glDrawTexturedQuad(x, y, w, h, texID, mirror = 0):
372 tx = float(texID % 4) / 4
373 ty = float(int(texID / 4)) / 8
383 glTranslatef(x, y, 0)
384 glEnable(GL_TEXTURE_2D)
386 glTexCoord2f(tx+tsx, ty)
390 glTexCoord2f(tx, ty+tsy)
392 glTexCoord2f(tx+tsx, ty+tsy)
397 def glDrawStretchedQuad(x, y, w, h, cornerSize, texID):
398 tx0 = float(texID % 4) / 4
399 ty0 = float(int(texID / 4)) / 8
400 tx1 = tx0 + 0.25 / 2.0
401 ty1 = ty0 + 0.125 / 2.0
406 glTranslatef(x, y, 0)
407 glEnable(GL_TEXTURE_2D)
410 glTexCoord2f(tx1, ty0)
411 glVertex2f( cornerSize, 0)
412 glTexCoord2f(tx0, ty0)
414 glTexCoord2f(tx0, ty1)
415 glVertex2f( 0, cornerSize)
416 glTexCoord2f(tx1, ty1)
417 glVertex2f( cornerSize, cornerSize)
419 glTexCoord2f(tx2, ty0)
421 glTexCoord2f(tx1, ty0)
422 glVertex2f( w - cornerSize, 0)
423 glTexCoord2f(tx1, ty1)
424 glVertex2f( w - cornerSize, cornerSize)
425 glTexCoord2f(tx2, ty1)
426 glVertex2f( w, cornerSize)
428 glTexCoord2f(tx1, ty1)
429 glVertex2f( cornerSize, h - cornerSize)
430 glTexCoord2f(tx0, ty1)
431 glVertex2f( 0, h - cornerSize)
432 glTexCoord2f(tx0, ty2)
434 glTexCoord2f(tx1, ty2)
435 glVertex2f( cornerSize, h)
437 glTexCoord2f(tx2, ty1)
438 glVertex2f( w, h - cornerSize)
439 glTexCoord2f(tx1, ty1)
440 glVertex2f( w - cornerSize, h - cornerSize)
441 glTexCoord2f(tx1, ty2)
442 glVertex2f( w - cornerSize, h)
443 glTexCoord2f(tx2, ty2)
447 glTexCoord2f(tx1, ty1)
448 glVertex2f( w-cornerSize, cornerSize)
449 glTexCoord2f(tx1, ty1)
450 glVertex2f( cornerSize, cornerSize)
451 glTexCoord2f(tx1, ty1)
452 glVertex2f( cornerSize, h-cornerSize)
453 glTexCoord2f(tx1, ty1)
454 glVertex2f( w-cornerSize, h-cornerSize)
457 glTexCoord2f(tx2, ty1)
458 glVertex2f( w, cornerSize)
459 glTexCoord2f(tx1, ty1)
460 glVertex2f( w-cornerSize, cornerSize)
461 glTexCoord2f(tx1, ty1)
462 glVertex2f( w-cornerSize, h-cornerSize)
463 glTexCoord2f(tx2, ty1)
464 glVertex2f( w, h-cornerSize)
467 glTexCoord2f(tx1, ty1)
468 glVertex2f( cornerSize, cornerSize)
469 glTexCoord2f(tx0, ty1)
470 glVertex2f( 0, cornerSize)
471 glTexCoord2f(tx0, ty1)
472 glVertex2f( 0, h-cornerSize)
473 glTexCoord2f(tx1, ty1)
474 glVertex2f( cornerSize, h-cornerSize)
477 glTexCoord2f(tx1, ty0)
478 glVertex2f( w-cornerSize, 0)
479 glTexCoord2f(tx1, ty0)
480 glVertex2f( cornerSize, 0)
481 glTexCoord2f(tx1, ty1)
482 glVertex2f( cornerSize, cornerSize)
483 glTexCoord2f(tx1, ty1)
484 glVertex2f( w-cornerSize, cornerSize)
487 glTexCoord2f(tx1, ty1)
488 glVertex2f( w-cornerSize, h-cornerSize)
489 glTexCoord2f(tx1, ty1)
490 glVertex2f( cornerSize, h-cornerSize)
491 glTexCoord2f(tx1, ty2)
492 glVertex2f( cornerSize, h)
493 glTexCoord2f(tx1, ty2)
494 glVertex2f( w-cornerSize, h)
497 glDisable(GL_TEXTURE_2D)
500 def unproject(winx, winy, winz, modelMatrix, projMatrix, viewport):
501 npModelMatrix = numpy.matrix(numpy.array(modelMatrix, numpy.float64).reshape((4,4)))
502 npProjMatrix = numpy.matrix(numpy.array(projMatrix, numpy.float64).reshape((4,4)))
503 finalMatrix = npModelMatrix * npProjMatrix
504 finalMatrix = numpy.linalg.inv(finalMatrix)
506 viewport = map(float, viewport)
507 vector = numpy.array([(winx - viewport[0]) / viewport[2] * 2.0 - 1.0, (winy - viewport[1]) / viewport[3] * 2.0 - 1.0, winz * 2.0 - 1.0, 1]).reshape((1,4))
508 vector = (numpy.matrix(vector) * finalMatrix).getA().flatten()
509 ret = list(vector)[0:3] / vector[3]
512 def convert3x3MatrixTo4x4(matrix):
513 return list(matrix.getA()[0]) + [0] + list(matrix.getA()[1]) + [0] + list(matrix.getA()[2]) + [0, 0,0,0,1]
515 def loadGLTexture(filename):
516 tex = glGenTextures(1)
517 glBindTexture(GL_TEXTURE_2D, tex)
518 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
519 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
520 img = wx.ImageFromBitmap(wx.Bitmap(getPathForImage(filename)))
521 rgbData = img.GetData()
522 alphaData = img.GetAlphaData()
523 if alphaData is not None:
525 for i in xrange(0, len(alphaData)):
526 data += rgbData[i*3:i*3+3] + alphaData[i]
527 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.GetWidth(), img.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, data)
529 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.GetWidth(), img.GetHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, rgbData)
532 def ResetMatrixRotationAndScale():
533 matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
537 scale2D = matrix[0][0]
548 if matrix[3][2] != 0.0:
549 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
550 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
553 matrix[0][0] = scale2D
554 matrix[1][1] = scale2D
555 matrix[2][2] = scale2D
559 glLoadMatrixf(matrix)
563 def DrawBox(vMin, vMax):
564 glBegin(GL_LINE_LOOP)
565 glVertex3f(vMin[0], vMin[1], vMin[2])
566 glVertex3f(vMax[0], vMin[1], vMin[2])
567 glVertex3f(vMax[0], vMax[1], vMin[2])
568 glVertex3f(vMin[0], vMax[1], vMin[2])
571 glBegin(GL_LINE_LOOP)
572 glVertex3f(vMin[0], vMin[1], vMax[2])
573 glVertex3f(vMax[0], vMin[1], vMax[2])
574 glVertex3f(vMax[0], vMax[1], vMax[2])
575 glVertex3f(vMin[0], vMax[1], vMax[2])
578 glVertex3f(vMin[0], vMin[1], vMin[2])
579 glVertex3f(vMin[0], vMin[1], vMax[2])
580 glVertex3f(vMax[0], vMin[1], vMin[2])
581 glVertex3f(vMax[0], vMin[1], vMax[2])
582 glVertex3f(vMax[0], vMax[1], vMin[2])
583 glVertex3f(vMax[0], vMax[1], vMax[2])
584 glVertex3f(vMin[0], vMax[1], vMin[2])
585 glVertex3f(vMin[0], vMax[1], vMax[2])
589 def DrawMeshOutline(mesh):
590 glEnable(GL_CULL_FACE)
591 glEnableClientState(GL_VERTEX_ARRAY);
592 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
596 glPolygonMode(GL_BACK, GL_LINE)
597 glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
598 glPolygonMode(GL_BACK, GL_FILL)
601 glDisableClientState(GL_VERTEX_ARRAY)
604 def DrawMesh(mesh, insideOut = False):
605 glEnable(GL_CULL_FACE)
606 glEnableClientState(GL_VERTEX_ARRAY)
607 glEnableClientState(GL_NORMAL_ARRAY)
608 for m in mesh._meshList:
609 glVertexPointer(3, GL_FLOAT, 0, m.vertexes)
611 glNormalPointer(GL_FLOAT, 0, m.invNormal)
613 glNormalPointer(GL_FLOAT, 0, m.normal)
615 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
616 batchSize = 999 #Warning, batchSize needs to be dividable by 3
617 extraStartPos = int(m.vertexCount / batchSize) * batchSize
618 extraCount = m.vertexCount - extraStartPos
621 for i in xrange(0, int(m.vertexCount / batchSize)):
622 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
623 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
627 glNormalPointer(GL_FLOAT, 0, m.normal)
629 glNormalPointer(GL_FLOAT, 0, m.invNormal)
630 for i in xrange(0, int(m.vertexCount / batchSize)):
631 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
632 extraStartPos = int(m.vertexCount / batchSize) * batchSize
633 extraCount = m.vertexCount - extraStartPos
634 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
637 glDisableClientState(GL_VERTEX_ARRAY)
638 glDisableClientState(GL_NORMAL_ARRAY)
641 def DrawMeshSteep(mesh, matrix, angle):
642 cosAngle = math.sin(angle / 180.0 * math.pi)
643 glDisable(GL_LIGHTING)
644 glDepthFunc(GL_EQUAL)
645 normals = (numpy.matrix(mesh.normal, copy = False) * matrix).getA()
646 for i in xrange(0, int(mesh.vertexCount), 3):
647 if normals[i][2] < -0.999999:
648 if mesh.vertexes[i + 0][2] > 0.01:
650 glBegin(GL_TRIANGLES)
651 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
652 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
653 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
655 elif normals[i][2] < -cosAngle:
656 glColor3f(-normals[i][2], 0, 0)
657 glBegin(GL_TRIANGLES)
658 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
659 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
660 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
662 elif normals[i][2] > 0.999999:
663 if mesh.vertexes[i + 0][2] > 0.01:
665 glBegin(GL_TRIANGLES)
666 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
667 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
668 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
670 elif normals[i][2] > cosAngle:
671 glColor3f(normals[i][2], 0, 0)
672 glBegin(GL_TRIANGLES)
673 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
674 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
675 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
679 def DrawGCodeLayer(layer, drawQuick = True):
680 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
681 filamentArea = math.pi * filamentRadius * filamentRadius
682 lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
685 fillColorCycle = [[0.5, 0.5, 0.0, 1], [0.0, 0.5, 0.5, 1], [0.5, 0.0, 0.5, 1]]
686 moveColor = [0, 0, 1, 0.5]
687 retractColor = [1, 0, 0.5, 0.5]
688 supportColor = [0, 1, 1, 1]
689 extrudeColor = [[1, 0, 0, 1], [0, 1, 1, 1], [1, 1, 0, 1], [1, 0, 1, 1]]
690 innerWallColor = [0, 1, 0, 1]
691 skirtColor = [0, 0.5, 0.5, 1]
692 prevPathWasRetract = False
694 glDisable(GL_CULL_FACE)
696 if path.type == 'move':
697 if prevPathWasRetract:
704 if path.type == 'extrude':
705 if path.pathType == 'FILL':
706 c = fillColorCycle[fillCycle]
707 fillCycle = (fillCycle + 1) % len(fillColorCycle)
708 elif path.pathType == 'WALL-INNER':
711 elif path.pathType == 'SUPPORT':
713 elif path.pathType == 'SKIRT':
716 c = extrudeColor[path.extruder]
717 if path.type == 'retract':
719 if path.type == 'extrude' and not drawQuick:
722 for i in xrange(0, len(path.points) - 1):
724 v1 = path.points[i + 1]
726 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
727 dist = (v0 - v1).vsize()
728 if dist > 0 and path.layerThickness > 0:
729 extrusionMMperDist = (v1.e - v0.e) / dist
730 lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
732 drawLength += (v0 - v1).vsize()
733 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
736 vv2 = v0 + normal * lineWidth
737 vv3 = v1 + normal * lineWidth
738 vv0 = v0 - normal * lineWidth
739 vv1 = v1 - normal * lineWidth
743 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
744 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
745 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
746 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
748 if prevNormal is not None:
749 n = (normal + prevNormal)
751 vv4 = v0 + n * lineWidth
752 vv5 = v0 - n * lineWidth
755 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
756 glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
757 glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
758 glVertex3f(v0.x, v0.y, v0.z - zOffset)
760 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
761 glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
762 glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
763 glVertex3f(v0.x, v0.y, v0.z - zOffset)
771 glBegin(GL_TRIANGLES)
772 for v in path.points:
773 glVertex3f(v[0], v[1], v[2])
776 if not path.type == 'move':
777 prevPathWasRetract = False
778 #if path.type == 'retract' and path.points[0].almostEqual(path.points[-1]):
779 # prevPathWasRetract = True
780 glEnable(GL_CULL_FACE)