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 if bool(glCreateShader):
41 class GLShader(GLReferenceCounter):
42 def __init__(self, vertexProgram, fragmentProgram):
43 super(GLShader, self).__init__()
44 self._vertexString = vertexProgram
45 self._fragmentString = fragmentProgram
47 self._vertexProgram = shaders.compileShader(vertexProgram, GL_VERTEX_SHADER)
48 self._fragmentProgram = shaders.compileShader(fragmentProgram, GL_FRAGMENT_SHADER)
49 self._program = shaders.compileProgram(self._vertexProgram, self._fragmentProgram)
50 except RuntimeError, e:
55 if self._program is not None:
56 shaders.glUseProgram(self._program)
59 shaders.glUseProgram(0)
62 if self._program is not None:
63 shaders.glDeleteShader(self._vertexProgram)
64 shaders.glDeleteShader(self._fragmentProgram)
65 glDeleteProgram(self._program)
68 def setUniform(self, name, value):
69 if self._program is not None:
70 if type(value) is float:
71 glUniform1f(glGetUniformLocation(self._program, name), value)
72 elif type(value) is numpy.matrix:
73 glUniformMatrix3fv(glGetUniformLocation(self._program, name), 1, False, value.getA().astype(numpy.float32))
75 print 'Unknown type for setUniform: %s' % (str(type(value)))
78 return self._program is not None
80 def getVertexShader(self):
81 return self._vertexString
83 def getFragmentShader(self):
84 return self._fragmentString
87 if self._program is not None and bool(glDeleteProgram):
88 print "Shader was not properly released!"
90 #A Class that acts as an OpenGL shader, but in reality is not none.
91 class GLFakeShader(GLReferenceCounter):
93 super(GLFakeShader, self).__init__()
98 glEnable(GL_COLOR_MATERIAL)
99 glLightfv(GL_LIGHT0, GL_DIFFUSE, [1,1,1,1])
100 glLightfv(GL_LIGHT0, GL_AMBIENT, [0,0,0,0])
101 glLightfv(GL_LIGHT0, GL_SPECULAR, [0,0,0,0])
104 glDisable(GL_LIGHTING)
109 def setUniform(self, name, value):
115 def getVertexShader(self):
118 def getFragmentShader(self):
121 class GLVBO(GLReferenceCounter):
122 def __init__(self, vertexArray, normalArray = None):
123 super(GLVBO, self).__init__()
124 if not bool(glGenBuffers):
125 self._vertexArray = vertexArray
126 self._normalArray = normalArray
129 self._buffer = glGenBuffers(1)
130 self._size = len(vertexArray)
131 self._hasNormals = normalArray is not None
132 glBindBuffer(GL_ARRAY_BUFFER, self._buffer)
134 glBufferData(GL_ARRAY_BUFFER, numpy.concatenate((vertexArray, normalArray), 1), GL_STATIC_DRAW)
136 glBufferData(GL_ARRAY_BUFFER, vertexArray, GL_STATIC_DRAW)
137 glBindBuffer(GL_ARRAY_BUFFER, 0)
139 def render(self, render_type = GL_TRIANGLES):
140 if self._buffer is None:
141 glEnableClientState(GL_VERTEX_ARRAY)
142 glVertexPointer(3, GL_FLOAT, 0, self._vertexArray)
143 if self._normalArray is not None:
144 glEnableClientState(GL_NORMAL_ARRAY)
145 glNormalPointer(GL_FLOAT, 0, self._normalArray)
146 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
147 batchSize = 999 #Warning, batchSize needs to be dividable by 3
148 extraStartPos = int(len(self._vertexArray) / batchSize) * batchSize
149 extraCount = len(self._vertexArray) - extraStartPos
152 for i in xrange(0, int(len(self._vertexArray) / batchSize)):
153 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
154 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
156 glEnableClientState(GL_VERTEX_ARRAY)
157 glBindBuffer(GL_ARRAY_BUFFER, self._buffer)
160 glEnableClientState(GL_NORMAL_ARRAY)
161 glVertexPointer(3, GL_FLOAT, 2*3*4, c_void_p(0))
162 glNormalPointer(GL_FLOAT, 2*3*4, c_void_p(3 * 4))
164 glVertexPointer(3, GL_FLOAT, 3*4, c_void_p(0))
166 batchSize = 996 #Warning, batchSize needs to be dividable by 4, 3 and 2
167 extraStartPos = int(self._size / batchSize) * batchSize
168 extraCount = self._size - extraStartPos
170 for i in xrange(0, int(self._size / batchSize)):
171 glDrawArrays(render_type, i * batchSize, batchSize)
172 glDrawArrays(render_type, extraStartPos, extraCount)
173 glBindBuffer(GL_ARRAY_BUFFER, 0)
175 glDisableClientState(GL_VERTEX_ARRAY)
177 glDisableClientState(GL_NORMAL_ARRAY)
180 if self._buffer is not None:
181 glBindBuffer(GL_ARRAY_BUFFER, self._buffer)
182 glBufferData(GL_ARRAY_BUFFER, None, GL_STATIC_DRAW)
183 glBindBuffer(GL_ARRAY_BUFFER, 0)
184 glDeleteBuffers(1, [self._buffer])
186 self._vertexArray = None
187 self._normalArray = None
190 if self._buffer is not None and bool(glDeleteBuffers):
191 print "VBO was not properly released!"
193 def DrawMachine(machineSize):
194 glDisable(GL_LIGHTING)
195 glDisable(GL_CULL_FACE)
197 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
201 for x in xrange(-int(sx/20)-1, int(sx / 20) + 1):
202 for y in xrange(-int(sx/20)-1, int(sy / 20) + 1):
207 x1 = max(min(x1, sx), 0)
208 y1 = max(min(y1, sy), 0)
209 x2 = max(min(x2, sx), 0)
210 y2 = max(min(y2, sy), 0)
211 if (x & 1) == (y & 1):
212 glColor4ub(5, 171, 231, 127)
214 glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128)
216 glVertex3f(x1, y1, -0.02)
217 glVertex3f(x2, y1, -0.02)
218 glVertex3f(x2, y2, -0.02)
219 glVertex3f(x1, y2, -0.02)
222 glEnable(GL_CULL_FACE)
224 if profile.getPreference('machine_type') == 'ultimaker':
226 glEnable(GL_LIGHTING)
227 glTranslate(100, 200, -1)
228 glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8])
229 glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5])
231 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR)
234 if platformMesh is None:
236 platformMesh = meshLoader.loadMesh(getPathForMesh('ultimaker_platform.stl'))
241 DrawMesh(platformMesh)
243 glDisable(GL_LIGHTING)
244 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
246 glColor4ub(5, 171, 231, 64)
248 glVertex3f(0, 0, machineSize.z)
249 glVertex3f(0, machineSize.y, machineSize.z)
250 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
251 glVertex3f(machineSize.x, 0, machineSize.z)
254 glColor4ub(5, 171, 231, 96)
257 glVertex3f(0, 0, machineSize.z)
258 glVertex3f(machineSize.x, 0, machineSize.z)
259 glVertex3f(machineSize.x, 0, 0)
261 glVertex3f(0, machineSize.y, machineSize.z)
262 glVertex3f(0, machineSize.y, 0)
263 glVertex3f(machineSize.x, machineSize.y, 0)
264 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
267 glColor4ub(5, 171, 231, 128)
269 glVertex3f(0, 0, machineSize.z)
271 glVertex3f(0, machineSize.y, 0)
272 glVertex3f(0, machineSize.y, machineSize.z)
274 glVertex3f(machineSize.x, 0, 0)
275 glVertex3f(machineSize.x, 0, machineSize.z)
276 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
277 glVertex3f(machineSize.x, machineSize.y, 0)
282 #Draw the X/Y/Z indicator
302 glDisable(GL_DEPTH_TEST)
306 glTranslate(20, 0, 0)
307 noZ = ResetMatrixRotationAndScale()
308 glDrawStringCenter("X")
314 glTranslate(0, 20, 0)
315 glDrawStringCenter("Y")
322 glTranslate(0, 0, 20)
323 glDrawStringCenter("Z")
327 glEnable(GL_DEPTH_TEST)
329 def glDrawStringCenter(s):
331 glBitmap(0,0,0,0, -glGetStringSize(s)[0]/2, 0, None)
333 glutBitmapCharacter(OpenGL.GLUT.GLUT_BITMAP_HELVETICA_18, ord(c))
335 def glGetStringSize(s):
338 width += glutBitmapWidth(OpenGL.GLUT.GLUT_BITMAP_HELVETICA_18, ord(c))
342 def glDrawStringLeft(s):
348 glTranslate(0, 18 * n, 0)
353 glutBitmapCharacter(OpenGL.GLUT.GLUT_BITMAP_HELVETICA_18, ord(c))
355 def glDrawStringRight(s):
357 glBitmap(0,0,0,0, -glGetStringSize(s)[0], 0, None)
359 glutBitmapCharacter(OpenGL.GLUT.GLUT_BITMAP_HELVETICA_18, ord(c))
361 def glDrawQuad(x, y, w, h):
363 glTranslatef(x, y, 0)
364 glDisable(GL_TEXTURE_2D)
373 def glDrawTexturedQuad(x, y, w, h, texID, mirror = 0):
374 tx = float(texID % 4) / 4
375 ty = float(int(texID / 4)) / 8
385 glTranslatef(x, y, 0)
386 glEnable(GL_TEXTURE_2D)
388 glTexCoord2f(tx+tsx, ty)
392 glTexCoord2f(tx, ty+tsy)
394 glTexCoord2f(tx+tsx, ty+tsy)
399 def glDrawStretchedQuad(x, y, w, h, cornerSize, texID):
400 tx0 = float(texID % 4) / 4
401 ty0 = float(int(texID / 4)) / 8
402 tx1 = tx0 + 0.25 / 2.0
403 ty1 = ty0 + 0.125 / 2.0
408 glTranslatef(x, y, 0)
409 glEnable(GL_TEXTURE_2D)
412 glTexCoord2f(tx1, ty0)
413 glVertex2f( cornerSize, 0)
414 glTexCoord2f(tx0, ty0)
416 glTexCoord2f(tx0, ty1)
417 glVertex2f( 0, cornerSize)
418 glTexCoord2f(tx1, ty1)
419 glVertex2f( cornerSize, cornerSize)
421 glTexCoord2f(tx2, ty0)
423 glTexCoord2f(tx1, ty0)
424 glVertex2f( w - cornerSize, 0)
425 glTexCoord2f(tx1, ty1)
426 glVertex2f( w - cornerSize, cornerSize)
427 glTexCoord2f(tx2, ty1)
428 glVertex2f( w, cornerSize)
430 glTexCoord2f(tx1, ty1)
431 glVertex2f( cornerSize, h - cornerSize)
432 glTexCoord2f(tx0, ty1)
433 glVertex2f( 0, h - cornerSize)
434 glTexCoord2f(tx0, ty2)
436 glTexCoord2f(tx1, ty2)
437 glVertex2f( cornerSize, h)
439 glTexCoord2f(tx2, ty1)
440 glVertex2f( w, h - cornerSize)
441 glTexCoord2f(tx1, ty1)
442 glVertex2f( w - cornerSize, h - cornerSize)
443 glTexCoord2f(tx1, ty2)
444 glVertex2f( w - cornerSize, h)
445 glTexCoord2f(tx2, ty2)
449 glTexCoord2f(tx1, ty1)
450 glVertex2f( w-cornerSize, cornerSize)
451 glTexCoord2f(tx1, ty1)
452 glVertex2f( cornerSize, cornerSize)
453 glTexCoord2f(tx1, ty1)
454 glVertex2f( cornerSize, h-cornerSize)
455 glTexCoord2f(tx1, ty1)
456 glVertex2f( w-cornerSize, h-cornerSize)
459 glTexCoord2f(tx2, ty1)
460 glVertex2f( w, cornerSize)
461 glTexCoord2f(tx1, ty1)
462 glVertex2f( w-cornerSize, cornerSize)
463 glTexCoord2f(tx1, ty1)
464 glVertex2f( w-cornerSize, h-cornerSize)
465 glTexCoord2f(tx2, ty1)
466 glVertex2f( w, h-cornerSize)
469 glTexCoord2f(tx1, ty1)
470 glVertex2f( cornerSize, cornerSize)
471 glTexCoord2f(tx0, ty1)
472 glVertex2f( 0, cornerSize)
473 glTexCoord2f(tx0, ty1)
474 glVertex2f( 0, h-cornerSize)
475 glTexCoord2f(tx1, ty1)
476 glVertex2f( cornerSize, h-cornerSize)
479 glTexCoord2f(tx1, ty0)
480 glVertex2f( w-cornerSize, 0)
481 glTexCoord2f(tx1, ty0)
482 glVertex2f( cornerSize, 0)
483 glTexCoord2f(tx1, ty1)
484 glVertex2f( cornerSize, cornerSize)
485 glTexCoord2f(tx1, ty1)
486 glVertex2f( w-cornerSize, cornerSize)
489 glTexCoord2f(tx1, ty1)
490 glVertex2f( w-cornerSize, h-cornerSize)
491 glTexCoord2f(tx1, ty1)
492 glVertex2f( cornerSize, h-cornerSize)
493 glTexCoord2f(tx1, ty2)
494 glVertex2f( cornerSize, h)
495 glTexCoord2f(tx1, ty2)
496 glVertex2f( w-cornerSize, h)
499 glDisable(GL_TEXTURE_2D)
502 def unproject(winx, winy, winz, modelMatrix, projMatrix, viewport):
503 npModelMatrix = numpy.matrix(numpy.array(modelMatrix, numpy.float64).reshape((4,4)))
504 npProjMatrix = numpy.matrix(numpy.array(projMatrix, numpy.float64).reshape((4,4)))
505 finalMatrix = npModelMatrix * npProjMatrix
506 finalMatrix = numpy.linalg.inv(finalMatrix)
508 viewport = map(float, viewport)
509 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))
510 vector = (numpy.matrix(vector) * finalMatrix).getA().flatten()
511 ret = list(vector)[0:3] / vector[3]
514 def convert3x3MatrixTo4x4(matrix):
515 return list(matrix.getA()[0]) + [0] + list(matrix.getA()[1]) + [0] + list(matrix.getA()[2]) + [0, 0,0,0,1]
517 def loadGLTexture(filename):
518 tex = glGenTextures(1)
519 glBindTexture(GL_TEXTURE_2D, tex)
520 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
521 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
522 img = wx.ImageFromBitmap(wx.Bitmap(getPathForImage(filename)))
523 rgbData = img.GetData()
524 alphaData = img.GetAlphaData()
525 if alphaData is not None:
527 for i in xrange(0, len(alphaData)):
528 data += rgbData[i*3:i*3+3] + alphaData[i]
529 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.GetWidth(), img.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, data)
531 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.GetWidth(), img.GetHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, rgbData)
534 def ResetMatrixRotationAndScale():
535 matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
539 scale2D = matrix[0][0]
550 if matrix[3][2] != 0.0:
551 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
552 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
555 matrix[0][0] = scale2D
556 matrix[1][1] = scale2D
557 matrix[2][2] = scale2D
561 glLoadMatrixf(matrix)
565 def DrawBox(vMin, vMax):
566 glBegin(GL_LINE_LOOP)
567 glVertex3f(vMin[0], vMin[1], vMin[2])
568 glVertex3f(vMax[0], vMin[1], vMin[2])
569 glVertex3f(vMax[0], vMax[1], vMin[2])
570 glVertex3f(vMin[0], vMax[1], vMin[2])
573 glBegin(GL_LINE_LOOP)
574 glVertex3f(vMin[0], vMin[1], vMax[2])
575 glVertex3f(vMax[0], vMin[1], vMax[2])
576 glVertex3f(vMax[0], vMax[1], vMax[2])
577 glVertex3f(vMin[0], vMax[1], vMax[2])
580 glVertex3f(vMin[0], vMin[1], vMin[2])
581 glVertex3f(vMin[0], vMin[1], vMax[2])
582 glVertex3f(vMax[0], vMin[1], vMin[2])
583 glVertex3f(vMax[0], vMin[1], vMax[2])
584 glVertex3f(vMax[0], vMax[1], vMin[2])
585 glVertex3f(vMax[0], vMax[1], vMax[2])
586 glVertex3f(vMin[0], vMax[1], vMin[2])
587 glVertex3f(vMin[0], vMax[1], vMax[2])
591 def DrawMeshOutline(mesh):
592 glEnable(GL_CULL_FACE)
593 glEnableClientState(GL_VERTEX_ARRAY);
594 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
598 glPolygonMode(GL_BACK, GL_LINE)
599 glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
600 glPolygonMode(GL_BACK, GL_FILL)
603 glDisableClientState(GL_VERTEX_ARRAY)
606 def DrawMesh(mesh, insideOut = False):
607 glEnable(GL_CULL_FACE)
608 glEnableClientState(GL_VERTEX_ARRAY)
609 glEnableClientState(GL_NORMAL_ARRAY)
610 for m in mesh._meshList:
611 glVertexPointer(3, GL_FLOAT, 0, m.vertexes)
613 glNormalPointer(GL_FLOAT, 0, m.invNormal)
615 glNormalPointer(GL_FLOAT, 0, m.normal)
617 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
618 batchSize = 999 #Warning, batchSize needs to be dividable by 3
619 extraStartPos = int(m.vertexCount / batchSize) * batchSize
620 extraCount = m.vertexCount - extraStartPos
623 for i in xrange(0, int(m.vertexCount / batchSize)):
624 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
625 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
629 glNormalPointer(GL_FLOAT, 0, m.normal)
631 glNormalPointer(GL_FLOAT, 0, m.invNormal)
632 for i in xrange(0, int(m.vertexCount / batchSize)):
633 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
634 extraStartPos = int(m.vertexCount / batchSize) * batchSize
635 extraCount = m.vertexCount - extraStartPos
636 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
639 glDisableClientState(GL_VERTEX_ARRAY)
640 glDisableClientState(GL_NORMAL_ARRAY)
643 def DrawMeshSteep(mesh, matrix, angle):
644 cosAngle = math.sin(angle / 180.0 * math.pi)
645 glDisable(GL_LIGHTING)
646 glDepthFunc(GL_EQUAL)
647 normals = (numpy.matrix(mesh.normal, copy = False) * matrix).getA()
648 for i in xrange(0, int(mesh.vertexCount), 3):
649 if normals[i][2] < -0.999999:
650 if mesh.vertexes[i + 0][2] > 0.01:
652 glBegin(GL_TRIANGLES)
653 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
654 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
655 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
657 elif normals[i][2] < -cosAngle:
658 glColor3f(-normals[i][2], 0, 0)
659 glBegin(GL_TRIANGLES)
660 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
661 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
662 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
664 elif normals[i][2] > 0.999999:
665 if mesh.vertexes[i + 0][2] > 0.01:
667 glBegin(GL_TRIANGLES)
668 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
669 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
670 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
672 elif normals[i][2] > cosAngle:
673 glColor3f(normals[i][2], 0, 0)
674 glBegin(GL_TRIANGLES)
675 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
676 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
677 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
681 def DrawGCodeLayer(layer, drawQuick = True):
682 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
683 filamentArea = math.pi * filamentRadius * filamentRadius
684 lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
687 fillColorCycle = [[0.5, 0.5, 0.0, 1], [0.0, 0.5, 0.5, 1], [0.5, 0.0, 0.5, 1]]
688 moveColor = [0, 0, 1, 0.5]
689 retractColor = [1, 0, 0.5, 0.5]
690 supportColor = [0, 1, 1, 1]
691 extrudeColor = [[1, 0, 0, 1], [0, 1, 1, 1], [1, 1, 0, 1], [1, 0, 1, 1]]
692 innerWallColor = [0, 1, 0, 1]
693 skirtColor = [0, 0.5, 0.5, 1]
694 prevPathWasRetract = False
696 glDisable(GL_CULL_FACE)
698 if path.type == 'move':
699 if prevPathWasRetract:
706 if path.type == 'extrude':
707 if path.pathType == 'FILL':
708 c = fillColorCycle[fillCycle]
709 fillCycle = (fillCycle + 1) % len(fillColorCycle)
710 elif path.pathType == 'WALL-INNER':
713 elif path.pathType == 'SUPPORT':
715 elif path.pathType == 'SKIRT':
718 c = extrudeColor[path.extruder]
719 if path.type == 'retract':
721 if path.type == 'extrude' and not drawQuick:
724 for i in xrange(0, len(path.points) - 1):
726 v1 = path.points[i + 1]
728 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
729 dist = (v0 - v1).vsize()
730 if dist > 0 and path.layerThickness > 0:
731 extrusionMMperDist = (v1.e - v0.e) / dist
732 lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
734 drawLength += (v0 - v1).vsize()
735 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
738 vv2 = v0 + normal * lineWidth
739 vv3 = v1 + normal * lineWidth
740 vv0 = v0 - normal * lineWidth
741 vv1 = v1 - normal * lineWidth
745 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
746 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
747 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
748 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
750 if prevNormal is not None:
751 n = (normal + prevNormal)
753 vv4 = v0 + n * lineWidth
754 vv5 = v0 - n * lineWidth
757 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
758 glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
759 glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
760 glVertex3f(v0.x, v0.y, v0.z - zOffset)
762 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
763 glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
764 glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
765 glVertex3f(v0.x, v0.y, v0.z - zOffset)
773 glBegin(GL_TRIANGLES)
774 for v in path.points:
775 glVertex3f(v[0], v[1], v[2])
778 if not path.type == 'move':
779 prevPathWasRetract = False
780 #if path.type == 'retract' and path.points[0].almostEqual(path.points[-1]):
781 # prevPathWasRetract = True
782 glEnable(GL_CULL_FACE)