chiark / gitweb /
Fixed the top down view light issue, made the project planner use the configured...
[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 DrawGCodeLayer(layer):\r
350         filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2\r
351         filamentArea = math.pi * filamentRadius * filamentRadius\r
352         lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10\r
353         \r
354         fillCycle = 0\r
355         fillColorCycle = [[0.5,0.5,0.0],[0.0,0.5,0.5],[0.5,0.0,0.5]]\r
356         moveColor = [0,0,1]\r
357         retractColor = [1,0,0.5]\r
358         supportColor = [0,1,1]\r
359         extrudeColor = [1,0,0]\r
360         innerWallColor = [0,1,0]\r
361         skirtColor = [0,0.5,0.5]\r
362         prevPathWasRetract = False\r
363         \r
364         glDisable(GL_CULL_FACE)\r
365         for path in layer:\r
366                 if path.type == 'move':\r
367                         if prevPathWasRetract:\r
368                                 c = retractColor\r
369                         else:\r
370                                 c = moveColor\r
371                 zOffset = 0.01\r
372                 if path.type == 'extrude':\r
373                         if path.pathType == 'FILL':\r
374                                 c = fillColorCycle[fillCycle]\r
375                                 fillCycle = (fillCycle + 1) % len(fillColorCycle)\r
376                         elif path.pathType == 'WALL-INNER':\r
377                                 c = innerWallColor\r
378                                 zOffset = 0.02\r
379                         elif path.pathType == 'SUPPORT':\r
380                                 c = supportColor\r
381                         elif path.pathType == 'SKIRT':\r
382                                 c = skirtColor\r
383                         else:\r
384                                 c = extrudeColor\r
385                 if path.type == 'retract':\r
386                         c = [0,1,1]\r
387                 if path.type == 'extrude':\r
388                         drawLength = 0.0\r
389                         prevNormal = None\r
390                         for i in xrange(0, len(path.list)-1):\r
391                                 v0 = path.list[i]\r
392                                 v1 = path.list[i+1]\r
393 \r
394                                 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)\r
395                                 dist = (v0 - v1).vsize()\r
396                                 if dist > 0 and path.layerThickness > 0:\r
397                                         extrusionMMperDist = (v1.e - v0.e) / dist\r
398                                         lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply\r
399 \r
400                                 drawLength += (v0 - v1).vsize()\r
401                                 normal = (v0 - v1).cross(util3d.Vector3(0,0,1))\r
402                                 normal.normalize()\r
403 \r
404                                 vv2 = v0 + normal * lineWidth\r
405                                 vv3 = v1 + normal * lineWidth\r
406                                 vv0 = v0 - normal * lineWidth\r
407                                 vv1 = v1 - normal * lineWidth\r
408 \r
409                                 glBegin(GL_QUADS)\r
410                                 glColor3fv(c)\r
411                                 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)\r
412                                 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)\r
413                                 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)\r
414                                 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)\r
415                                 glEnd()\r
416                                 if prevNormal != None:\r
417                                         n = (normal + prevNormal)\r
418                                         n.normalize()\r
419                                         vv4 = v0 + n * lineWidth\r
420                                         vv5 = v0 - n * lineWidth\r
421                                         glBegin(GL_QUADS)\r
422                                         glColor3fv(c)\r
423                                         glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)\r
424                                         glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)\r
425                                         glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)\r
426                                         glVertex3f(v0.x, v0.y, v0.z - zOffset)\r
427                                         \r
428                                         glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)\r
429                                         glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)\r
430                                         glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)\r
431                                         glVertex3f(v0.x, v0.y, v0.z - zOffset)\r
432                                         glEnd()\r
433                                         \r
434                                 prevNormal = normal\r
435                                 prevVv1 = vv1\r
436                                 prevVv3 = vv3\r
437                 else:\r
438                         glBegin(GL_LINE_STRIP)\r
439                         glColor3fv(c)\r
440                         for v in path.list:\r
441                                 glVertex3f(v.x, v.y, v.z)\r
442                         glEnd()\r
443                 if not path.type == 'move':\r
444                         prevPathWasRetract = False\r
445                 if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):\r
446                         prevPathWasRetract = True\r
447         glEnable(GL_CULL_FACE)\r