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 is None:
71 platformMesh = meshLoader.loadMesh(getPathForMesh('ultimaker_platform.stl'))
72 platformMesh.setRotateMirror(0, False, False, False, False, False)
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)
253 glEnable(GL_DEPTH_TEST)
256 def ResetMatrixRotationAndScale():
257 matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
261 scale2D = matrix[0][0]
272 if matrix[3][2] != 0.0:
273 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
274 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
277 matrix[0][0] = scale2D
278 matrix[1][1] = scale2D
279 matrix[2][2] = scale2D
283 glLoadMatrixf(matrix)
287 def DrawBox(vMin, vMax):
288 glBegin(GL_LINE_LOOP)
289 glVertex3f(vMin[0], vMin[1], vMin[2])
290 glVertex3f(vMax[0], vMin[1], vMin[2])
291 glVertex3f(vMax[0], vMax[1], vMin[2])
292 glVertex3f(vMin[0], vMax[1], vMin[2])
295 glBegin(GL_LINE_LOOP)
296 glVertex3f(vMin[0], vMin[1], vMax[2])
297 glVertex3f(vMax[0], vMin[1], vMax[2])
298 glVertex3f(vMax[0], vMax[1], vMax[2])
299 glVertex3f(vMin[0], vMax[1], vMax[2])
302 glVertex3f(vMin[0], vMin[1], vMin[2])
303 glVertex3f(vMin[0], vMin[1], vMax[2])
304 glVertex3f(vMax[0], vMin[1], vMin[2])
305 glVertex3f(vMax[0], vMin[1], vMax[2])
306 glVertex3f(vMax[0], vMax[1], vMin[2])
307 glVertex3f(vMax[0], vMax[1], vMax[2])
308 glVertex3f(vMin[0], vMax[1], vMin[2])
309 glVertex3f(vMin[0], vMax[1], vMax[2])
313 def DrawMeshOutline(mesh):
314 glEnable(GL_CULL_FACE)
315 glEnableClientState(GL_VERTEX_ARRAY);
316 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
320 glPolygonMode(GL_BACK, GL_LINE)
321 glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
322 glPolygonMode(GL_BACK, GL_FILL)
325 glDisableClientState(GL_VERTEX_ARRAY)
329 glEnable(GL_CULL_FACE)
330 glEnableClientState(GL_VERTEX_ARRAY);
331 glEnableClientState(GL_NORMAL_ARRAY);
332 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
333 glNormalPointer(GL_FLOAT, 0, mesh.normal)
335 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
336 batchSize = 999 #Warning, batchSize needs to be dividable by 3
337 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
338 extraCount = mesh.vertexCount - extraStartPos
341 for i in xrange(0, int(mesh.vertexCount / batchSize)):
342 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
343 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
346 glNormalPointer(GL_FLOAT, 0, mesh.invNormal)
347 for i in xrange(0, int(mesh.vertexCount / batchSize)):
348 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
349 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
350 extraCount = mesh.vertexCount - extraStartPos
351 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
354 glDisableClientState(GL_VERTEX_ARRAY)
355 glDisableClientState(GL_NORMAL_ARRAY);
358 def DrawMeshSteep(mesh, angle):
359 cosAngle = math.sin(angle / 180.0 * math.pi)
360 glDisable(GL_LIGHTING)
361 glDepthFunc(GL_EQUAL)
362 for i in xrange(0, int(mesh.vertexCount), 3):
363 if mesh.normal[i][2] < -0.999999:
364 if mesh.vertexes[i + 0][2] > 0.01:
366 glBegin(GL_TRIANGLES)
367 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
368 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
369 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
371 elif mesh.normal[i][2] < -cosAngle:
372 glColor3f(-mesh.normal[i][2], 0, 0)
373 glBegin(GL_TRIANGLES)
374 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
375 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
376 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
378 elif mesh.normal[i][2] > 0.999999:
379 if mesh.vertexes[i + 0][2] > 0.01:
381 glBegin(GL_TRIANGLES)
382 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
383 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
384 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
386 elif mesh.normal[i][2] > cosAngle:
387 glColor3f(mesh.normal[i][2], 0, 0)
388 glBegin(GL_TRIANGLES)
389 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
390 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
391 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
396 def DrawGCodeLayer(layer):
397 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
398 filamentArea = math.pi * filamentRadius * filamentRadius
399 lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
402 fillColorCycle = [[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]
403 moveColor = [0, 0, 1]
404 retractColor = [1, 0, 0.5]
405 supportColor = [0, 1, 1]
406 extrudeColor = [1, 0, 0]
407 innerWallColor = [0, 1, 0]
408 skirtColor = [0, 0.5, 0.5]
409 prevPathWasRetract = False
411 glDisable(GL_CULL_FACE)
413 if path.type == 'move':
414 if prevPathWasRetract:
419 if path.type == 'extrude':
420 if path.pathType == 'FILL':
421 c = fillColorCycle[fillCycle]
422 fillCycle = (fillCycle + 1) % len(fillColorCycle)
423 elif path.pathType == 'WALL-INNER':
426 elif path.pathType == 'SUPPORT':
428 elif path.pathType == 'SKIRT':
432 if path.type == 'retract':
434 if path.type == 'extrude':
437 for i in xrange(0, len(path.list) - 1):
439 v1 = path.list[i + 1]
441 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
442 dist = (v0 - v1).vsize()
443 if dist > 0 and path.layerThickness > 0:
444 extrusionMMperDist = (v1.e - v0.e) / dist
445 lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
447 drawLength += (v0 - v1).vsize()
448 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
451 vv2 = v0 + normal * lineWidth
452 vv3 = v1 + normal * lineWidth
453 vv0 = v0 - normal * lineWidth
454 vv1 = v1 - normal * lineWidth
458 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
459 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
460 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
461 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
463 if prevNormal is not None:
464 n = (normal + prevNormal)
466 vv4 = v0 + n * lineWidth
467 vv5 = v0 - n * lineWidth
470 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
471 glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
472 glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
473 glVertex3f(v0.x, v0.y, v0.z - zOffset)
475 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
476 glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
477 glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
478 glVertex3f(v0.x, v0.y, v0.z - zOffset)
485 glBegin(GL_LINE_STRIP)
488 glVertex3f(v.x, v.y, v.z)
490 if not path.type == 'move':
491 prevPathWasRetract = False
492 if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):
493 prevPathWasRetract = True
494 glEnable(GL_CULL_FACE)