chiark / gitweb /
Update on the font draw.
[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(0,0)
216         glBitmap(0,0,0,0, -5, -5, None)
217         glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord('X'))
218         glPopMatrix()
219
220         #Y
221         glColor3f(0, 1, 0)
222         glPushMatrix()
223         glTranslate(0, 23, 0)
224         glRasterPos2f(0,0)
225         glBitmap(0,0,0,0, -5, -5, None)
226         glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord('Y'))
227         glPopMatrix()
228
229         #Z
230         if not noZ:
231                 glColor3f(0, 0, 1)
232                 glPushMatrix()
233                 glTranslate(0, 0, 23)
234                 glRasterPos2f(0,0)
235                 glBitmap(0,0,0,0, -5, -5, None)
236                 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord('Z'))
237                 glPopMatrix()
238
239         glPopMatrix()
240         glEnable(GL_DEPTH_TEST)
241
242
243 def ResetMatrixRotationAndScale():
244         matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
245         noZ = False
246         if matrix[3][2] > 0:
247                 return False
248         scale2D = matrix[0][0]
249         matrix[0][0] = 1.0
250         matrix[1][0] = 0.0
251         matrix[2][0] = 0.0
252         matrix[0][1] = 0.0
253         matrix[1][1] = 1.0
254         matrix[2][1] = 0.0
255         matrix[0][2] = 0.0
256         matrix[1][2] = 0.0
257         matrix[2][2] = 1.0
258
259         if matrix[3][2] != 0.0:
260                 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
261                 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
262                 matrix[3][2] = -100
263         else:
264                 matrix[0][0] = scale2D
265                 matrix[1][1] = scale2D
266                 matrix[2][2] = scale2D
267                 matrix[3][2] = -100
268                 noZ = True
269
270         glLoadMatrixf(matrix)
271         return noZ
272
273
274 def DrawBox(vMin, vMax):
275         glBegin(GL_LINE_LOOP)
276         glVertex3f(vMin[0], vMin[1], vMin[2])
277         glVertex3f(vMax[0], vMin[1], vMin[2])
278         glVertex3f(vMax[0], vMax[1], vMin[2])
279         glVertex3f(vMin[0], vMax[1], vMin[2])
280         glEnd()
281
282         glBegin(GL_LINE_LOOP)
283         glVertex3f(vMin[0], vMin[1], vMax[2])
284         glVertex3f(vMax[0], vMin[1], vMax[2])
285         glVertex3f(vMax[0], vMax[1], vMax[2])
286         glVertex3f(vMin[0], vMax[1], vMax[2])
287         glEnd()
288         glBegin(GL_LINES)
289         glVertex3f(vMin[0], vMin[1], vMin[2])
290         glVertex3f(vMin[0], vMin[1], vMax[2])
291         glVertex3f(vMax[0], vMin[1], vMin[2])
292         glVertex3f(vMax[0], vMin[1], vMax[2])
293         glVertex3f(vMax[0], vMax[1], vMin[2])
294         glVertex3f(vMax[0], vMax[1], vMax[2])
295         glVertex3f(vMin[0], vMax[1], vMin[2])
296         glVertex3f(vMin[0], vMax[1], vMax[2])
297         glEnd()
298
299
300 def DrawMeshOutline(mesh):
301         glEnable(GL_CULL_FACE)
302         glEnableClientState(GL_VERTEX_ARRAY);
303         glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
304
305         glCullFace(GL_FRONT)
306         glLineWidth(3)
307         glPolygonMode(GL_BACK, GL_LINE)
308         glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
309         glPolygonMode(GL_BACK, GL_FILL)
310         glCullFace(GL_BACK)
311
312         glDisableClientState(GL_VERTEX_ARRAY)
313
314
315 def DrawMesh(mesh):
316         glEnable(GL_CULL_FACE)
317         glEnableClientState(GL_VERTEX_ARRAY);
318         glEnableClientState(GL_NORMAL_ARRAY);
319         glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
320         glNormalPointer(GL_FLOAT, 0, mesh.normal)
321
322         #Odd, drawing in batchs is a LOT faster then drawing it all at once.
323         batchSize = 999    #Warning, batchSize needs to be dividable by 3
324         extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
325         extraCount = mesh.vertexCount - extraStartPos
326
327         glCullFace(GL_BACK)
328         for i in xrange(0, int(mesh.vertexCount / batchSize)):
329                 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
330         glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
331
332         glCullFace(GL_FRONT)
333         glNormalPointer(GL_FLOAT, 0, mesh.invNormal)
334         for i in xrange(0, int(mesh.vertexCount / batchSize)):
335                 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
336         extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
337         extraCount = mesh.vertexCount - extraStartPos
338         glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
339         glCullFace(GL_BACK)
340
341         glDisableClientState(GL_VERTEX_ARRAY)
342         glDisableClientState(GL_NORMAL_ARRAY);
343
344
345 def DrawMeshSteep(mesh, angle):
346         cosAngle = math.sin(angle / 180.0 * math.pi)
347         glDisable(GL_LIGHTING)
348         glDepthFunc(GL_EQUAL)
349         for i in xrange(0, int(mesh.vertexCount), 3):
350                 if mesh.normal[i][2] < -0.999999:
351                         if mesh.vertexes[i + 0][2] > 0.01:
352                                 glColor3f(0.5, 0, 0)
353                                 glBegin(GL_TRIANGLES)
354                                 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
355                                 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
356                                 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
357                                 glEnd()
358                 elif mesh.normal[i][2] < -cosAngle:
359                         glColor3f(-mesh.normal[i][2], 0, 0)
360                         glBegin(GL_TRIANGLES)
361                         glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
362                         glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
363                         glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
364                         glEnd()
365                 elif mesh.normal[i][2] > 0.999999:
366                         if mesh.vertexes[i + 0][2] > 0.01:
367                                 glColor3f(0.5, 0, 0)
368                                 glBegin(GL_TRIANGLES)
369                                 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
370                                 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
371                                 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
372                                 glEnd()
373                 elif mesh.normal[i][2] > cosAngle:
374                         glColor3f(mesh.normal[i][2], 0, 0)
375                         glBegin(GL_TRIANGLES)
376                         glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
377                         glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
378                         glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
379                         glEnd()
380         glDepthFunc(GL_LESS)
381
382
383 def DrawGCodeLayer(layer):
384         filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
385         filamentArea = math.pi * filamentRadius * filamentRadius
386         lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
387
388         fillCycle = 0
389         fillColorCycle = [[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]
390         moveColor = [0, 0, 1]
391         retractColor = [1, 0, 0.5]
392         supportColor = [0, 1, 1]
393         extrudeColor = [1, 0, 0]
394         innerWallColor = [0, 1, 0]
395         skirtColor = [0, 0.5, 0.5]
396         prevPathWasRetract = False
397
398         glDisable(GL_CULL_FACE)
399         for path in layer:
400                 if path.type == 'move':
401                         if prevPathWasRetract:
402                                 c = retractColor
403                         else:
404                                 c = moveColor
405                 zOffset = 0.01
406                 if path.type == 'extrude':
407                         if path.pathType == 'FILL':
408                                 c = fillColorCycle[fillCycle]
409                                 fillCycle = (fillCycle + 1) % len(fillColorCycle)
410                         elif path.pathType == 'WALL-INNER':
411                                 c = innerWallColor
412                                 zOffset = 0.02
413                         elif path.pathType == 'SUPPORT':
414                                 c = supportColor
415                         elif path.pathType == 'SKIRT':
416                                 c = skirtColor
417                         else:
418                                 c = extrudeColor
419                 if path.type == 'retract':
420                         c = [0, 1, 1]
421                 if path.type == 'extrude':
422                         drawLength = 0.0
423                         prevNormal = None
424                         for i in xrange(0, len(path.list) - 1):
425                                 v0 = path.list[i]
426                                 v1 = path.list[i + 1]
427
428                                 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
429                                 dist = (v0 - v1).vsize()
430                                 if dist > 0 and path.layerThickness > 0:
431                                         extrusionMMperDist = (v1.e - v0.e) / dist
432                                         lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
433
434                                 drawLength += (v0 - v1).vsize()
435                                 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
436                                 normal.normalize()
437
438                                 vv2 = v0 + normal * lineWidth
439                                 vv3 = v1 + normal * lineWidth
440                                 vv0 = v0 - normal * lineWidth
441                                 vv1 = v1 - normal * lineWidth
442
443                                 glBegin(GL_QUADS)
444                                 glColor3fv(c)
445                                 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
446                                 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
447                                 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
448                                 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
449                                 glEnd()
450                                 if prevNormal is not None:
451                                         n = (normal + prevNormal)
452                                         n.normalize()
453                                         vv4 = v0 + n * lineWidth
454                                         vv5 = v0 - n * lineWidth
455                                         glBegin(GL_QUADS)
456                                         glColor3fv(c)
457                                         glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
458                                         glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
459                                         glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
460                                         glVertex3f(v0.x, v0.y, v0.z - zOffset)
461
462                                         glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
463                                         glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
464                                         glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
465                                         glVertex3f(v0.x, v0.y, v0.z - zOffset)
466                                         glEnd()
467
468                                 prevNormal = normal
469                                 prevVv1 = vv1
470                                 prevVv3 = vv3
471                 else:
472                         glBegin(GL_LINE_STRIP)
473                         glColor3fv(c)
474                         for v in path.list:
475                                 glVertex3f(v.x, v.y, v.z)
476                         glEnd()
477                 if not path.type == 'move':
478                         prevPathWasRetract = False
479                 if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):
480                         prevPathWasRetract = True
481         glEnable(GL_CULL_FACE)