1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
2 from __future__ import absolute_import
9 OpenGL.ERROR_CHECKING = False
10 from OpenGL.GLU import *
11 from OpenGL.GL import *
13 from Cura.gui.util import opengl
15 class toolNone(object):
16 def __init__(self, parent):
19 def OnMouseMove(self, p0, p1):
22 def OnDragStart(self, p0, p1):
25 def OnDrag(self, p0, p1):
34 class toolInfo(object):
35 def __init__(self, parent):
38 def OnMouseMove(self, p0, p1):
41 def OnDragStart(self, p0, p1):
44 def OnDrag(self, p0, p1):
51 glDisable(GL_LIGHTING)
53 glDisable(GL_DEPTH_TEST)
54 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
56 size = self.parent.getObjectSize()
57 radius = self.parent.getObjectBoundaryCircle()
59 glTranslate(0,0,size[2]/2 + 5)
60 glRotate(-self.parent.yaw, 0,0,1)
61 if self.parent.pitch < 80:
62 glTranslate(0, radius + 5,0)
63 elif self.parent.pitch < 100:
64 glTranslate(0, (radius + 5) * (90 - self.parent.pitch) / 10,0)
66 glTranslate(0,-(radius + 5),0)
67 opengl.glDrawStringCenter("%dx%dx%d" % (size[0], size[1], size[2]))
74 glVertex3f(size[0], size[1], size[2])
75 glVertex3f(size[0], size[1], size[2]/4*3)
76 glVertex3f(size[0], size[1], size[2])
77 glVertex3f(size[0], size[1]/4*3, size[2])
78 glVertex3f(size[0], size[1], size[2])
79 glVertex3f(size[0]/4*3, size[1], size[2])
81 glVertex3f(-size[0], -size[1], size[2])
82 glVertex3f(-size[0], -size[1], size[2]/4*3)
83 glVertex3f(-size[0], -size[1], size[2])
84 glVertex3f(-size[0], -size[1]/4*3, size[2])
85 glVertex3f(-size[0], -size[1], size[2])
86 glVertex3f(-size[0]/4*3, -size[1], size[2])
88 glVertex3f(size[0], -size[1], -size[2])
89 glVertex3f(size[0], -size[1], -size[2]/4*3)
90 glVertex3f(size[0], -size[1], -size[2])
91 glVertex3f(size[0], -size[1]/4*3, -size[2])
92 glVertex3f(size[0], -size[1], -size[2])
93 glVertex3f(size[0]/4*3, -size[1], -size[2])
95 glVertex3f(-size[0], size[1], -size[2])
96 glVertex3f(-size[0], size[1], -size[2]/4*3)
97 glVertex3f(-size[0], size[1], -size[2])
98 glVertex3f(-size[0], size[1]/4*3, -size[2])
99 glVertex3f(-size[0], size[1], -size[2])
100 glVertex3f(-size[0]/4*3, size[1], -size[2])
103 class toolRotate(object):
104 def __init__(self, parent):
106 self.rotateRingDist = 1.5
107 self.rotateRingDistMin = 1.3
108 self.rotateRingDistMax = 1.7
109 self.dragPlane = None
110 self.dragStartAngle = None
111 self.dragEndAngle = None
113 def _ProjectToPlanes(self, p0, p1):
114 cursorX0 = p0 - (p1 - p0) * (p0[0] / (p1[0] - p0[0]))
115 cursorY0 = p0 - (p1 - p0) * (p0[1] / (p1[1] - p0[1]))
116 cursorZ0 = p0 - (p1 - p0) * (p0[2] / (p1[2] - p0[2]))
117 cursorYZ = math.sqrt((cursorX0[1] * cursorX0[1]) + (cursorX0[2] * cursorX0[2]))
118 cursorXZ = math.sqrt((cursorY0[0] * cursorY0[0]) + (cursorY0[2] * cursorY0[2]))
119 cursorXY = math.sqrt((cursorZ0[0] * cursorZ0[0]) + (cursorZ0[1] * cursorZ0[1]))
120 return cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY
122 def OnMouseMove(self, p0, p1):
123 radius = self.parent.getObjectBoundaryCircle()
124 cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY = self._ProjectToPlanes(p0, p1)
125 oldDragPlane = self.dragPlane
126 if radius * self.rotateRingDistMin <= cursorXY <= radius * self.rotateRingDistMax or radius * self.rotateRingDistMin <= cursorYZ <= radius * self.rotateRingDistMax or radius * self.rotateRingDistMin <= cursorXZ <= radius * self.rotateRingDistMax:
127 #self.parent.SetCursor(wx.StockCursor(wx.CURSOR_SIZING))
128 if self.dragStartAngle is None:
129 if radius * self.rotateRingDistMin <= cursorXY <= radius * self.rotateRingDistMax:
130 self.dragPlane = 'XY'
131 elif radius * self.rotateRingDistMin <= cursorXZ <= radius * self.rotateRingDistMax:
132 self.dragPlane = 'XZ'
134 self.dragPlane = 'YZ'
136 if self.dragStartAngle is None:
138 #self.parent.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
140 def OnDragStart(self, p0, p1):
141 radius = self.parent.getObjectBoundaryCircle()
142 cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY = self._ProjectToPlanes(p0, p1)
143 if radius * self.rotateRingDistMin <= cursorXY <= radius * self.rotateRingDistMax or radius * self.rotateRingDistMin <= cursorYZ <= radius * self.rotateRingDistMax or radius * self.rotateRingDistMin <= cursorXZ <= radius * self.rotateRingDistMax:
144 if radius * self.rotateRingDistMin <= cursorXY <= radius * self.rotateRingDistMax:
145 self.dragPlane = 'XY'
146 self.dragStartAngle = math.atan2(cursorZ0[1], cursorZ0[0]) * 180 / math.pi
147 elif radius * self.rotateRingDistMin <= cursorXZ <= radius * self.rotateRingDistMax:
148 self.dragPlane = 'XZ'
149 self.dragStartAngle = math.atan2(cursorY0[2], cursorY0[0]) * 180 / math.pi
151 self.dragPlane = 'YZ'
152 self.dragStartAngle = math.atan2(cursorX0[2], cursorX0[1]) * 180 / math.pi
153 self.dragEndAngle = self.dragStartAngle
157 def OnDrag(self, p0, p1):
158 cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY = self._ProjectToPlanes(p0, p1)
159 if self.dragPlane == 'XY':
160 angle = math.atan2(cursorZ0[1], cursorZ0[0]) * 180 / math.pi
161 elif self.dragPlane == 'XZ':
162 angle = math.atan2(cursorY0[2], cursorY0[0]) * 180 / math.pi
164 angle = math.atan2(cursorX0[2], cursorX0[1]) * 180 / math.pi
165 diff = angle - self.dragStartAngle
166 if wx.GetKeyState(wx.WXK_SHIFT):
167 diff = round(diff / 1) * 1
169 diff = round(diff / 15) * 15
174 rad = diff / 180.0 * math.pi
175 self.dragEndAngle = self.dragStartAngle + diff
176 if self.dragPlane == 'XY':
177 self.parent.tempMatrix = numpy.matrix([[math.cos(rad), math.sin(rad), 0], [-math.sin(rad), math.cos(rad), 0], [0,0,1]], numpy.float64)
178 elif self.dragPlane == 'XZ':
179 self.parent.tempMatrix = numpy.matrix([[math.cos(rad), 0, math.sin(rad)], [0,1,0], [-math.sin(rad), 0, math.cos(rad)]], numpy.float64)
181 self.parent.tempMatrix = numpy.matrix([[1,0,0], [0, math.cos(rad), math.sin(rad)], [0, -math.sin(rad), math.cos(rad)]], numpy.float64)
184 self.dragStartAngle = None
187 glDisable(GL_LIGHTING)
189 glDisable(GL_DEPTH_TEST)
190 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
191 radius = self.parent.getObjectBoundaryCircle()
192 glScalef(self.rotateRingDist * radius, self.rotateRingDist * radius, self.rotateRingDist * radius)
193 if self.dragPlane == 'XY':
195 glColor4ub(255,64,64,255)
196 if self.dragStartAngle is not None:
198 glRotate(self.dragStartAngle, 0,0,1)
205 glRotate(self.dragEndAngle, 0,0,1)
210 glTranslatef(1.1,0,0)
211 glColor4ub(0,0,0,255)
212 opengl.glDrawStringCenter("%d" % (abs(self.dragEndAngle - self.dragStartAngle)))
213 glColor4ub(255,64,64,255)
217 glColor4ub(128,0,0,255)
218 glBegin(GL_LINE_LOOP)
219 for i in xrange(0, 64):
220 glVertex3f(math.cos(i/32.0*math.pi), math.sin(i/32.0*math.pi),0)
222 if self.dragPlane == 'YZ':
223 glColor4ub(64,255,64,255)
225 if self.dragStartAngle is not None:
227 glRotate(self.dragStartAngle, 1,0,0)
234 glRotate(self.dragEndAngle, 1,0,0)
239 glTranslatef(0,1.1,0)
240 glColor4ub(0,0,0,255)
241 opengl.glDrawStringCenter("%d" % (abs(self.dragEndAngle - self.dragStartAngle)))
242 glColor4ub(64,255,64,255)
245 glColor4ub(0,128,0,255)
247 glBegin(GL_LINE_LOOP)
248 for i in xrange(0, 64):
249 glVertex3f(0, math.cos(i/32.0*math.pi), math.sin(i/32.0*math.pi))
251 if self.dragPlane == 'XZ':
253 glColor4ub(255,255,0,255)
254 if self.dragStartAngle is not None:
256 glRotate(self.dragStartAngle, 0,-1,0)
263 glRotate(self.dragEndAngle, 0,-1,0)
268 glTranslatef(1.1,0,0)
269 glColor4ub(0,0,0,255)
270 opengl.glDrawStringCenter("%d" % (abs(self.dragEndAngle - self.dragStartAngle)))
271 glColor4ub(255,255,0,255)
274 glColor4ub(128,128,0,255)
276 glBegin(GL_LINE_LOOP)
277 for i in xrange(0, 64):
278 glVertex3f(math.cos(i/32.0*math.pi), 0, math.sin(i/32.0*math.pi))
280 glEnable(GL_DEPTH_TEST)
282 class toolScale(object):
283 def __init__(self, parent):
288 def _pointDist(self, p0, p1, p2):
289 return numpy.linalg.norm(numpy.cross((p0 - p1), (p0 - p2))) / numpy.linalg.norm(p2 - p1)
291 def _traceNodes(self, p0, p1):
293 if self._pointDist(numpy.array([0,0,0],numpy.float32), p0, p1) < s * 2:
295 if self._pointDist(numpy.array([s*15,0,0],numpy.float32), p0, p1) < s * 2:
297 if self._pointDist(numpy.array([0,s*15,0],numpy.float32), p0, p1) < s * 2:
299 if self._pointDist(numpy.array([0,0,s*15],numpy.float32), p0, p1) < s * 2:
303 def _lineLineCrossingDistOnLine(self, s0, e0, s1, e1):
306 a = numpy.dot(d0, d0)
307 b = numpy.dot(d0, d1)
308 e = numpy.dot(d1, d1)
320 return float(self.parent._zoom) / float(self.parent.GetSize().GetWidth()) * 6.0
322 def OnMouseMove(self, p0, p1):
323 self.node = self._traceNodes(p0, p1)
325 def OnDragStart(self, p0, p1):
326 if self.node is None:
330 def OnDrag(self, p0, p1):
339 scale = self._lineLineCrossingDistOnLine(p0, p1, numpy.array([0,0,0], numpy.float32), numpy.array(endPoint, numpy.float32)) / 15.0 / s
340 if not wx.GetKeyState(wx.WXK_SHIFT):
341 objMatrix = self.parent.getObjectMatrix()
342 scaleX = numpy.linalg.norm(objMatrix[::,0].getA().flatten())
343 scaleY = numpy.linalg.norm(objMatrix[::,1].getA().flatten())
344 scaleZ = numpy.linalg.norm(objMatrix[::,2].getA().flatten())
345 if self.node == 1 or not wx.GetKeyState(wx.WXK_CONTROL):
346 matrixScale = (scaleX + scaleY + scaleZ) / 3
353 scale = (round((matrixScale * scale) * 10) / 10) / matrixScale
359 if self.node == 1 or not wx.GetKeyState(wx.WXK_CONTROL):
360 self.parent.tempMatrix = numpy.matrix([[scale,0,0], [0, scale, 0], [0, 0, scale]], numpy.float64)
362 self.parent.tempMatrix = numpy.matrix([[scale,0,0], [0, 1, 0], [0, 0, 1]], numpy.float64)
364 self.parent.tempMatrix = numpy.matrix([[1,0,0], [0, scale, 0], [0, 0, 1]], numpy.float64)
366 self.parent.tempMatrix = numpy.matrix([[1,0,0], [0, 1, 0], [0, 0, scale]], numpy.float64)
376 if self.node == 2 and self.scale is not None:
378 if self.node == 3 and self.scale is not None:
380 if self.node == 4 and self.scale is not None:
382 objMatrix = self.parent.getObjectMatrix()
383 scaleX = numpy.linalg.norm(objMatrix[::,0].getA().flatten())
384 scaleY = numpy.linalg.norm(objMatrix[::,1].getA().flatten())
385 scaleZ = numpy.linalg.norm(objMatrix[::,2].getA().flatten())
386 if self.scale is not None:
391 glDisable(GL_LIGHTING)
392 glDisable(GL_DEPTH_TEST)
394 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
397 size = self.parent.getObjectSize()
398 radius = self.parent.getObjectBoundaryCircle()
399 if self.scale is not None:
402 glTranslate(0,0,size[2]/2 + 5)
403 glRotate(-self.parent._yaw, 0,0,1)
404 if self.parent._pitch < 80:
405 glTranslate(0, radius + 5,0)
406 elif self.parent._pitch < 100:
407 glTranslate(0, (radius + 5) * (90 - self.parent._pitch) / 10,0)
409 glTranslate(0,-(radius + 5),0)
410 if self.parent.tempMatrix is not None:
411 size = (numpy.matrix([size]) * self.parent.tempMatrix).getA().flatten()
412 opengl.glDrawStringCenter("W, D, H: %0.1f, %0.1f, %0.1f mm" % (size[0], size[1], size[2]))
430 glColor3ub(255,255,255)
432 glColor3ub(192,192,192)
433 opengl.DrawBox([-s,-s,-s], [s,s,s])
436 opengl.glDrawStringCenter("%0.2f" % ((scaleX + scaleY + scaleZ) / 3.0))
439 glColor3ub(255,64,64)
444 opengl.DrawBox([-s,-s,-s], [s,s,s])
447 opengl.glDrawStringCenter("%0.2f" % (scaleX))
450 glColor3ub(64,255,64)
455 opengl.DrawBox([-s,-s,-s], [s,s,s])
458 opengl.glDrawStringCenter("%0.2f" % (scaleY))
461 glColor3ub(64,64,255)
466 opengl.DrawBox([-s,-s,-s], [s,s,s])
469 opengl.glDrawStringCenter("%0.2f" % (scaleZ))
472 glEnable(GL_DEPTH_TEST)
478 glVertex3f(size[0], size[1], size[2])
479 glVertex3f(size[0], size[1], size[2]/4*3)
480 glVertex3f(size[0], size[1], size[2])
481 glVertex3f(size[0], size[1]/4*3, size[2])
482 glVertex3f(size[0], size[1], size[2])
483 glVertex3f(size[0]/4*3, size[1], size[2])
485 glVertex3f(-size[0], size[1], size[2])
486 glVertex3f(-size[0], size[1], size[2]/4*3)
487 glVertex3f(-size[0], size[1], size[2])
488 glVertex3f(-size[0], size[1]/4*3, size[2])
489 glVertex3f(-size[0], size[1], size[2])
490 glVertex3f(-size[0]/4*3, size[1], size[2])
492 glVertex3f(size[0], -size[1], size[2])
493 glVertex3f(size[0], -size[1], size[2]/4*3)
494 glVertex3f(size[0], -size[1], size[2])
495 glVertex3f(size[0], -size[1]/4*3, size[2])
496 glVertex3f(size[0], -size[1], size[2])
497 glVertex3f(size[0]/4*3, -size[1], size[2])
499 glVertex3f(-size[0], -size[1], size[2])
500 glVertex3f(-size[0], -size[1], size[2]/4*3)
501 glVertex3f(-size[0], -size[1], size[2])
502 glVertex3f(-size[0], -size[1]/4*3, size[2])
503 glVertex3f(-size[0], -size[1], size[2])
504 glVertex3f(-size[0]/4*3, -size[1], size[2])
506 glVertex3f(size[0], size[1], -size[2])
507 glVertex3f(size[0], size[1], -size[2]/4*3)
508 glVertex3f(size[0], size[1], -size[2])
509 glVertex3f(size[0], size[1]/4*3, -size[2])
510 glVertex3f(size[0], size[1], -size[2])
511 glVertex3f(size[0]/4*3, size[1], -size[2])
513 glVertex3f(-size[0], size[1], -size[2])
514 glVertex3f(-size[0], size[1], -size[2]/4*3)
515 glVertex3f(-size[0], size[1], -size[2])
516 glVertex3f(-size[0], size[1]/4*3, -size[2])
517 glVertex3f(-size[0], size[1], -size[2])
518 glVertex3f(-size[0]/4*3, size[1], -size[2])
520 glVertex3f(size[0], -size[1], -size[2])
521 glVertex3f(size[0], -size[1], -size[2]/4*3)
522 glVertex3f(size[0], -size[1], -size[2])
523 glVertex3f(size[0], -size[1]/4*3, -size[2])
524 glVertex3f(size[0], -size[1], -size[2])
525 glVertex3f(size[0]/4*3, -size[1], -size[2])
527 glVertex3f(-size[0], -size[1], -size[2])
528 glVertex3f(-size[0], -size[1], -size[2]/4*3)
529 glVertex3f(-size[0], -size[1], -size[2])
530 glVertex3f(-size[0], -size[1]/4*3, -size[2])
531 glVertex3f(-size[0], -size[1], -size[2])
532 glVertex3f(-size[0]/4*3, -size[1], -size[2])
535 glEnable(GL_DEPTH_TEST)