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 *
22 print "Failed to find PyOpenGL: http://pyopengl.sourceforge.net/"
25 def InitGL(window, view3D, zoom):
26 # set viewing projection
27 glMatrixMode(GL_MODELVIEW)
29 size = window.GetSize()
30 glViewport(0, 0, size.GetWidth(), size.GetHeight())
32 glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
33 glLightfv(GL_LIGHT1, GL_POSITION, [1.0, 1.0, 1.0, 0.0])
35 glEnable(GL_RESCALE_NORMAL)
38 glEnable(GL_DEPTH_TEST)
39 glEnable(GL_CULL_FACE)
42 glClearColor(1.0, 1.0, 1.0, 1.0)
46 glMatrixMode(GL_PROJECTION)
48 aspect = float(size.GetWidth()) / float(size.GetHeight())
50 gluPerspective(45.0, aspect, 1.0, 1000.0)
52 glOrtho(-aspect * (zoom), aspect * (zoom), -1.0 * (zoom), 1.0 * (zoom), -1000.0, 1000.0)
54 glMatrixMode(GL_MODELVIEW)
56 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
60 def DrawMachine(machineSize):
61 if profile.getPreference('machine_type') == 'ultimaker':
64 glTranslate(100, 200, -5)
65 glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8])
66 glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5])
68 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR)
71 if platformMesh is None:
73 platformMesh = meshLoader.loadMesh(getPathForMesh('ultimaker_platform.stl'))
78 DrawMesh(platformMesh)
81 glDisable(GL_LIGHTING)
83 glColor3f(0.7, 0.7, 0.7)
86 for i in xrange(0, int(machineSize.x), 10):
88 glVertex3f(i, machineSize.y, 0)
89 for i in xrange(0, int(machineSize.y), 10):
91 glVertex3f(machineSize.x, i, 0)
94 glEnable(GL_LINE_SMOOTH)
96 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
97 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
99 glColor3f(0.0, 0.0, 0.0)
101 glBegin(GL_LINE_LOOP)
103 glVertex3f(machineSize.x, 0, 0)
104 glVertex3f(machineSize.x, machineSize.y, 0)
105 glVertex3f(0, machineSize.y, 0)
109 glBegin(GL_LINE_LOOP)
110 glVertex3f(0, 0, machineSize.z)
111 glVertex3f(machineSize.x, 0, machineSize.z)
112 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
113 glVertex3f(0, machineSize.y, machineSize.z)
117 glVertex3f(0, 0, machineSize.z)
118 glVertex3f(machineSize.x, 0, 0)
119 glVertex3f(machineSize.x, 0, machineSize.z)
120 glVertex3f(machineSize.x, machineSize.y, 0)
121 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
122 glVertex3f(0, machineSize.y, 0)
123 glVertex3f(0, machineSize.y, machineSize.z)
126 glDisable(GL_CULL_FACE)
128 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
132 for x in xrange(-int(sx/20)-1, int(sx / 20) + 1):
133 for y in xrange(-int(sx/20)-1, int(sy / 20) + 1):
138 x1 = max(min(x1, sx), 0)
139 y1 = max(min(y1, sy), 0)
140 x2 = max(min(x2, sx), 0)
141 y2 = max(min(y2, sy), 0)
142 if (x & 1) == (y & 1):
143 glColor4ub(5, 171, 231, 127)
145 glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128)
147 glVertex3f(x1, y1, -0.01)
148 glVertex3f(x2, y1, -0.01)
149 glVertex3f(x2, y2, -0.01)
150 glVertex3f(x1, y2, -0.01)
153 glEnable(GL_CULL_FACE)
155 glColor4ub(5, 171, 231, 64)
157 glVertex3f(0, 0, machineSize.z)
158 glVertex3f(0, machineSize.y, machineSize.z)
159 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
160 glVertex3f(machineSize.x, 0, machineSize.z)
163 glColor4ub(5, 171, 231, 96)
166 glVertex3f(0, 0, machineSize.z)
167 glVertex3f(machineSize.x, 0, machineSize.z)
168 glVertex3f(machineSize.x, 0, 0)
170 glVertex3f(0, machineSize.y, machineSize.z)
171 glVertex3f(0, machineSize.y, 0)
172 glVertex3f(machineSize.x, machineSize.y, 0)
173 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
176 glColor4ub(5, 171, 231, 128)
178 glVertex3f(0, 0, machineSize.z)
180 glVertex3f(0, machineSize.y, 0)
181 glVertex3f(0, machineSize.y, machineSize.z)
183 glVertex3f(machineSize.x, 0, 0)
184 glVertex3f(machineSize.x, 0, machineSize.z)
185 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
186 glVertex3f(machineSize.x, machineSize.y, 0)
210 glDisable(GL_DEPTH_TEST)
214 glTranslate(20, 0, 0)
215 noZ = ResetMatrixRotationAndScale()
216 glDrawStringCenter("X")
222 glTranslate(0, 20, 0)
223 glDrawStringCenter("Y")
230 glTranslate(0, 0, 20)
231 glDrawStringCenter("Z")
235 glEnable(GL_DEPTH_TEST)
237 def glDrawStringCenter(s):
241 width += glutBitmapWidth(GLUT_BITMAP_HELVETICA_18, ord(c))
242 glBitmap(0,0,0,0, -width/2, 0, None)
244 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord(c))
246 def ResetMatrixRotationAndScale():
247 matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
251 scale2D = matrix[0][0]
262 if matrix[3][2] != 0.0:
263 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
264 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
267 matrix[0][0] = scale2D
268 matrix[1][1] = scale2D
269 matrix[2][2] = scale2D
273 glLoadMatrixf(matrix)
277 def DrawBox(vMin, vMax):
278 glBegin(GL_LINE_LOOP)
279 glVertex3f(vMin[0], vMin[1], vMin[2])
280 glVertex3f(vMax[0], vMin[1], vMin[2])
281 glVertex3f(vMax[0], vMax[1], vMin[2])
282 glVertex3f(vMin[0], vMax[1], vMin[2])
285 glBegin(GL_LINE_LOOP)
286 glVertex3f(vMin[0], vMin[1], vMax[2])
287 glVertex3f(vMax[0], vMin[1], vMax[2])
288 glVertex3f(vMax[0], vMax[1], vMax[2])
289 glVertex3f(vMin[0], vMax[1], vMax[2])
292 glVertex3f(vMin[0], vMin[1], vMin[2])
293 glVertex3f(vMin[0], vMin[1], vMax[2])
294 glVertex3f(vMax[0], vMin[1], vMin[2])
295 glVertex3f(vMax[0], vMin[1], vMax[2])
296 glVertex3f(vMax[0], vMax[1], vMin[2])
297 glVertex3f(vMax[0], vMax[1], vMax[2])
298 glVertex3f(vMin[0], vMax[1], vMin[2])
299 glVertex3f(vMin[0], vMax[1], vMax[2])
303 def DrawMeshOutline(mesh):
304 glEnable(GL_CULL_FACE)
305 glEnableClientState(GL_VERTEX_ARRAY);
306 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
310 glPolygonMode(GL_BACK, GL_LINE)
311 glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
312 glPolygonMode(GL_BACK, GL_FILL)
315 glDisableClientState(GL_VERTEX_ARRAY)
319 glEnable(GL_CULL_FACE)
320 glEnableClientState(GL_VERTEX_ARRAY);
321 glEnableClientState(GL_NORMAL_ARRAY);
322 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
323 glNormalPointer(GL_FLOAT, 0, mesh.normal)
325 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
326 batchSize = 999 #Warning, batchSize needs to be dividable by 3
327 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
328 extraCount = mesh.vertexCount - extraStartPos
331 for i in xrange(0, int(mesh.vertexCount / batchSize)):
332 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
333 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
336 glNormalPointer(GL_FLOAT, 0, mesh.invNormal)
337 for i in xrange(0, int(mesh.vertexCount / batchSize)):
338 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
339 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
340 extraCount = mesh.vertexCount - extraStartPos
341 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
344 glDisableClientState(GL_VERTEX_ARRAY)
345 glDisableClientState(GL_NORMAL_ARRAY);
348 def DrawMeshSteep(mesh, angle):
349 cosAngle = math.sin(angle / 180.0 * math.pi)
350 glDisable(GL_LIGHTING)
351 glDepthFunc(GL_EQUAL)
352 for i in xrange(0, int(mesh.vertexCount), 3):
353 if mesh.normal[i][2] < -0.999999:
354 if mesh.vertexes[i + 0][2] > 0.01:
356 glBegin(GL_TRIANGLES)
357 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
358 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
359 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
361 elif mesh.normal[i][2] < -cosAngle:
362 glColor3f(-mesh.normal[i][2], 0, 0)
363 glBegin(GL_TRIANGLES)
364 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
365 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
366 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
368 elif mesh.normal[i][2] > 0.999999:
369 if mesh.vertexes[i + 0][2] > 0.01:
371 glBegin(GL_TRIANGLES)
372 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
373 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
374 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
376 elif mesh.normal[i][2] > cosAngle:
377 glColor3f(mesh.normal[i][2], 0, 0)
378 glBegin(GL_TRIANGLES)
379 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
380 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
381 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
386 def DrawGCodeLayer(layer):
387 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
388 filamentArea = math.pi * filamentRadius * filamentRadius
389 lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
392 fillColorCycle = [[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]
393 moveColor = [0, 0, 1]
394 retractColor = [1, 0, 0.5]
395 supportColor = [0, 1, 1]
396 extrudeColor = [1, 0, 0]
397 innerWallColor = [0, 1, 0]
398 skirtColor = [0, 0.5, 0.5]
399 prevPathWasRetract = False
401 glDisable(GL_CULL_FACE)
403 if path.type == 'move':
404 if prevPathWasRetract:
409 if path.type == 'extrude':
410 if path.pathType == 'FILL':
411 c = fillColorCycle[fillCycle]
412 fillCycle = (fillCycle + 1) % len(fillColorCycle)
413 elif path.pathType == 'WALL-INNER':
416 elif path.pathType == 'SUPPORT':
418 elif path.pathType == 'SKIRT':
422 if path.type == 'retract':
424 if path.type == 'extrude':
427 for i in xrange(0, len(path.list) - 1):
429 v1 = path.list[i + 1]
431 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
432 dist = (v0 - v1).vsize()
433 if dist > 0 and path.layerThickness > 0:
434 extrusionMMperDist = (v1.e - v0.e) / dist
435 lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
437 drawLength += (v0 - v1).vsize()
438 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
441 vv2 = v0 + normal * lineWidth
442 vv3 = v1 + normal * lineWidth
443 vv0 = v0 - normal * lineWidth
444 vv1 = v1 - normal * lineWidth
448 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
449 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
450 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
451 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
453 if prevNormal is not None:
454 n = (normal + prevNormal)
456 vv4 = v0 + n * lineWidth
457 vv5 = v0 - n * lineWidth
460 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
461 glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
462 glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
463 glVertex3f(v0.x, v0.y, v0.z - zOffset)
465 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
466 glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
467 glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
468 glVertex3f(v0.x, v0.y, v0.z - zOffset)
475 glBegin(GL_LINE_STRIP)
478 glVertex3f(v.x, v.y, v.z)
480 if not path.type == 'move':
481 prevPathWasRetract = False
482 if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):
483 prevPathWasRetract = True
484 glEnable(GL_CULL_FACE)