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