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(20, 0, 0)
214 noZ = ResetMatrixRotationAndScale()
215 glDrawStringCenter("X")
221 glTranslate(0, 20, 0)
222 glDrawStringCenter("Y")
229 glTranslate(0, 0, 20)
230 glDrawStringCenter("Z")
234 glEnable(GL_DEPTH_TEST)
236 def glDrawStringCenter(s):
240 width += glutBitmapWidth(GLUT_BITMAP_HELVETICA_18, ord(c))
241 glBitmap(0,0,0,0, -width/2, 0, None)
243 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord(c))
245 def ResetMatrixRotationAndScale():
246 matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
250 scale2D = matrix[0][0]
261 if matrix[3][2] != 0.0:
262 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
263 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
266 matrix[0][0] = scale2D
267 matrix[1][1] = scale2D
268 matrix[2][2] = scale2D
272 glLoadMatrixf(matrix)
276 def DrawBox(vMin, vMax):
277 glBegin(GL_LINE_LOOP)
278 glVertex3f(vMin[0], vMin[1], vMin[2])
279 glVertex3f(vMax[0], vMin[1], vMin[2])
280 glVertex3f(vMax[0], vMax[1], vMin[2])
281 glVertex3f(vMin[0], vMax[1], vMin[2])
284 glBegin(GL_LINE_LOOP)
285 glVertex3f(vMin[0], vMin[1], vMax[2])
286 glVertex3f(vMax[0], vMin[1], vMax[2])
287 glVertex3f(vMax[0], vMax[1], vMax[2])
288 glVertex3f(vMin[0], vMax[1], vMax[2])
291 glVertex3f(vMin[0], vMin[1], vMin[2])
292 glVertex3f(vMin[0], vMin[1], vMax[2])
293 glVertex3f(vMax[0], vMin[1], vMin[2])
294 glVertex3f(vMax[0], vMin[1], vMax[2])
295 glVertex3f(vMax[0], vMax[1], vMin[2])
296 glVertex3f(vMax[0], vMax[1], vMax[2])
297 glVertex3f(vMin[0], vMax[1], vMin[2])
298 glVertex3f(vMin[0], vMax[1], vMax[2])
302 def DrawMeshOutline(mesh):
303 glEnable(GL_CULL_FACE)
304 glEnableClientState(GL_VERTEX_ARRAY);
305 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
309 glPolygonMode(GL_BACK, GL_LINE)
310 glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
311 glPolygonMode(GL_BACK, GL_FILL)
314 glDisableClientState(GL_VERTEX_ARRAY)
318 glEnable(GL_CULL_FACE)
319 glEnableClientState(GL_VERTEX_ARRAY);
320 glEnableClientState(GL_NORMAL_ARRAY);
321 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
322 glNormalPointer(GL_FLOAT, 0, mesh.normal)
324 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
325 batchSize = 999 #Warning, batchSize needs to be dividable by 3
326 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
327 extraCount = mesh.vertexCount - extraStartPos
330 for i in xrange(0, int(mesh.vertexCount / batchSize)):
331 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
332 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
335 glNormalPointer(GL_FLOAT, 0, mesh.invNormal)
336 for i in xrange(0, int(mesh.vertexCount / batchSize)):
337 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
338 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
339 extraCount = mesh.vertexCount - extraStartPos
340 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
343 glDisableClientState(GL_VERTEX_ARRAY)
344 glDisableClientState(GL_NORMAL_ARRAY);
347 def DrawMeshSteep(mesh, angle):
348 cosAngle = math.sin(angle / 180.0 * math.pi)
349 glDisable(GL_LIGHTING)
350 glDepthFunc(GL_EQUAL)
351 for i in xrange(0, int(mesh.vertexCount), 3):
352 if mesh.normal[i][2] < -0.999999:
353 if mesh.vertexes[i + 0][2] > 0.01:
355 glBegin(GL_TRIANGLES)
356 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
357 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
358 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
360 elif mesh.normal[i][2] < -cosAngle:
361 glColor3f(-mesh.normal[i][2], 0, 0)
362 glBegin(GL_TRIANGLES)
363 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
364 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
365 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
367 elif mesh.normal[i][2] > 0.999999:
368 if mesh.vertexes[i + 0][2] > 0.01:
370 glBegin(GL_TRIANGLES)
371 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
372 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
373 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
375 elif mesh.normal[i][2] > cosAngle:
376 glColor3f(mesh.normal[i][2], 0, 0)
377 glBegin(GL_TRIANGLES)
378 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
379 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
380 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
385 def DrawGCodeLayer(layer):
386 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
387 filamentArea = math.pi * filamentRadius * filamentRadius
388 lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
391 fillColorCycle = [[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]
392 moveColor = [0, 0, 1]
393 retractColor = [1, 0, 0.5]
394 supportColor = [0, 1, 1]
395 extrudeColor = [1, 0, 0]
396 innerWallColor = [0, 1, 0]
397 skirtColor = [0, 0.5, 0.5]
398 prevPathWasRetract = False
400 glDisable(GL_CULL_FACE)
402 if path.type == 'move':
403 if prevPathWasRetract:
408 if path.type == 'extrude':
409 if path.pathType == 'FILL':
410 c = fillColorCycle[fillCycle]
411 fillCycle = (fillCycle + 1) % len(fillColorCycle)
412 elif path.pathType == 'WALL-INNER':
415 elif path.pathType == 'SUPPORT':
417 elif path.pathType == 'SKIRT':
421 if path.type == 'retract':
423 if path.type == 'extrude':
426 for i in xrange(0, len(path.list) - 1):
428 v1 = path.list[i + 1]
430 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
431 dist = (v0 - v1).vsize()
432 if dist > 0 and path.layerThickness > 0:
433 extrusionMMperDist = (v1.e - v0.e) / dist
434 lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
436 drawLength += (v0 - v1).vsize()
437 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
440 vv2 = v0 + normal * lineWidth
441 vv3 = v1 + normal * lineWidth
442 vv0 = v0 - normal * lineWidth
443 vv1 = v1 - normal * lineWidth
447 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
448 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
449 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
450 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
452 if prevNormal is not None:
453 n = (normal + prevNormal)
455 vv4 = v0 + n * lineWidth
456 vv5 = v0 - n * lineWidth
459 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
460 glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
461 glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
462 glVertex3f(v0.x, v0.y, v0.z - zOffset)
464 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
465 glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
466 glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
467 glVertex3f(v0.x, v0.y, v0.z - zOffset)
474 glBegin(GL_LINE_STRIP)
477 glVertex3f(v.x, v.y, v.z)
479 if not path.type == 'move':
480 prevPathWasRetract = False
481 if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):
482 prevPathWasRetract = True
483 glEnable(GL_CULL_FACE)