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 glBitmap(0,0,0,0, -5, -5, None)
217 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord('X'))
223 glTranslate(0, 23, 0)
225 glBitmap(0,0,0,0, -5, -5, None)
226 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord('Y'))
233 glTranslate(0, 0, 23)
235 glBitmap(0,0,0,0, -5, -5, None)
236 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord('Z'))
240 glEnable(GL_DEPTH_TEST)
243 def ResetMatrixRotationAndScale():
244 matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
248 scale2D = matrix[0][0]
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)
264 matrix[0][0] = scale2D
265 matrix[1][1] = scale2D
266 matrix[2][2] = scale2D
270 glLoadMatrixf(matrix)
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])
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])
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])
300 def DrawMeshOutline(mesh):
301 glEnable(GL_CULL_FACE)
302 glEnableClientState(GL_VERTEX_ARRAY);
303 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
307 glPolygonMode(GL_BACK, GL_LINE)
308 glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
309 glPolygonMode(GL_BACK, GL_FILL)
312 glDisableClientState(GL_VERTEX_ARRAY)
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)
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
328 for i in xrange(0, int(mesh.vertexCount / batchSize)):
329 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
330 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
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)
341 glDisableClientState(GL_VERTEX_ARRAY)
342 glDisableClientState(GL_NORMAL_ARRAY);
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:
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])
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])
365 elif 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 + 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])
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])
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
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
398 glDisable(GL_CULL_FACE)
400 if path.type == 'move':
401 if prevPathWasRetract:
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':
413 elif path.pathType == 'SUPPORT':
415 elif path.pathType == 'SKIRT':
419 if path.type == 'retract':
421 if path.type == 'extrude':
424 for i in xrange(0, len(path.list) - 1):
426 v1 = path.list[i + 1]
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
434 drawLength += (v0 - v1).vsize()
435 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
438 vv2 = v0 + normal * lineWidth
439 vv3 = v1 + normal * lineWidth
440 vv0 = v0 - normal * lineWidth
441 vv1 = v1 - normal * lineWidth
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)
450 if prevNormal is not None:
451 n = (normal + prevNormal)
453 vv4 = v0 + n * lineWidth
454 vv5 = v0 - n * lineWidth
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)
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)
472 glBegin(GL_LINE_STRIP)
475 glVertex3f(v.x, v.y, v.z)
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)