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 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord('X'))
222 glTranslate(0, 23, 0)
223 ResetMatrixRotationAndScale()
225 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord('Y'))
232 glTranslate(0, 0, 23)
233 ResetMatrixRotationAndScale()
235 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord('Z'))
239 glEnable(GL_DEPTH_TEST)
242 def ResetMatrixRotationAndScale():
243 matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
247 scale2D = matrix[0][0]
258 if matrix[3][2] != 0.0:
259 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
260 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
263 matrix[0][0] = scale2D
264 matrix[1][1] = scale2D
265 matrix[2][2] = scale2D
269 glLoadMatrixf(matrix)
273 def DrawBox(vMin, vMax):
274 glBegin(GL_LINE_LOOP)
275 glVertex3f(vMin[0], vMin[1], vMin[2])
276 glVertex3f(vMax[0], vMin[1], vMin[2])
277 glVertex3f(vMax[0], vMax[1], vMin[2])
278 glVertex3f(vMin[0], vMax[1], vMin[2])
281 glBegin(GL_LINE_LOOP)
282 glVertex3f(vMin[0], vMin[1], vMax[2])
283 glVertex3f(vMax[0], vMin[1], vMax[2])
284 glVertex3f(vMax[0], vMax[1], vMax[2])
285 glVertex3f(vMin[0], vMax[1], vMax[2])
288 glVertex3f(vMin[0], vMin[1], vMin[2])
289 glVertex3f(vMin[0], vMin[1], vMax[2])
290 glVertex3f(vMax[0], vMin[1], vMin[2])
291 glVertex3f(vMax[0], vMin[1], vMax[2])
292 glVertex3f(vMax[0], vMax[1], vMin[2])
293 glVertex3f(vMax[0], vMax[1], vMax[2])
294 glVertex3f(vMin[0], vMax[1], vMin[2])
295 glVertex3f(vMin[0], vMax[1], vMax[2])
299 def DrawMeshOutline(mesh):
300 glEnable(GL_CULL_FACE)
301 glEnableClientState(GL_VERTEX_ARRAY);
302 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
306 glPolygonMode(GL_BACK, GL_LINE)
307 glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
308 glPolygonMode(GL_BACK, GL_FILL)
311 glDisableClientState(GL_VERTEX_ARRAY)
315 glEnable(GL_CULL_FACE)
316 glEnableClientState(GL_VERTEX_ARRAY);
317 glEnableClientState(GL_NORMAL_ARRAY);
318 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
319 glNormalPointer(GL_FLOAT, 0, mesh.normal)
321 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
322 batchSize = 999 #Warning, batchSize needs to be dividable by 3
323 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
324 extraCount = mesh.vertexCount - extraStartPos
327 for i in xrange(0, int(mesh.vertexCount / batchSize)):
328 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
329 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
332 glNormalPointer(GL_FLOAT, 0, mesh.invNormal)
333 for i in xrange(0, int(mesh.vertexCount / batchSize)):
334 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
335 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
336 extraCount = mesh.vertexCount - extraStartPos
337 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
340 glDisableClientState(GL_VERTEX_ARRAY)
341 glDisableClientState(GL_NORMAL_ARRAY);
344 def DrawMeshSteep(mesh, angle):
345 cosAngle = math.sin(angle / 180.0 * math.pi)
346 glDisable(GL_LIGHTING)
347 glDepthFunc(GL_EQUAL)
348 for i in xrange(0, int(mesh.vertexCount), 3):
349 if mesh.normal[i][2] < -0.999999:
350 if mesh.vertexes[i + 0][2] > 0.01:
352 glBegin(GL_TRIANGLES)
353 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
354 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
355 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
357 elif mesh.normal[i][2] < -cosAngle:
358 glColor3f(-mesh.normal[i][2], 0, 0)
359 glBegin(GL_TRIANGLES)
360 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
361 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
362 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
364 elif mesh.normal[i][2] > 0.999999:
365 if mesh.vertexes[i + 0][2] > 0.01:
367 glBegin(GL_TRIANGLES)
368 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
369 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
370 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
372 elif mesh.normal[i][2] > cosAngle:
373 glColor3f(mesh.normal[i][2], 0, 0)
374 glBegin(GL_TRIANGLES)
375 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
376 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
377 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
382 def DrawGCodeLayer(layer):
383 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
384 filamentArea = math.pi * filamentRadius * filamentRadius
385 lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
388 fillColorCycle = [[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]
389 moveColor = [0, 0, 1]
390 retractColor = [1, 0, 0.5]
391 supportColor = [0, 1, 1]
392 extrudeColor = [1, 0, 0]
393 innerWallColor = [0, 1, 0]
394 skirtColor = [0, 0.5, 0.5]
395 prevPathWasRetract = False
397 glDisable(GL_CULL_FACE)
399 if path.type == 'move':
400 if prevPathWasRetract:
405 if path.type == 'extrude':
406 if path.pathType == 'FILL':
407 c = fillColorCycle[fillCycle]
408 fillCycle = (fillCycle + 1) % len(fillColorCycle)
409 elif path.pathType == 'WALL-INNER':
412 elif path.pathType == 'SUPPORT':
414 elif path.pathType == 'SKIRT':
418 if path.type == 'retract':
420 if path.type == 'extrude':
423 for i in xrange(0, len(path.list) - 1):
425 v1 = path.list[i + 1]
427 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
428 dist = (v0 - v1).vsize()
429 if dist > 0 and path.layerThickness > 0:
430 extrusionMMperDist = (v1.e - v0.e) / dist
431 lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
433 drawLength += (v0 - v1).vsize()
434 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
437 vv2 = v0 + normal * lineWidth
438 vv3 = v1 + normal * lineWidth
439 vv0 = v0 - normal * lineWidth
440 vv1 = v1 - normal * lineWidth
444 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
445 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
446 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
447 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
449 if prevNormal is not None:
450 n = (normal + prevNormal)
452 vv4 = v0 + n * lineWidth
453 vv5 = v0 - n * lineWidth
456 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
457 glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
458 glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
459 glVertex3f(v0.x, v0.y, v0.z - zOffset)
461 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
462 glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
463 glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
464 glVertex3f(v0.x, v0.y, v0.z - zOffset)
471 glBegin(GL_LINE_STRIP)
474 glVertex3f(v.x, v.y, v.z)
476 if not path.type == 'move':
477 prevPathWasRetract = False
478 if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):
479 prevPathWasRetract = True
480 glEnable(GL_CULL_FACE)