2 from __future__ import absolute_import
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
14 OpenGL.ERROR_CHECKING = False
15 from OpenGL.GLUT import *
16 from OpenGL.GLU import *
17 from OpenGL.GL import *
21 print "Failed to find PyOpenGL: http://pyopengl.sourceforge.net/"
24 def InitGL(window, view3D, zoom):
25 # set viewing projection
26 glMatrixMode(GL_MODELVIEW)
28 size = window.GetSize()
29 glViewport(0, 0, size.GetWidth(), size.GetHeight())
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])
34 glEnable(GL_RESCALE_NORMAL)
37 glEnable(GL_DEPTH_TEST)
38 glEnable(GL_CULL_FACE)
41 glClearColor(1.0, 1.0, 1.0, 1.0)
45 glMatrixMode(GL_PROJECTION)
47 aspect = float(size.GetWidth()) / float(size.GetHeight())
49 gluPerspective(45.0, aspect, 1.0, 1000.0)
51 glOrtho(-aspect * (zoom), aspect * (zoom), -1.0 * (zoom), 1.0 * (zoom), -1000.0, 1000.0)
53 glMatrixMode(GL_MODELVIEW)
55 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
59 def DrawMachine(machineSize):
60 if profile.getPreference('machine_type') == 'ultimaker':
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])
67 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR)
70 if platformMesh is None:
72 platformMesh = meshLoader.loadMesh(getPathForMesh('ultimaker_platform.stl'))
77 DrawMesh(platformMesh)
80 glDisable(GL_LIGHTING)
82 glColor3f(0.7, 0.7, 0.7)
85 for i in xrange(0, int(machineSize.x), 10):
87 glVertex3f(i, machineSize.y, 0)
88 for i in xrange(0, int(machineSize.y), 10):
90 glVertex3f(machineSize.x, i, 0)
93 glEnable(GL_LINE_SMOOTH)
95 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
96 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
98 glColor3f(0.0, 0.0, 0.0)
100 glBegin(GL_LINE_LOOP)
102 glVertex3f(machineSize.x, 0, 0)
103 glVertex3f(machineSize.x, machineSize.y, 0)
104 glVertex3f(0, machineSize.y, 0)
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)
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)
125 glDisable(GL_CULL_FACE)
127 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
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):
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)
144 glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128)
146 glVertex3f(x1, y1, -0.01)
147 glVertex3f(x2, y1, -0.01)
148 glVertex3f(x2, y2, -0.01)
149 glVertex3f(x1, y2, -0.01)
152 glEnable(GL_CULL_FACE)
154 glColor4ub(5, 171, 231, 64)
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)
162 glColor4ub(5, 171, 231, 96)
165 glVertex3f(0, 0, machineSize.z)
166 glVertex3f(machineSize.x, 0, machineSize.z)
167 glVertex3f(machineSize.x, 0, 0)
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)
175 glColor4ub(5, 171, 231, 128)
177 glVertex3f(0, 0, machineSize.z)
179 glVertex3f(0, machineSize.y, 0)
180 glVertex3f(0, machineSize.y, machineSize.z)
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)
209 glDisable(GL_DEPTH_TEST)
213 glTranslate(23, 0, 0)
214 noZ = ResetMatrixRotationAndScale()
216 glVertex3f(-0.8, 1, 0)
217 glVertex3f(0.8, -1, 0)
218 glVertex3f(0.8, 1, 0)
219 glVertex3f(-0.8, -1, 0)
226 glTranslate(0, 23, 0)
227 ResetMatrixRotationAndScale()
229 glVertex3f(-0.8, 1, 0)
230 glVertex3f(0.0, 0, 0)
231 glVertex3f(0.8, 1, 0)
232 glVertex3f(-0.8, -1, 0)
240 glTranslate(0, 0, 23)
241 ResetMatrixRotationAndScale()
243 glVertex3f(-0.8, 1, 0)
244 glVertex3f(0.8, 1, 0)
245 glVertex3f(0.8, 1, 0)
246 glVertex3f(-0.8, -1, 0)
247 glVertex3f(-0.8, -1, 0)
248 glVertex3f(0.8, -1, 0)
250 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, 64)
251 glutStrokeCharacter(GLUT_STROKE_ROMAN, 64)
255 glEnable(GL_DEPTH_TEST)
258 def ResetMatrixRotationAndScale():
259 matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
263 scale2D = matrix[0][0]
274 if matrix[3][2] != 0.0:
275 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
276 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
279 matrix[0][0] = scale2D
280 matrix[1][1] = scale2D
281 matrix[2][2] = scale2D
285 glLoadMatrixf(matrix)
289 def DrawBox(vMin, vMax):
290 glBegin(GL_LINE_LOOP)
291 glVertex3f(vMin[0], vMin[1], vMin[2])
292 glVertex3f(vMax[0], vMin[1], vMin[2])
293 glVertex3f(vMax[0], vMax[1], vMin[2])
294 glVertex3f(vMin[0], vMax[1], vMin[2])
297 glBegin(GL_LINE_LOOP)
298 glVertex3f(vMin[0], vMin[1], vMax[2])
299 glVertex3f(vMax[0], vMin[1], vMax[2])
300 glVertex3f(vMax[0], vMax[1], vMax[2])
301 glVertex3f(vMin[0], vMax[1], vMax[2])
304 glVertex3f(vMin[0], vMin[1], vMin[2])
305 glVertex3f(vMin[0], vMin[1], vMax[2])
306 glVertex3f(vMax[0], vMin[1], vMin[2])
307 glVertex3f(vMax[0], vMin[1], vMax[2])
308 glVertex3f(vMax[0], vMax[1], vMin[2])
309 glVertex3f(vMax[0], vMax[1], vMax[2])
310 glVertex3f(vMin[0], vMax[1], vMin[2])
311 glVertex3f(vMin[0], vMax[1], vMax[2])
315 def DrawMeshOutline(mesh):
316 glEnable(GL_CULL_FACE)
317 glEnableClientState(GL_VERTEX_ARRAY);
318 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
322 glPolygonMode(GL_BACK, GL_LINE)
323 glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
324 glPolygonMode(GL_BACK, GL_FILL)
327 glDisableClientState(GL_VERTEX_ARRAY)
331 glEnable(GL_CULL_FACE)
332 glEnableClientState(GL_VERTEX_ARRAY);
333 glEnableClientState(GL_NORMAL_ARRAY);
334 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
335 glNormalPointer(GL_FLOAT, 0, mesh.normal)
337 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
338 batchSize = 999 #Warning, batchSize needs to be dividable by 3
339 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
340 extraCount = mesh.vertexCount - extraStartPos
343 for i in xrange(0, int(mesh.vertexCount / batchSize)):
344 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
345 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
348 glNormalPointer(GL_FLOAT, 0, mesh.invNormal)
349 for i in xrange(0, int(mesh.vertexCount / batchSize)):
350 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
351 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
352 extraCount = mesh.vertexCount - extraStartPos
353 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
356 glDisableClientState(GL_VERTEX_ARRAY)
357 glDisableClientState(GL_NORMAL_ARRAY);
360 def DrawMeshSteep(mesh, angle):
361 cosAngle = math.sin(angle / 180.0 * math.pi)
362 glDisable(GL_LIGHTING)
363 glDepthFunc(GL_EQUAL)
364 for i in xrange(0, int(mesh.vertexCount), 3):
365 if mesh.normal[i][2] < -0.999999:
366 if mesh.vertexes[i + 0][2] > 0.01:
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 + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
371 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
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 + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
378 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
380 elif mesh.normal[i][2] > 0.999999:
381 if mesh.vertexes[i + 0][2] > 0.01:
383 glBegin(GL_TRIANGLES)
384 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
385 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
386 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
388 elif mesh.normal[i][2] > cosAngle:
389 glColor3f(mesh.normal[i][2], 0, 0)
390 glBegin(GL_TRIANGLES)
391 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
392 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
393 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
398 def DrawGCodeLayer(layer):
399 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
400 filamentArea = math.pi * filamentRadius * filamentRadius
401 lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
404 fillColorCycle = [[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]
405 moveColor = [0, 0, 1]
406 retractColor = [1, 0, 0.5]
407 supportColor = [0, 1, 1]
408 extrudeColor = [1, 0, 0]
409 innerWallColor = [0, 1, 0]
410 skirtColor = [0, 0.5, 0.5]
411 prevPathWasRetract = False
413 glDisable(GL_CULL_FACE)
415 if path.type == 'move':
416 if prevPathWasRetract:
421 if path.type == 'extrude':
422 if path.pathType == 'FILL':
423 c = fillColorCycle[fillCycle]
424 fillCycle = (fillCycle + 1) % len(fillColorCycle)
425 elif path.pathType == 'WALL-INNER':
428 elif path.pathType == 'SUPPORT':
430 elif path.pathType == 'SKIRT':
434 if path.type == 'retract':
436 if path.type == 'extrude':
439 for i in xrange(0, len(path.list) - 1):
441 v1 = path.list[i + 1]
443 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
444 dist = (v0 - v1).vsize()
445 if dist > 0 and path.layerThickness > 0:
446 extrusionMMperDist = (v1.e - v0.e) / dist
447 lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
449 drawLength += (v0 - v1).vsize()
450 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
453 vv2 = v0 + normal * lineWidth
454 vv3 = v1 + normal * lineWidth
455 vv0 = v0 - normal * lineWidth
456 vv1 = v1 - normal * lineWidth
460 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
461 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
462 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
463 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
465 if prevNormal is not None:
466 n = (normal + prevNormal)
468 vv4 = v0 + n * lineWidth
469 vv5 = v0 - n * lineWidth
472 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
473 glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
474 glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
475 glVertex3f(v0.x, v0.y, v0.z - zOffset)
477 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
478 glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
479 glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
480 glVertex3f(v0.x, v0.y, v0.z - zOffset)
487 glBegin(GL_LINE_STRIP)
490 glVertex3f(v.x, v.y, v.z)
492 if not path.type == 'move':
493 prevPathWasRetract = False
494 if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):
495 prevPathWasRetract = True
496 glEnable(GL_CULL_FACE)