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.GLU import *
16 from OpenGL.GL import *
20 print "Failed to find PyOpenGL: http://pyopengl.sourceforge.net/"
23 def InitGL(window, view3D, zoom):
24 # set viewing projection
25 glMatrixMode(GL_MODELVIEW)
27 size = window.GetSize()
28 glViewport(0, 0, size.GetWidth(), size.GetHeight())
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])
33 glEnable(GL_RESCALE_NORMAL)
36 glEnable(GL_DEPTH_TEST)
37 glEnable(GL_CULL_FACE)
40 glClearColor(1.0, 1.0, 1.0, 1.0)
44 glMatrixMode(GL_PROJECTION)
46 aspect = float(size.GetWidth()) / float(size.GetHeight())
48 gluPerspective(45.0, aspect, 1.0, 1000.0)
50 glOrtho(-aspect * (zoom), aspect * (zoom), -1.0 * (zoom), 1.0 * (zoom), -1000.0, 1000.0)
52 glMatrixMode(GL_MODELVIEW)
54 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
58 def DrawMachine(machineSize):
59 if profile.getPreference('machine_type') == 'ultimaker':
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])
66 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR)
69 if platformMesh == None:
70 platformMesh = meshLoader.loadMesh(getPathForMesh('ultimaker_platform.stl'))
71 platformMesh.setRotateMirror(0, False, False, False, False, False)
73 DrawMesh(platformMesh)
76 glDisable(GL_LIGHTING)
78 glColor3f(0.7, 0.7, 0.7)
81 for i in xrange(0, int(machineSize.x), 10):
83 glVertex3f(i, machineSize.y, 0)
84 for i in xrange(0, int(machineSize.y), 10):
86 glVertex3f(machineSize.x, i, 0)
89 glEnable(GL_LINE_SMOOTH)
91 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
92 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
94 glColor3f(0.0, 0.0, 0.0)
98 glVertex3f(machineSize.x, 0, 0)
99 glVertex3f(machineSize.x, machineSize.y, 0)
100 glVertex3f(0, machineSize.y, 0)
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)
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)
121 glDisable(GL_CULL_FACE)
123 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
124 glColor4ub(5, 171, 231, 127)
126 for x in xrange(0, int(machineSize.x), 20):
127 for y in xrange(0, int(machineSize.y), 20):
128 glVertex3f(x, y, -0.01)
129 glVertex3f(min(x + 10, machineSize.x), y, -0.01)
130 glVertex3f(min(x + 10, machineSize.x), min(y + 10, machineSize.y), -0.01)
131 glVertex3f(x, min(y + 10, machineSize.y), -0.01)
132 for x in xrange(10, int(machineSize.x), 20):
133 for y in xrange(10, int(machineSize.y), 20):
134 glVertex3f(x, y, -0.01)
135 glVertex3f(min(x + 10, machineSize.x), y, -0.01)
136 glVertex3f(min(x + 10, machineSize.x), min(y + 10, machineSize.y), -0.01)
137 glVertex3f(x, min(y + 10, machineSize.y), -0.01)
139 glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128)
141 for x in xrange(10, int(machineSize.x), 20):
142 for y in xrange(0, int(machineSize.y), 20):
143 glVertex3f(x, y, -0.01)
144 glVertex3f(min(x + 10, machineSize.x), y, -0.01)
145 glVertex3f(min(x + 10, machineSize.x), min(y + 10, machineSize.y), -0.01)
146 glVertex3f(x, min(y + 10, machineSize.y), -0.01)
147 for x in xrange(0, int(machineSize.x), 20):
148 for y in xrange(10, int(machineSize.y), 20):
149 glVertex3f(x, y, -0.01)
150 glVertex3f(min(x + 10, machineSize.x), y, -0.01)
151 glVertex3f(min(x + 10, machineSize.x), min(y + 10, machineSize.y), -0.01)
152 glVertex3f(x, min(y + 10, machineSize.y), -0.01)
154 glEnable(GL_CULL_FACE)
156 glColor4ub(5, 171, 231, 64)
158 glVertex3f(0, 0, machineSize.z)
159 glVertex3f(0, machineSize.y, machineSize.z)
160 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
161 glVertex3f(machineSize.x, 0, machineSize.z)
164 glColor4ub(5, 171, 231, 96)
167 glVertex3f(0, 0, machineSize.z)
168 glVertex3f(machineSize.x, 0, machineSize.z)
169 glVertex3f(machineSize.x, 0, 0)
171 glVertex3f(0, machineSize.y, machineSize.z)
172 glVertex3f(0, machineSize.y, 0)
173 glVertex3f(machineSize.x, machineSize.y, 0)
174 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
177 glColor4ub(5, 171, 231, 128)
179 glVertex3f(0, 0, machineSize.z)
181 glVertex3f(0, machineSize.y, 0)
182 glVertex3f(0, machineSize.y, machineSize.z)
184 glVertex3f(machineSize.x, 0, 0)
185 glVertex3f(machineSize.x, 0, machineSize.z)
186 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
187 glVertex3f(machineSize.x, machineSize.y, 0)
211 glDisable(GL_DEPTH_TEST)
215 glTranslate(23, 0, 0)
216 noZ = ResetMatrixRotationAndScale()
218 glVertex3f(-0.8, 1, 0)
219 glVertex3f(0.8, -1, 0)
220 glVertex3f(0.8, 1, 0)
221 glVertex3f(-0.8, -1, 0)
228 glTranslate(0, 23, 0)
229 ResetMatrixRotationAndScale()
231 glVertex3f(-0.8, 1, 0)
232 glVertex3f(0.0, 0, 0)
233 glVertex3f(0.8, 1, 0)
234 glVertex3f(-0.8, -1, 0)
242 glTranslate(0, 0, 23)
243 ResetMatrixRotationAndScale()
245 glVertex3f(-0.8, 1, 0)
246 glVertex3f(0.8, 1, 0)
247 glVertex3f(0.8, 1, 0)
248 glVertex3f(-0.8, -1, 0)
249 glVertex3f(-0.8, -1, 0)
250 glVertex3f(0.8, -1, 0)
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 != 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)