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