2 from __future__ import absolute_import
8 from Cura.util import meshLoader
9 from Cura.util import util3d
10 from Cura.util import profile
11 from Cura.util.resources import getPathForMesh, getPathForImage
15 OpenGL.ERROR_CHECKING = False
16 from OpenGL.GLUT import *
17 from OpenGL.GLU import *
18 from OpenGL.GL import *
21 def InitGL(window, view3D, zoom):
22 # set viewing projection
23 glMatrixMode(GL_MODELVIEW)
25 size = window.GetSize()
26 glViewport(0, 0, size.GetWidth(), size.GetHeight())
28 glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
29 glLightfv(GL_LIGHT1, GL_POSITION, [1.0, 1.0, 1.0, 0.0])
31 glEnable(GL_RESCALE_NORMAL)
34 glEnable(GL_DEPTH_TEST)
35 glEnable(GL_CULL_FACE)
38 glClearColor(1.0, 1.0, 1.0, 1.0)
42 glMatrixMode(GL_PROJECTION)
44 aspect = float(size.GetWidth()) / float(size.GetHeight())
46 gluPerspective(45.0, aspect, 1.0, 1000.0)
48 glOrtho(-aspect * (zoom), aspect * (zoom), -1.0 * (zoom), 1.0 * (zoom), -1000.0, 1000.0)
50 glMatrixMode(GL_MODELVIEW)
52 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
56 def DrawMachine(machineSize):
57 if profile.getPreference('machine_type') == 'ultimaker':
60 glTranslate(100, 200, -5)
61 glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8])
62 glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5])
64 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR)
67 if platformMesh is None:
69 platformMesh = meshLoader.loadMesh(getPathForMesh('ultimaker_platform.stl'))
74 DrawMesh(platformMesh)
77 glDisable(GL_LIGHTING)
79 glColor3f(0.7, 0.7, 0.7)
82 for i in xrange(0, int(machineSize.x), 10):
84 glVertex3f(i, machineSize.y, 0)
85 for i in xrange(0, int(machineSize.y), 10):
87 glVertex3f(machineSize.x, i, 0)
90 glEnable(GL_LINE_SMOOTH)
92 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
93 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
95 glColor3f(0.0, 0.0, 0.0)
99 glVertex3f(machineSize.x, 0, 0)
100 glVertex3f(machineSize.x, machineSize.y, 0)
101 glVertex3f(0, machineSize.y, 0)
105 glBegin(GL_LINE_LOOP)
106 glVertex3f(0, 0, machineSize.z)
107 glVertex3f(machineSize.x, 0, machineSize.z)
108 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
109 glVertex3f(0, machineSize.y, machineSize.z)
113 glVertex3f(0, 0, machineSize.z)
114 glVertex3f(machineSize.x, 0, 0)
115 glVertex3f(machineSize.x, 0, machineSize.z)
116 glVertex3f(machineSize.x, machineSize.y, 0)
117 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
118 glVertex3f(0, machineSize.y, 0)
119 glVertex3f(0, machineSize.y, machineSize.z)
122 glDisable(GL_CULL_FACE)
124 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
128 for x in xrange(-int(sx/20)-1, int(sx / 20) + 1):
129 for y in xrange(-int(sx/20)-1, int(sy / 20) + 1):
134 x1 = max(min(x1, sx), 0)
135 y1 = max(min(y1, sy), 0)
136 x2 = max(min(x2, sx), 0)
137 y2 = max(min(y2, sy), 0)
138 if (x & 1) == (y & 1):
139 glColor4ub(5, 171, 231, 127)
141 glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128)
143 glVertex3f(x1, y1, -0.01)
144 glVertex3f(x2, y1, -0.01)
145 glVertex3f(x2, y2, -0.01)
146 glVertex3f(x1, y2, -0.01)
149 glEnable(GL_CULL_FACE)
151 glColor4ub(5, 171, 231, 64)
153 glVertex3f(0, 0, machineSize.z)
154 glVertex3f(0, machineSize.y, machineSize.z)
155 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
156 glVertex3f(machineSize.x, 0, machineSize.z)
159 glColor4ub(5, 171, 231, 96)
162 glVertex3f(0, 0, machineSize.z)
163 glVertex3f(machineSize.x, 0, machineSize.z)
164 glVertex3f(machineSize.x, 0, 0)
166 glVertex3f(0, machineSize.y, machineSize.z)
167 glVertex3f(0, machineSize.y, 0)
168 glVertex3f(machineSize.x, machineSize.y, 0)
169 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
172 glColor4ub(5, 171, 231, 128)
174 glVertex3f(0, 0, machineSize.z)
176 glVertex3f(0, machineSize.y, 0)
177 glVertex3f(0, machineSize.y, machineSize.z)
179 glVertex3f(machineSize.x, 0, 0)
180 glVertex3f(machineSize.x, 0, machineSize.z)
181 glVertex3f(machineSize.x, machineSize.y, machineSize.z)
182 glVertex3f(machineSize.x, machineSize.y, 0)
206 glDisable(GL_DEPTH_TEST)
210 glTranslate(20, 0, 0)
211 noZ = ResetMatrixRotationAndScale()
212 glDrawStringCenter("X")
218 glTranslate(0, 20, 0)
219 glDrawStringCenter("Y")
226 glTranslate(0, 0, 20)
227 glDrawStringCenter("Z")
231 glEnable(GL_DEPTH_TEST)
233 def glDrawStringCenter(s):
237 width += glutBitmapWidth(GLUT_BITMAP_HELVETICA_18, ord(c))
238 glBitmap(0,0,0,0, -width/2, 0, None)
240 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, ord(c))
242 def unproject(winx, winy, winz, modelMatrix, projMatrix, viewport):
243 npModelMatrix = numpy.matrix(numpy.array(modelMatrix, numpy.float64).reshape((4,4)))
244 npProjMatrix = numpy.matrix(numpy.array(projMatrix, numpy.float64).reshape((4,4)))
245 finalMatrix = npModelMatrix * npProjMatrix
246 finalMatrix = numpy.linalg.inv(finalMatrix)
248 viewport = map(float, viewport)
249 vector = numpy.array([(winx - viewport[0]) / viewport[2] * 2.0 - 1.0, (winy - viewport[1]) / viewport[3] * 2.0 - 1.0, winz * 2.0 - 1.0, 1]).reshape((1,4))
250 vector = (numpy.matrix(vector) * finalMatrix).getA().flatten()
251 ret = list(vector)[0:3] / vector[3]
254 def convert3x3MatrixTo4x4(matrix):
255 return list(matrix.getA()[0]) + [0] + list(matrix.getA()[1]) + [0] + list(matrix.getA()[2]) + [0, 0,0,0,1]
257 def loadGLTexture(filename):
258 tex = glGenTextures(1)
259 glBindTexture(GL_TEXTURE_2D, tex)
260 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
263 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
264 img = wx.ImageFromBitmap(wx.Bitmap(getPathForImage(filename)))
265 rgbData = img.GetData()
266 alphaData = img.GetAlphaData()
267 if alphaData != None:
269 for i in xrange(0, len(alphaData)):
270 data += rgbData[i*3:i*3+3] + alphaData[i]
271 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.GetWidth(), img.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, data)
273 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.GetWidth(), img.GetHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, rgbData)
276 def ResetMatrixRotationAndScale():
277 matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
281 scale2D = matrix[0][0]
292 if matrix[3][2] != 0.0:
293 matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
294 matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
297 matrix[0][0] = scale2D
298 matrix[1][1] = scale2D
299 matrix[2][2] = scale2D
303 glLoadMatrixf(matrix)
307 def DrawBox(vMin, vMax):
308 glBegin(GL_LINE_LOOP)
309 glVertex3f(vMin[0], vMin[1], vMin[2])
310 glVertex3f(vMax[0], vMin[1], vMin[2])
311 glVertex3f(vMax[0], vMax[1], vMin[2])
312 glVertex3f(vMin[0], vMax[1], vMin[2])
315 glBegin(GL_LINE_LOOP)
316 glVertex3f(vMin[0], vMin[1], vMax[2])
317 glVertex3f(vMax[0], vMin[1], vMax[2])
318 glVertex3f(vMax[0], vMax[1], vMax[2])
319 glVertex3f(vMin[0], vMax[1], vMax[2])
322 glVertex3f(vMin[0], vMin[1], vMin[2])
323 glVertex3f(vMin[0], vMin[1], vMax[2])
324 glVertex3f(vMax[0], vMin[1], vMin[2])
325 glVertex3f(vMax[0], vMin[1], vMax[2])
326 glVertex3f(vMax[0], vMax[1], vMin[2])
327 glVertex3f(vMax[0], vMax[1], vMax[2])
328 glVertex3f(vMin[0], vMax[1], vMin[2])
329 glVertex3f(vMin[0], vMax[1], vMax[2])
333 def DrawMeshOutline(mesh):
334 glEnable(GL_CULL_FACE)
335 glEnableClientState(GL_VERTEX_ARRAY);
336 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
340 glPolygonMode(GL_BACK, GL_LINE)
341 glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
342 glPolygonMode(GL_BACK, GL_FILL)
345 glDisableClientState(GL_VERTEX_ARRAY)
349 glEnable(GL_CULL_FACE)
350 glEnableClientState(GL_VERTEX_ARRAY);
351 glEnableClientState(GL_NORMAL_ARRAY);
352 glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
353 glNormalPointer(GL_FLOAT, 0, mesh.normal)
355 #Odd, drawing in batchs is a LOT faster then drawing it all at once.
356 batchSize = 999 #Warning, batchSize needs to be dividable by 3
357 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
358 extraCount = mesh.vertexCount - extraStartPos
361 for i in xrange(0, int(mesh.vertexCount / batchSize)):
362 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
363 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
366 glNormalPointer(GL_FLOAT, 0, mesh.invNormal)
367 for i in xrange(0, int(mesh.vertexCount / batchSize)):
368 glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
369 extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
370 extraCount = mesh.vertexCount - extraStartPos
371 glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
374 glDisableClientState(GL_VERTEX_ARRAY)
375 glDisableClientState(GL_NORMAL_ARRAY);
378 def DrawMeshSteep(mesh, angle):
379 cosAngle = math.sin(angle / 180.0 * math.pi)
380 glDisable(GL_LIGHTING)
381 glDepthFunc(GL_EQUAL)
382 for i in xrange(0, int(mesh.vertexCount), 3):
383 if mesh.normal[i][2] < -0.999999:
384 if mesh.vertexes[i + 0][2] > 0.01:
386 glBegin(GL_TRIANGLES)
387 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
388 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
389 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
391 elif mesh.normal[i][2] < -cosAngle:
392 glColor3f(-mesh.normal[i][2], 0, 0)
393 glBegin(GL_TRIANGLES)
394 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
395 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
396 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
398 elif mesh.normal[i][2] > 0.999999:
399 if mesh.vertexes[i + 0][2] > 0.01:
401 glBegin(GL_TRIANGLES)
402 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
403 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
404 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
406 elif mesh.normal[i][2] > cosAngle:
407 glColor3f(mesh.normal[i][2], 0, 0)
408 glBegin(GL_TRIANGLES)
409 glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
410 glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
411 glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
416 def DrawGCodeLayer(layer):
417 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
418 filamentArea = math.pi * filamentRadius * filamentRadius
419 lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
422 fillColorCycle = [[0.5, 0.5, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]
423 moveColor = [0, 0, 1]
424 retractColor = [1, 0, 0.5]
425 supportColor = [0, 1, 1]
426 extrudeColor = [1, 0, 0]
427 innerWallColor = [0, 1, 0]
428 skirtColor = [0, 0.5, 0.5]
429 prevPathWasRetract = False
431 glDisable(GL_CULL_FACE)
433 if path.type == 'move':
434 if prevPathWasRetract:
439 if path.type == 'extrude':
440 if path.pathType == 'FILL':
441 c = fillColorCycle[fillCycle]
442 fillCycle = (fillCycle + 1) % len(fillColorCycle)
443 elif path.pathType == 'WALL-INNER':
446 elif path.pathType == 'SUPPORT':
448 elif path.pathType == 'SKIRT':
452 if path.type == 'retract':
454 if path.type == 'extrude':
457 for i in xrange(0, len(path.list) - 1):
459 v1 = path.list[i + 1]
461 # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
462 dist = (v0 - v1).vsize()
463 if dist > 0 and path.layerThickness > 0:
464 extrusionMMperDist = (v1.e - v0.e) / dist
465 lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
467 drawLength += (v0 - v1).vsize()
468 normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
471 vv2 = v0 + normal * lineWidth
472 vv3 = v1 + normal * lineWidth
473 vv0 = v0 - normal * lineWidth
474 vv1 = v1 - normal * lineWidth
478 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
479 glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
480 glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
481 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
483 if prevNormal is not None:
484 n = (normal + prevNormal)
486 vv4 = v0 + n * lineWidth
487 vv5 = v0 - n * lineWidth
490 glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
491 glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
492 glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
493 glVertex3f(v0.x, v0.y, v0.z - zOffset)
495 glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
496 glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
497 glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
498 glVertex3f(v0.x, v0.y, v0.z - zOffset)
505 glBegin(GL_LINE_STRIP)
508 glVertex3f(v.x, v.y, v.z)
510 if not path.type == 'move':
511 prevPathWasRetract = False
512 if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):
513 prevPathWasRetract = True
514 glEnable(GL_CULL_FACE)