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:
70 platformMesh = meshLoader.loadMesh(getPathForMesh('ultimaker_platform.stl'))
71 platformMesh.setRotateMirror(0, False, False, False, False, False)
73 DrawMesh(platformMesh)
76 glDisable(GL_LIGHTING)
78 glColor3f(0.7, 0.7, 0.7)
81 for i in xrange(0, int(machineSize.x), 10):
83 glVertex3f(i, machineSize.y, 0)
84 for i in xrange(0, int(machineSize.y), 10):
86 glVertex3f(machineSize.x, i, 0)
89 glEnable(GL_LINE_SMOOTH)
91 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
92 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
94 glColor3f(0.0, 0.0, 0.0)
98 glVertex3f(machineSize.x, 0, 0)
99 glVertex3f(machineSize.x, machineSize.y, 0)
100 glVertex3f(0, machineSize.y, 0)
104 glBegin(GL_LINE_LOOP)
105 glVertex3f(0, 0, machineSize.z)
106 glVertex3f(machineSize.x, 0, machineSize.z)
107 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
108 glVertex3f(0, machineSize.y, machineSize.z)
112 glVertex3f(0, 0, machineSize.z)
113 glVertex3f(machineSize.x, 0, 0)
114 glVertex3f(machineSize.x, 0, machineSize.z)
115 glVertex3f(machineSize.x, machineSize.y, 0)
116 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
117 glVertex3f(0, machineSize.y, 0)
118 glVertex3f(0, machineSize.y, machineSize.z)
121 glDisable(GL_CULL_FACE)
123 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
127 for x in xrange(-int(sx/20)-1, int(sx / 20) + 1):
128 for y in xrange(-int(sx/20)-1, int(sy / 20) + 1):
133 x1 = max(min(x1, sx), 0)
134 y1 = max(min(y1, sy), 0)
135 x2 = max(min(x2, sx), 0)
136 y2 = max(min(y2, sy), 0)
137 if (x & 1) == (y & 1):
138 glColor4ub(5, 171, 231, 127)
140 glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128)
142 glVertex3f(x1, y1, -0.01)
143 glVertex3f(x2, y1, -0.01)
144 glVertex3f(x2, y2, -0.01)
145 glVertex3f(x1, y2, -0.01)
148 glEnable(GL_CULL_FACE)
150 glColor4ub(5, 171, 231, 64)
152 glVertex3f(0, 0, machineSize.z)
153 glVertex3f(0, machineSize.y, machineSize.z)
154 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
155 glVertex3f(machineSize.x, 0, machineSize.z)
158 glColor4ub(5, 171, 231, 96)
161 glVertex3f(0, 0, machineSize.z)
162 glVertex3f(machineSize.x, 0, machineSize.z)
163 glVertex3f(machineSize.x, 0, 0)
165 glVertex3f(0, machineSize.y, machineSize.z)
166 glVertex3f(0, machineSize.y, 0)
167 glVertex3f(machineSize.x, machineSize.y, 0)
168 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
171 glColor4ub(5, 171, 231, 128)
173 glVertex3f(0, 0, machineSize.z)
175 glVertex3f(0, machineSize.y, 0)
176 glVertex3f(0, machineSize.y, machineSize.z)
178 glVertex3f(machineSize.x, 0, 0)
179 glVertex3f(machineSize.x, 0, machineSize.z)
180 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
181 glVertex3f(machineSize.x, machineSize.y, 0)
205 glDisable(GL_DEPTH_TEST)
209 glTranslate(23, 0, 0)
210 noZ = ResetMatrixRotationAndScale()
212 glVertex3f(-0.8, 1, 0)
213 glVertex3f(0.8, -1, 0)
214 glVertex3f(0.8, 1, 0)
215 glVertex3f(-0.8, -1, 0)
222 glTranslate(0, 23, 0)
223 ResetMatrixRotationAndScale()
225 glVertex3f(-0.8, 1, 0)
226 glVertex3f(0.0, 0, 0)
227 glVertex3f(0.8, 1, 0)
228 glVertex3f(-0.8, -1, 0)
236 glTranslate(0, 0, 23)
237 ResetMatrixRotationAndScale()
239 glVertex3f(-0.8, 1, 0)
240 glVertex3f(0.8, 1, 0)
241 glVertex3f(0.8, 1, 0)
242 glVertex3f(-0.8, -1, 0)
243 glVertex3f(-0.8, -1, 0)
244 glVertex3f(0.8, -1, 0)
249 glEnable(GL_DEPTH_TEST)
252 def ResetMatrixRotationAndScale():
253 matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
257 scale2D = matrix[0][0]
268 if matrix[3][2] != 0.0:
269 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
270 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
273 matrix[0][0] = scale2D
274 matrix[1][1] = scale2D
275 matrix[2][2] = scale2D
279 glLoadMatrixf(matrix)
283 def DrawBox(vMin, vMax):
284 glBegin(GL_LINE_LOOP)
285 glVertex3f(vMin[0], vMin[1], vMin[2])
286 glVertex3f(vMax[0], vMin[1], vMin[2])
287 glVertex3f(vMax[0], vMax[1], vMin[2])
288 glVertex3f(vMin[0], vMax[1], vMin[2])
291 glBegin(GL_LINE_LOOP)
292 glVertex3f(vMin[0], vMin[1], vMax[2])
293 glVertex3f(vMax[0], vMin[1], vMax[2])
294 glVertex3f(vMax[0], vMax[1], vMax[2])
295 glVertex3f(vMin[0], vMax[1], vMax[2])
298 glVertex3f(vMin[0], vMin[1], vMin[2])
299 glVertex3f(vMin[0], vMin[1], vMax[2])
300 glVertex3f(vMax[0], vMin[1], vMin[2])
301 glVertex3f(vMax[0], vMin[1], vMax[2])
302 glVertex3f(vMax[0], vMax[1], vMin[2])
303 glVertex3f(vMax[0], vMax[1], vMax[2])
304 glVertex3f(vMin[0], vMax[1], vMin[2])
305 glVertex3f(vMin[0], vMax[1], vMax[2])
309 def DrawMeshOutline(mesh):
310 glEnable(GL_CULL_FACE)
311 glEnableClientState(GL_VERTEX_ARRAY);
312 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
316 glPolygonMode(GL_BACK, GL_LINE)
317 glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
318 glPolygonMode(GL_BACK, GL_FILL)
321 glDisableClientState(GL_VERTEX_ARRAY)
325 glEnable(GL_CULL_FACE)
326 glEnableClientState(GL_VERTEX_ARRAY);
327 glEnableClientState(GL_NORMAL_ARRAY);
328 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
329 glNormalPointer(GL_FLOAT, 0, mesh.normal)
331 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
332 batchSize = 999 #Warning, batchSize needs to be dividable by 3
333 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
334 extraCount = mesh.vertexCount - extraStartPos
337 for i in xrange(0, int(mesh.vertexCount / batchSize)):
338 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
339 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
342 glNormalPointer(GL_FLOAT, 0, mesh.invNormal)
343 for i in xrange(0, int(mesh.vertexCount / batchSize)):
344 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
345 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
346 extraCount = mesh.vertexCount - extraStartPos
347 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
350 glDisableClientState(GL_VERTEX_ARRAY)
351 glDisableClientState(GL_NORMAL_ARRAY);
354 def DrawMeshSteep(mesh, angle):
355 cosAngle = math.sin(angle / 180.0 * math.pi)
356 glDisable(GL_LIGHTING)
357 glDepthFunc(GL_EQUAL)
358 for i in xrange(0, int(mesh.vertexCount), 3):
359 if mesh.normal[i][2] < -0.999999:
360 if mesh.vertexes[i + 0][2] > 0.01:
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] < -cosAngle:
368 glColor3f(-mesh.normal[i][2], 0, 0)
369 glBegin(GL_TRIANGLES)
370 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
371 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
372 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
374 elif mesh.normal[i][2] > 0.999999:
375 if mesh.vertexes[i + 0][2] > 0.01:
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])
382 elif mesh.normal[i][2] > cosAngle:
383 glColor3f(mesh.normal[i][2], 0, 0)
384 glBegin(GL_TRIANGLES)
385 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
386 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
387 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
392 def DrawGCodeLayer(layer):
393 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
394 filamentArea = math.pi * filamentRadius * filamentRadius
395 lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
398 fillColorCycle = [[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]
399 moveColor = [0, 0, 1]
400 retractColor = [1, 0, 0.5]
401 supportColor = [0, 1, 1]
402 extrudeColor = [1, 0, 0]
403 innerWallColor = [0, 1, 0]
404 skirtColor = [0, 0.5, 0.5]
405 prevPathWasRetract = False
407 glDisable(GL_CULL_FACE)
409 if path.type == 'move':
410 if prevPathWasRetract:
415 if path.type == 'extrude':
416 if path.pathType == 'FILL':
417 c = fillColorCycle[fillCycle]
418 fillCycle = (fillCycle + 1) % len(fillColorCycle)
419 elif path.pathType == 'WALL-INNER':
422 elif path.pathType == 'SUPPORT':
424 elif path.pathType == 'SKIRT':
428 if path.type == 'retract':
430 if path.type == 'extrude':
433 for i in xrange(0, len(path.list) - 1):
435 v1 = path.list[i + 1]
437 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
438 dist = (v0 - v1).vsize()
439 if dist > 0 and path.layerThickness > 0:
440 extrusionMMperDist = (v1.e - v0.e) / dist
441 lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
443 drawLength += (v0 - v1).vsize()
444 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
447 vv2 = v0 + normal * lineWidth
448 vv3 = v1 + normal * lineWidth
449 vv0 = v0 - normal * lineWidth
450 vv1 = v1 - normal * lineWidth
454 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
455 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
456 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
457 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
459 if prevNormal is not None:
460 n = (normal + prevNormal)
462 vv4 = v0 + n * lineWidth
463 vv5 = v0 - n * lineWidth
466 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
467 glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
468 glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
469 glVertex3f(v0.x, v0.y, v0.z - zOffset)
471 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
472 glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
473 glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
474 glVertex3f(v0.x, v0.y, v0.z - zOffset)
481 glBegin(GL_LINE_STRIP)
484 glVertex3f(v.x, v.y, v.z)
486 if not path.type == 'move':
487 prevPathWasRetract = False
488 if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):
489 prevPathWasRetract = True
490 glEnable(GL_CULL_FACE)