chiark / gitweb /
Added general help for plugin tab, added open plugin folder button, fixed scale to...
[cura.git] / Cura / gui / opengl.py
1 import math, time, os\r
2 \r
3 from util import meshLoader\r
4 from util import util3d\r
5 from util import profile\r
6 \r
7 try:\r
8         import OpenGL\r
9         OpenGL.ERROR_CHECKING = False\r
10         from OpenGL.GLU import *\r
11         from OpenGL.GL import *\r
12         hasOpenGLlibs = True\r
13 except:\r
14         print "Failed to find PyOpenGL: http://pyopengl.sourceforge.net/"\r
15         hasOpenGLlibs = False\r
16 \r
17 def InitGL(window, view3D, zoom):\r
18         # set viewing projection\r
19         glMatrixMode(GL_MODELVIEW)\r
20         glLoadIdentity()\r
21         size = window.GetSize()\r
22         glViewport(0,0, size.GetWidth(), size.GetHeight())\r
23         \r
24         glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])\r
25         glLightfv(GL_LIGHT1, GL_POSITION, [1.0, 1.0, 1.0, 0.0])\r
26 \r
27         glEnable(GL_RESCALE_NORMAL)\r
28         glEnable(GL_LIGHTING)\r
29         glEnable(GL_LIGHT0)\r
30         glEnable(GL_DEPTH_TEST)\r
31         glEnable(GL_CULL_FACE)\r
32         glDisable(GL_BLEND)\r
33 \r
34         glClearColor(1.0, 1.0, 1.0, 1.0)\r
35         glClearStencil(0)\r
36         glClearDepth(1.0)\r
37 \r
38         glMatrixMode(GL_PROJECTION)\r
39         glLoadIdentity()\r
40         aspect = float(size.GetWidth()) / float(size.GetHeight())\r
41         if view3D:\r
42                 gluPerspective(45.0, aspect, 1.0, 1000.0)\r
43         else:\r
44                 glOrtho(-aspect * (zoom), aspect * (zoom), -1.0 * (zoom), 1.0 * (zoom), -1000.0, 1000.0)\r
45 \r
46         glMatrixMode(GL_MODELVIEW)\r
47         glLoadIdentity()\r
48         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)\r
49 \r
50 platformMesh = None\r
51 \r
52 def DrawMachine(machineSize):\r
53         if profile.getPreference('machine_type') == 'ultimaker':\r
54                 glPushMatrix()\r
55                 glEnable(GL_LIGHTING)\r
56                 glTranslate(100,200,-5)\r
57                 glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8,0.8,0.8])\r
58                 glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5,0.5,0.5])\r
59                 glEnable(GL_BLEND)\r
60                 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR)\r
61                 \r
62                 global platformMesh\r
63                 if platformMesh == None:\r
64                         platformMesh = meshLoader.loadMesh(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../images", 'ultimaker_platform.stl')))\r
65                         platformMesh.setRotateMirror(0, False, False, False, False, False)\r
66                 \r
67                 DrawMesh(platformMesh)\r
68                 glPopMatrix()\r
69 \r
70         glDisable(GL_LIGHTING)\r
71         if False:\r
72                 glColor3f(0.7,0.7,0.7)\r
73                 glLineWidth(2)\r
74                 glBegin(GL_LINES)\r
75                 for i in xrange(0, int(machineSize.x), 10):\r
76                         glVertex3f(i, 0, 0)\r
77                         glVertex3f(i, machineSize.y, 0)\r
78                 for i in xrange(0, int(machineSize.y), 10):\r
79                         glVertex3f(0, i, 0)\r
80                         glVertex3f(machineSize.x, i, 0)\r
81                 glEnd()\r
82                 \r
83                 glEnable(GL_LINE_SMOOTH)\r
84                 glEnable(GL_BLEND)\r
85                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)\r
86                 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);\r
87 \r
88                 glColor3f(0.0,0.0,0.0)\r
89                 glLineWidth(4)\r
90                 glBegin(GL_LINE_LOOP)\r
91                 glVertex3f(0, 0, 0)\r
92                 glVertex3f(machineSize.x, 0, 0)\r
93                 glVertex3f(machineSize.x, machineSize.y, 0)\r
94                 glVertex3f(0, machineSize.y, 0)\r
95                 glEnd()\r
96                 \r
97                 glLineWidth(2)\r
98                 glBegin(GL_LINE_LOOP)\r
99                 glVertex3f(0, 0, machineSize.z)\r
100                 glVertex3f(machineSize.x, 0, machineSize.z)\r
101                 glVertex3f(machineSize.x, machineSize.y, machineSize.z)\r
102                 glVertex3f(0, machineSize.y, machineSize.z)\r
103                 glEnd()\r
104                 glBegin(GL_LINES)\r
105                 glVertex3f(0, 0, 0)\r
106                 glVertex3f(0, 0, machineSize.z)\r
107                 glVertex3f(machineSize.x, 0, 0)\r
108                 glVertex3f(machineSize.x, 0, machineSize.z)\r
109                 glVertex3f(machineSize.x, machineSize.y, 0)\r
110                 glVertex3f(machineSize.x, machineSize.y, machineSize.z)\r
111                 glVertex3f(0, machineSize.y, 0)\r
112                 glVertex3f(0, machineSize.y, machineSize.z)\r
113                 glEnd()\r
114         else:\r
115                 glDisable(GL_CULL_FACE)\r
116                 glEnable(GL_BLEND)\r
117                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)\r
118                 glColor4ub(5,171,231,127)\r
119                 glBegin(GL_QUADS)\r
120                 for x in xrange(0, int(machineSize.x), 20):\r
121                         for y in xrange(0, int(machineSize.y), 20):\r
122                                 glVertex3f(x, y, -0.01)\r
123                                 glVertex3f(min(x+10, machineSize.x), y, -0.01)\r
124                                 glVertex3f(min(x+10, machineSize.x), min(y+10, machineSize.y), -0.01)\r
125                                 glVertex3f(x, min(y+10, machineSize.y), -0.01)\r
126                 for x in xrange(10, int(machineSize.x), 20):\r
127                         for y in xrange(10, int(machineSize.y), 20):\r
128                                 glVertex3f(x, y, -0.01)\r
129                                 glVertex3f(min(x+10, machineSize.x), y, -0.01)\r
130                                 glVertex3f(min(x+10, machineSize.x), min(y+10, machineSize.y), -0.01)\r
131                                 glVertex3f(x, min(y+10, machineSize.y), -0.01)\r
132                 glEnd()\r
133                 glColor4ub(5*8/10,171*8/10,231*8/10,128)\r
134                 glBegin(GL_QUADS)\r
135                 for x in xrange(10, int(machineSize.x), 20):\r
136                         for y in xrange(0, int(machineSize.y), 20):\r
137                                 glVertex3f(x, y, -0.01)\r
138                                 glVertex3f(min(x+10, machineSize.x), y, -0.01)\r
139                                 glVertex3f(min(x+10, machineSize.x), min(y+10, machineSize.y), -0.01)\r
140                                 glVertex3f(x, min(y+10, machineSize.y), -0.01)\r
141                 for x in xrange(0, int(machineSize.x), 20):\r
142                         for y in xrange(10, int(machineSize.y), 20):\r
143                                 glVertex3f(x, y, -0.01)\r
144                                 glVertex3f(min(x+10, machineSize.x), y, -0.01)\r
145                                 glVertex3f(min(x+10, machineSize.x), min(y+10, machineSize.y), -0.01)\r
146                                 glVertex3f(x, min(y+10, machineSize.y), -0.01)\r
147                 glEnd()\r
148                 glEnable(GL_CULL_FACE)\r
149 \r
150                 glColor4ub(5,171,231,64)\r
151                 glBegin(GL_QUADS)\r
152                 glVertex3f(0, 0, machineSize.z)\r
153                 glVertex3f(0, machineSize.y, machineSize.z)\r
154                 glVertex3f(machineSize.x, machineSize.y, machineSize.z)\r
155                 glVertex3f(machineSize.x, 0, machineSize.z)\r
156                 glEnd()\r
157                 \r
158                 glColor4ub(5,171,231,96)\r
159                 glBegin(GL_QUADS)\r
160                 glVertex3f(0, 0, 0)\r
161                 glVertex3f(0, 0, machineSize.z)\r
162                 glVertex3f(machineSize.x, 0, machineSize.z)\r
163                 glVertex3f(machineSize.x, 0, 0)\r
164 \r
165                 glVertex3f(0, machineSize.y, machineSize.z)\r
166                 glVertex3f(0, machineSize.y, 0)\r
167                 glVertex3f(machineSize.x, machineSize.y, 0)\r
168                 glVertex3f(machineSize.x, machineSize.y, machineSize.z)\r
169                 glEnd()\r
170 \r
171                 glColor4ub(5,171,231,128)\r
172                 glBegin(GL_QUADS)\r
173                 glVertex3f(0, 0, machineSize.z)\r
174                 glVertex3f(0, 0, 0)\r
175                 glVertex3f(0, machineSize.y, 0)\r
176                 glVertex3f(0, machineSize.y, machineSize.z)\r
177 \r
178                 glVertex3f(machineSize.x, 0, 0)\r
179                 glVertex3f(machineSize.x, 0, machineSize.z)\r
180                 glVertex3f(machineSize.x, machineSize.y, machineSize.z)\r
181                 glVertex3f(machineSize.x, machineSize.y, 0)\r
182                 glEnd()\r
183 \r
184                 glDisable(GL_BLEND)\r
185         \r
186         glPushMatrix()\r
187         glTranslate(5,5,2)\r
188         glLineWidth(2)\r
189         glColor3f(0.5,0,0)\r
190         glBegin(GL_LINES)\r
191         glVertex3f(0,0,0)\r
192         glVertex3f(20,0,0)\r
193         glEnd()\r
194         glColor3f(0,0.5,0)\r
195         glBegin(GL_LINES)\r
196         glVertex3f(0,0,0)\r
197         glVertex3f(0,20,0)\r
198         glEnd()\r
199         glColor3f(0,0,0.5)\r
200         glBegin(GL_LINES)\r
201         glVertex3f(0,0,0)\r
202         glVertex3f(0,0,20)\r
203         glEnd()\r
204 \r
205         glDisable(GL_DEPTH_TEST)\r
206         #X\r
207         glColor3f(1,0,0)\r
208         glPushMatrix()\r
209         glTranslate(23,0,0)\r
210         noZ = ResetMatrixRotationAndScale()\r
211         glBegin(GL_LINES)\r
212         glVertex3f(-0.8,1,0)\r
213         glVertex3f(0.8,-1,0)\r
214         glVertex3f(0.8,1,0)\r
215         glVertex3f(-0.8,-1,0)\r
216         glEnd()\r
217         glPopMatrix()\r
218 \r
219         #Y\r
220         glColor3f(0,1,0)\r
221         glPushMatrix()\r
222         glTranslate(0,23,0)\r
223         ResetMatrixRotationAndScale()\r
224         glBegin(GL_LINES)\r
225         glVertex3f(-0.8, 1,0)\r
226         glVertex3f( 0.0, 0,0)\r
227         glVertex3f( 0.8, 1,0)\r
228         glVertex3f(-0.8,-1,0)\r
229         glEnd()\r
230         glPopMatrix()\r
231 \r
232         #Z\r
233         if not noZ:\r
234                 glColor3f(0,0,1)\r
235                 glPushMatrix()\r
236                 glTranslate(0,0,23)\r
237                 ResetMatrixRotationAndScale()\r
238                 glBegin(GL_LINES)\r
239                 glVertex3f(-0.8, 1,0)\r
240                 glVertex3f( 0.8, 1,0)\r
241                 glVertex3f( 0.8, 1,0)\r
242                 glVertex3f(-0.8,-1,0)\r
243                 glVertex3f(-0.8,-1,0)\r
244                 glVertex3f( 0.8,-1,0)\r
245                 glEnd()\r
246                 glPopMatrix()\r
247 \r
248         glPopMatrix()\r
249         glEnable(GL_DEPTH_TEST)\r
250         \r
251 def ResetMatrixRotationAndScale():\r
252         matrix = glGetFloatv(GL_MODELVIEW_MATRIX)\r
253         noZ = False\r
254         if matrix[3][2] > 0:\r
255                 return False\r
256         scale2D = matrix[0][0]\r
257         matrix[0][0] = 1.0\r
258         matrix[1][0] = 0.0\r
259         matrix[2][0] = 0.0\r
260         matrix[0][1] = 0.0\r
261         matrix[1][1] = 1.0\r
262         matrix[2][1] = 0.0\r
263         matrix[0][2] = 0.0\r
264         matrix[1][2] = 0.0\r
265         matrix[2][2] = 1.0\r
266         \r
267         if matrix[3][2] != 0.0:\r
268                 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)\r
269                 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)\r
270                 matrix[3][2] = -100\r
271         else:\r
272                 matrix[0][0] = scale2D\r
273                 matrix[1][1] = scale2D\r
274                 matrix[2][2] = scale2D\r
275                 matrix[3][2] = -100\r
276                 noZ = True\r
277         \r
278         glLoadMatrixf(matrix)\r
279         return noZ\r
280 \r
281 def DrawBox(vMin, vMax):\r
282         glBegin(GL_LINE_LOOP)\r
283         glVertex3f(vMin[0], vMin[1], vMin[2])\r
284         glVertex3f(vMax[0], vMin[1], vMin[2])\r
285         glVertex3f(vMax[0], vMax[1], vMin[2])\r
286         glVertex3f(vMin[0], vMax[1], vMin[2])\r
287         glEnd()\r
288 \r
289         glBegin(GL_LINE_LOOP)\r
290         glVertex3f(vMin[0], vMin[1], vMax[2])\r
291         glVertex3f(vMax[0], vMin[1], vMax[2])\r
292         glVertex3f(vMax[0], vMax[1], vMax[2])\r
293         glVertex3f(vMin[0], vMax[1], vMax[2])\r
294         glEnd()\r
295         glBegin(GL_LINES)\r
296         glVertex3f(vMin[0], vMin[1], vMin[2])\r
297         glVertex3f(vMin[0], vMin[1], vMax[2])\r
298         glVertex3f(vMax[0], vMin[1], vMin[2])\r
299         glVertex3f(vMax[0], vMin[1], vMax[2])\r
300         glVertex3f(vMax[0], vMax[1], vMin[2])\r
301         glVertex3f(vMax[0], vMax[1], vMax[2])\r
302         glVertex3f(vMin[0], vMax[1], vMin[2])\r
303         glVertex3f(vMin[0], vMax[1], vMax[2])\r
304         glEnd()\r
305 \r
306 def DrawMeshOutline(mesh):\r
307         glEnable(GL_CULL_FACE)\r
308         glEnableClientState(GL_VERTEX_ARRAY);\r
309         glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)\r
310 \r
311         glCullFace(GL_FRONT)\r
312         glLineWidth(3)\r
313         glPolygonMode(GL_BACK, GL_LINE)\r
314         glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)\r
315         glPolygonMode(GL_BACK, GL_FILL)\r
316         glCullFace(GL_BACK)\r
317         \r
318         glDisableClientState(GL_VERTEX_ARRAY)\r
319 \r
320 def DrawMesh(mesh):\r
321         glEnable(GL_CULL_FACE)\r
322         glEnableClientState(GL_VERTEX_ARRAY);\r
323         glEnableClientState(GL_NORMAL_ARRAY);\r
324         glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)\r
325         glNormalPointer(GL_FLOAT, 0, mesh.normal)\r
326 \r
327         #Odd, drawing in batchs is a LOT faster then drawing it all at once.\r
328         batchSize = 999 #Warning, batchSize needs to be dividable by 3\r
329         extraStartPos = int(mesh.vertexCount / batchSize) * batchSize\r
330         extraCount = mesh.vertexCount - extraStartPos\r
331         \r
332         glCullFace(GL_BACK)\r
333         for i in xrange(0, int(mesh.vertexCount / batchSize)):\r
334                 glDrawArrays(GL_TRIANGLES, i*batchSize, batchSize)\r
335         glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)\r
336         \r
337         glCullFace(GL_FRONT)\r
338         glNormalPointer(GL_FLOAT, 0, mesh.invNormal)\r
339         for i in xrange(0, int(mesh.vertexCount / batchSize)):\r
340                 glDrawArrays(GL_TRIANGLES, i*batchSize, batchSize)\r
341         extraStartPos = int(mesh.vertexCount / batchSize) * batchSize\r
342         extraCount = mesh.vertexCount - extraStartPos\r
343         glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)\r
344         glCullFace(GL_BACK)\r
345         \r
346         glDisableClientState(GL_VERTEX_ARRAY)\r
347         glDisableClientState(GL_NORMAL_ARRAY);\r
348 \r
349 def DrawMeshSteep(mesh, angle):\r
350         cosAngle = math.sin(angle / 180.0 * math.pi)\r
351         glDisable(GL_LIGHTING)\r
352         glDepthFunc(GL_EQUAL)\r
353         for i in xrange(0, int(mesh.vertexCount), 3):\r
354                 if mesh.normal[i][2] < -0.999999:\r
355                         if mesh.vertexes[i+0][2] > 0.01:\r
356                                 glColor3f(0.5,0,0)\r
357                                 glBegin(GL_TRIANGLES)\r
358                                 glVertex3f(mesh.vertexes[i+0][0], mesh.vertexes[i+0][1], mesh.vertexes[i+0][2])\r
359                                 glVertex3f(mesh.vertexes[i+1][0], mesh.vertexes[i+1][1], mesh.vertexes[i+1][2])\r
360                                 glVertex3f(mesh.vertexes[i+2][0], mesh.vertexes[i+2][1], mesh.vertexes[i+2][2])\r
361                                 glEnd()\r
362                 elif mesh.normal[i][2] < -cosAngle:\r
363                         glColor3f(-mesh.normal[i][2],0,0)\r
364                         glBegin(GL_TRIANGLES)\r
365                         glVertex3f(mesh.vertexes[i+0][0], mesh.vertexes[i+0][1], mesh.vertexes[i+0][2])\r
366                         glVertex3f(mesh.vertexes[i+1][0], mesh.vertexes[i+1][1], mesh.vertexes[i+1][2])\r
367                         glVertex3f(mesh.vertexes[i+2][0], mesh.vertexes[i+2][1], mesh.vertexes[i+2][2])\r
368                         glEnd()\r
369                 elif mesh.normal[i][2] > 0.999999:\r
370                         if mesh.vertexes[i+0][2] > 0.01:\r
371                                 glColor3f(0.5,0,0)\r
372                                 glBegin(GL_TRIANGLES)\r
373                                 glVertex3f(mesh.vertexes[i+0][0], mesh.vertexes[i+0][1], mesh.vertexes[i+0][2])\r
374                                 glVertex3f(mesh.vertexes[i+2][0], mesh.vertexes[i+2][1], mesh.vertexes[i+2][2])\r
375                                 glVertex3f(mesh.vertexes[i+1][0], mesh.vertexes[i+1][1], mesh.vertexes[i+1][2])\r
376                                 glEnd()\r
377                 elif mesh.normal[i][2] > cosAngle:\r
378                         glColor3f(mesh.normal[i][2],0,0)\r
379                         glBegin(GL_TRIANGLES)\r
380                         glVertex3f(mesh.vertexes[i+0][0], mesh.vertexes[i+0][1], mesh.vertexes[i+0][2])\r
381                         glVertex3f(mesh.vertexes[i+2][0], mesh.vertexes[i+2][1], mesh.vertexes[i+2][2])\r
382                         glVertex3f(mesh.vertexes[i+1][0], mesh.vertexes[i+1][1], mesh.vertexes[i+1][2])\r
383                         glEnd()\r
384         glDepthFunc(GL_LESS)\r
385 \r
386 def DrawGCodeLayer(layer):\r
387         filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2\r
388         filamentArea = math.pi * filamentRadius * filamentRadius\r
389         lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10\r
390         \r
391         fillCycle = 0\r
392         fillColorCycle = [[0.5,0.5,0.0],[0.0,0.5,0.5],[0.5,0.0,0.5]]\r
393         moveColor = [0,0,1]\r
394         retractColor = [1,0,0.5]\r
395         supportColor = [0,1,1]\r
396         extrudeColor = [1,0,0]\r
397         innerWallColor = [0,1,0]\r
398         skirtColor = [0,0.5,0.5]\r
399         prevPathWasRetract = False\r
400         \r
401         glDisable(GL_CULL_FACE)\r
402         for path in layer:\r
403                 if path.type == 'move':\r
404                         if prevPathWasRetract:\r
405                                 c = retractColor\r
406                         else:\r
407                                 c = moveColor\r
408                 zOffset = 0.01\r
409                 if path.type == 'extrude':\r
410                         if path.pathType == 'FILL':\r
411                                 c = fillColorCycle[fillCycle]\r
412                                 fillCycle = (fillCycle + 1) % len(fillColorCycle)\r
413                         elif path.pathType == 'WALL-INNER':\r
414                                 c = innerWallColor\r
415                                 zOffset = 0.02\r
416                         elif path.pathType == 'SUPPORT':\r
417                                 c = supportColor\r
418                         elif path.pathType == 'SKIRT':\r
419                                 c = skirtColor\r
420                         else:\r
421                                 c = extrudeColor\r
422                 if path.type == 'retract':\r
423                         c = [0,1,1]\r
424                 if path.type == 'extrude':\r
425                         drawLength = 0.0\r
426                         prevNormal = None\r
427                         for i in xrange(0, len(path.list)-1):\r
428                                 v0 = path.list[i]\r
429                                 v1 = path.list[i+1]\r
430 \r
431                                 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)\r
432                                 dist = (v0 - v1).vsize()\r
433                                 if dist > 0 and path.layerThickness > 0:\r
434                                         extrusionMMperDist = (v1.e - v0.e) / dist\r
435                                         lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply\r
436 \r
437                                 drawLength += (v0 - v1).vsize()\r
438                                 normal = (v0 - v1).cross(util3d.Vector3(0,0,1))\r
439                                 normal.normalize()\r
440 \r
441                                 vv2 = v0 + normal * lineWidth\r
442                                 vv3 = v1 + normal * lineWidth\r
443                                 vv0 = v0 - normal * lineWidth\r
444                                 vv1 = v1 - normal * lineWidth\r
445 \r
446                                 glBegin(GL_QUADS)\r
447                                 glColor3fv(c)\r
448                                 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)\r
449                                 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)\r
450                                 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)\r
451                                 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)\r
452                                 glEnd()\r
453                                 if prevNormal != None:\r
454                                         n = (normal + prevNormal)\r
455                                         n.normalize()\r
456                                         vv4 = v0 + n * lineWidth\r
457                                         vv5 = v0 - n * lineWidth\r
458                                         glBegin(GL_QUADS)\r
459                                         glColor3fv(c)\r
460                                         glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)\r
461                                         glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)\r
462                                         glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)\r
463                                         glVertex3f(v0.x, v0.y, v0.z - zOffset)\r
464                                         \r
465                                         glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)\r
466                                         glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)\r
467                                         glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)\r
468                                         glVertex3f(v0.x, v0.y, v0.z - zOffset)\r
469                                         glEnd()\r
470                                         \r
471                                 prevNormal = normal\r
472                                 prevVv1 = vv1\r
473                                 prevVv3 = vv3\r
474                 else:\r
475                         glBegin(GL_LINE_STRIP)\r
476                         glColor3fv(c)\r
477                         for v in path.list:\r
478                                 glVertex3f(v.x, v.y, v.z)\r
479                         glEnd()\r
480                 if not path.type == 'move':\r
481                         prevPathWasRetract = False\r
482                 if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):\r
483                         prevPathWasRetract = True\r
484         glEnable(GL_CULL_FACE)\r