1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
8 #OpenGL.ERROR_CHECKING = False
9 from OpenGL.GLU import *
10 from OpenGL.GL import *
12 from Cura.gui.util import openglHelpers
14 class toolNone(object):
15 def __init__(self, parent):
18 def OnMouseMove(self, p0, p1):
21 def OnDragStart(self, p0, p1):
24 def OnDrag(self, p0, p1):
33 class toolInfo(object):
34 def __init__(self, parent):
37 def OnMouseMove(self, p0, p1):
40 def OnDragStart(self, p0, p1):
43 def OnDrag(self, p0, p1):
50 glDisable(GL_LIGHTING)
52 glDisable(GL_DEPTH_TEST)
53 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
55 size = self.parent.getObjectSize()
56 radius = self.parent.getObjectBoundaryCircle()
58 glTranslate(0,0,size[2]/2 + 5)
59 glRotate(-self.parent.yaw, 0,0,1)
60 if self.parent.pitch < 80:
61 glTranslate(0, radius + 5,0)
62 elif self.parent.pitch < 100:
63 glTranslate(0, (radius + 5) * (90 - self.parent.pitch) / 10,0)
65 glTranslate(0,-(radius + 5),0)
66 openglHelpers.glDrawStringCenter("%dx%dx%d" % (size[0], size[1], size[2]))
73 glVertex3f(size[0], size[1], size[2])
74 glVertex3f(size[0], size[1], size[2]/4*3)
75 glVertex3f(size[0], size[1], size[2])
76 glVertex3f(size[0], size[1]/4*3, size[2])
77 glVertex3f(size[0], size[1], size[2])
78 glVertex3f(size[0]/4*3, size[1], size[2])
80 glVertex3f(-size[0], -size[1], size[2])
81 glVertex3f(-size[0], -size[1], size[2]/4*3)
82 glVertex3f(-size[0], -size[1], size[2])
83 glVertex3f(-size[0], -size[1]/4*3, size[2])
84 glVertex3f(-size[0], -size[1], size[2])
85 glVertex3f(-size[0]/4*3, -size[1], size[2])
87 glVertex3f(size[0], -size[1], -size[2])
88 glVertex3f(size[0], -size[1], -size[2]/4*3)
89 glVertex3f(size[0], -size[1], -size[2])
90 glVertex3f(size[0], -size[1]/4*3, -size[2])
91 glVertex3f(size[0], -size[1], -size[2])
92 glVertex3f(size[0]/4*3, -size[1], -size[2])
94 glVertex3f(-size[0], size[1], -size[2])
95 glVertex3f(-size[0], size[1], -size[2]/4*3)
96 glVertex3f(-size[0], size[1], -size[2])
97 glVertex3f(-size[0], size[1]/4*3, -size[2])
98 glVertex3f(-size[0], size[1], -size[2])
99 glVertex3f(-size[0]/4*3, size[1], -size[2])
102 class toolRotate(object):
103 def __init__(self, parent):
105 self.rotateRingDist = 1.5
106 self.rotateRingDistMin = 1.3
107 self.rotateRingDistMax = 1.7
108 self.dragPlane = None
109 self.dragStartAngle = None
110 self.dragEndAngle = None
112 def _ProjectToPlanes(self, p0, p1):
113 cursorX0 = p0 - (p1 - p0) * (p0[0] / (p1[0] - p0[0]))
114 cursorY0 = p0 - (p1 - p0) * (p0[1] / (p1[1] - p0[1]))
115 cursorZ0 = p0 - (p1 - p0) * (p0[2] / (p1[2] - p0[2]))
116 cursorYZ = math.sqrt((cursorX0[1] * cursorX0[1]) + (cursorX0[2] * cursorX0[2]))
117 cursorXZ = math.sqrt((cursorY0[0] * cursorY0[0]) + (cursorY0[2] * cursorY0[2]))
118 cursorXY = math.sqrt((cursorZ0[0] * cursorZ0[0]) + (cursorZ0[1] * cursorZ0[1]))
119 return cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY
121 def OnMouseMove(self, p0, p1):
122 radius = self.parent.getObjectBoundaryCircle()
123 cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY = self._ProjectToPlanes(p0, p1)
124 oldDragPlane = self.dragPlane
125 if radius * self.rotateRingDistMin <= cursorXY <= radius * self.rotateRingDistMax or radius * self.rotateRingDistMin <= cursorYZ <= radius * self.rotateRingDistMax or radius * self.rotateRingDistMin <= cursorXZ <= radius * self.rotateRingDistMax:
126 #self.parent.SetCursor(wx.StockCursor(wx.CURSOR_SIZING))
127 if self.dragStartAngle is None:
128 if radius * self.rotateRingDistMin <= cursorXY <= radius * self.rotateRingDistMax:
129 self.dragPlane = 'XY'
130 elif radius * self.rotateRingDistMin <= cursorXZ <= radius * self.rotateRingDistMax:
131 self.dragPlane = 'XZ'
133 self.dragPlane = 'YZ'
135 if self.dragStartAngle is None:
137 #self.parent.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
139 def OnDragStart(self, p0, p1):
140 radius = self.parent.getObjectBoundaryCircle()
141 cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY = self._ProjectToPlanes(p0, p1)
142 if radius * self.rotateRingDistMin <= cursorXY <= radius * self.rotateRingDistMax or radius * self.rotateRingDistMin <= cursorYZ <= radius * self.rotateRingDistMax or radius * self.rotateRingDistMin <= cursorXZ <= radius * self.rotateRingDistMax:
143 if radius * self.rotateRingDistMin <= cursorXY <= radius * self.rotateRingDistMax:
144 self.dragPlane = 'XY'
145 self.dragStartAngle = math.atan2(cursorZ0[1], cursorZ0[0]) * 180 / math.pi
146 elif radius * self.rotateRingDistMin <= cursorXZ <= radius * self.rotateRingDistMax:
147 self.dragPlane = 'XZ'
148 self.dragStartAngle = math.atan2(cursorY0[2], cursorY0[0]) * 180 / math.pi
150 self.dragPlane = 'YZ'
151 self.dragStartAngle = math.atan2(cursorX0[2], cursorX0[1]) * 180 / math.pi
152 self.dragEndAngle = self.dragStartAngle
156 def OnDrag(self, p0, p1):
157 cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY = self._ProjectToPlanes(p0, p1)
158 if self.dragPlane == 'XY':
159 angle = math.atan2(cursorZ0[1], cursorZ0[0]) * 180 / math.pi
160 elif self.dragPlane == 'XZ':
161 angle = math.atan2(cursorY0[2], cursorY0[0]) * 180 / math.pi
163 angle = math.atan2(cursorX0[2], cursorX0[1]) * 180 / math.pi
164 diff = angle - self.dragStartAngle
165 if wx.GetKeyState(wx.WXK_SHIFT):
166 diff = round(diff / 1) * 1
168 diff = round(diff / 15) * 15
173 rad = diff / 180.0 * math.pi
174 self.dragEndAngle = self.dragStartAngle + diff
175 if self.dragPlane == 'XY':
176 self.parent.tempMatrix = numpy.matrix([[math.cos(rad), math.sin(rad), 0], [-math.sin(rad), math.cos(rad), 0], [0,0,1]], numpy.float64)
177 elif self.dragPlane == 'XZ':
178 self.parent.tempMatrix = numpy.matrix([[math.cos(rad), 0, math.sin(rad)], [0,1,0], [-math.sin(rad), 0, math.cos(rad)]], numpy.float64)
180 self.parent.tempMatrix = numpy.matrix([[1,0,0], [0, math.cos(rad), math.sin(rad)], [0, -math.sin(rad), math.cos(rad)]], numpy.float64)
183 self.dragStartAngle = None
186 glDisable(GL_LIGHTING)
188 glDisable(GL_DEPTH_TEST)
189 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
190 radius = self.parent.getObjectBoundaryCircle()
191 glScalef(self.rotateRingDist * radius, self.rotateRingDist * radius, self.rotateRingDist * radius)
192 if self.dragPlane == 'XY':
194 glColor4ub(255,64,64,255)
195 if self.dragStartAngle is not None:
197 glRotate(self.dragStartAngle, 0,0,1)
204 glRotate(self.dragEndAngle, 0,0,1)
209 glTranslatef(1.1,0,0)
210 glColor4ub(0,0,0,255)
211 openglHelpers.glDrawStringCenter("%d" % (abs(self.dragEndAngle - self.dragStartAngle) + 0.5))
212 glColor4ub(255,64,64,255)
216 glColor4ub(128,0,0,255)
217 glBegin(GL_LINE_LOOP)
218 for i in xrange(0, 64):
219 glVertex3f(math.cos(i/32.0*math.pi), math.sin(i/32.0*math.pi),0)
221 if self.dragPlane == 'YZ':
222 glColor4ub(64,255,64,255)
224 if self.dragStartAngle is not None:
226 glRotate(self.dragStartAngle, 1,0,0)
233 glRotate(self.dragEndAngle, 1,0,0)
238 glTranslatef(0,1.1,0)
239 glColor4ub(0,0,0,255)
240 openglHelpers.glDrawStringCenter("%d" % (abs(self.dragEndAngle - self.dragStartAngle)))
241 glColor4ub(64,255,64,255)
244 glColor4ub(0,128,0,255)
246 glBegin(GL_LINE_LOOP)
247 for i in xrange(0, 64):
248 glVertex3f(0, math.cos(i/32.0*math.pi), math.sin(i/32.0*math.pi))
250 if self.dragPlane == 'XZ':
252 glColor4ub(255,255,0,255)
253 if self.dragStartAngle is not None:
255 glRotate(self.dragStartAngle, 0,-1,0)
262 glRotate(self.dragEndAngle, 0,-1,0)
267 glTranslatef(1.1,0,0)
268 glColor4ub(0,0,0,255)
269 openglHelpers.glDrawStringCenter("%d" % (abs(self.dragEndAngle - self.dragStartAngle)))
270 glColor4ub(255,255,0,255)
273 glColor4ub(128,128,0,255)
275 glBegin(GL_LINE_LOOP)
276 for i in xrange(0, 64):
277 glVertex3f(math.cos(i/32.0*math.pi), 0, math.sin(i/32.0*math.pi))
279 glEnable(GL_DEPTH_TEST)
281 class toolScale(object):
282 def __init__(self, parent):
287 def _pointDist(self, p0, p1, p2):
288 return numpy.linalg.norm(numpy.cross((p0 - p1), (p0 - p2))) / numpy.linalg.norm(p2 - p1)
290 def _traceNodes(self, p0, p1):
292 if self._pointDist(numpy.array([0,0,0],numpy.float32), p0, p1) < s * 2:
294 if self._pointDist(numpy.array([s*15,0,0],numpy.float32), p0, p1) < s * 2:
296 if self._pointDist(numpy.array([0,s*15,0],numpy.float32), p0, p1) < s * 2:
298 if self._pointDist(numpy.array([0,0,s*15],numpy.float32), p0, p1) < s * 2:
302 def _lineLineCrossingDistOnLine(self, s0, e0, s1, e1):
305 a = numpy.dot(d0, d0)
306 b = numpy.dot(d0, d1)
307 e = numpy.dot(d1, d1)
319 return float(self.parent._zoom) / float(self.parent.GetSize().GetWidth()) * 6.0
321 def OnMouseMove(self, p0, p1):
322 self.node = self._traceNodes(p0, p1)
324 def OnDragStart(self, p0, p1):
325 if self.node is None:
329 def OnDrag(self, p0, p1):
338 scale = self._lineLineCrossingDistOnLine(p0, p1, numpy.array([0,0,0], numpy.float32), numpy.array(endPoint, numpy.float32)) / 15.0 / s
339 if not wx.GetKeyState(wx.WXK_SHIFT):
340 objMatrix = self.parent.getObjectMatrix()
341 scaleX = numpy.linalg.norm(objMatrix[::,0].getA().flatten())
342 scaleY = numpy.linalg.norm(objMatrix[::,1].getA().flatten())
343 scaleZ = numpy.linalg.norm(objMatrix[::,2].getA().flatten())
344 if self.node == 1 or not wx.GetKeyState(wx.WXK_CONTROL):
345 matrixScale = (scaleX + scaleY + scaleZ) / 3
352 scale = (round((matrixScale * scale) * 10) / 10) / matrixScale
358 if self.node == 1 or not wx.GetKeyState(wx.WXK_CONTROL):
359 self.parent.tempMatrix = numpy.matrix([[scale,0,0], [0, scale, 0], [0, 0, scale]], numpy.float64)
361 self.parent.tempMatrix = numpy.matrix([[scale,0,0], [0, 1, 0], [0, 0, 1]], numpy.float64)
363 self.parent.tempMatrix = numpy.matrix([[1,0,0], [0, scale, 0], [0, 0, 1]], numpy.float64)
365 self.parent.tempMatrix = numpy.matrix([[1,0,0], [0, 1, 0], [0, 0, scale]], numpy.float64)
375 if self.node == 2 and self.scale is not None:
377 if self.node == 3 and self.scale is not None:
379 if self.node == 4 and self.scale is not None:
381 objMatrix = self.parent.getObjectMatrix()
382 scaleX = numpy.linalg.norm(objMatrix[::,0].getA().flatten())
383 scaleY = numpy.linalg.norm(objMatrix[::,1].getA().flatten())
384 scaleZ = numpy.linalg.norm(objMatrix[::,2].getA().flatten())
385 if self.scale is not None:
390 glDisable(GL_LIGHTING)
391 glDisable(GL_DEPTH_TEST)
393 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
396 size = self.parent.getObjectSize()
397 radius = self.parent.getObjectBoundaryCircle()
398 if self.scale is not None:
401 glTranslate(0,0,size[2]/2 + 5)
402 glRotate(-self.parent._yaw, 0,0,1)
403 if self.parent._pitch < 80:
404 glTranslate(0, radius + 5,0)
405 elif self.parent._pitch < 100:
406 glTranslate(0, (radius + 5) * (90 - self.parent._pitch) / 10,0)
408 glTranslate(0,-(radius + 5),0)
409 if self.parent.tempMatrix is not None:
410 size = (numpy.matrix([size]) * self.parent.tempMatrix).getA().flatten()
411 openglHelpers.glDrawStringCenter("W, D, H: %0.1f, %0.1f, %0.1f mm" % (size[0], size[1], size[2]))
429 glColor3ub(255,255,255)
431 glColor3ub(192,192,192)
432 openglHelpers.DrawBox([-s,-s,-s], [s,s,s])
435 openglHelpers.glDrawStringCenter("%0.2f" % ((scaleX + scaleY + scaleZ) / 3.0))
438 glColor3ub(255,64,64)
443 openglHelpers.DrawBox([-s,-s,-s], [s,s,s])
446 openglHelpers.glDrawStringCenter("%0.2f" % (scaleX))
449 glColor3ub(64,255,64)
454 openglHelpers.DrawBox([-s,-s,-s], [s,s,s])
457 openglHelpers.glDrawStringCenter("%0.2f" % (scaleY))
460 glColor3ub(64,64,255)
465 openglHelpers.DrawBox([-s,-s,-s], [s,s,s])
468 openglHelpers.glDrawStringCenter("%0.2f" % (scaleZ))
471 glEnable(GL_DEPTH_TEST)
477 glVertex3f(size[0], size[1], size[2])
478 glVertex3f(size[0], size[1], size[2]/4*3)
479 glVertex3f(size[0], size[1], size[2])
480 glVertex3f(size[0], size[1]/4*3, size[2])
481 glVertex3f(size[0], size[1], size[2])
482 glVertex3f(size[0]/4*3, size[1], size[2])
484 glVertex3f(-size[0], size[1], size[2])
485 glVertex3f(-size[0], size[1], size[2]/4*3)
486 glVertex3f(-size[0], size[1], size[2])
487 glVertex3f(-size[0], size[1]/4*3, size[2])
488 glVertex3f(-size[0], size[1], size[2])
489 glVertex3f(-size[0]/4*3, size[1], size[2])
491 glVertex3f(size[0], -size[1], size[2])
492 glVertex3f(size[0], -size[1], size[2]/4*3)
493 glVertex3f(size[0], -size[1], size[2])
494 glVertex3f(size[0], -size[1]/4*3, size[2])
495 glVertex3f(size[0], -size[1], size[2])
496 glVertex3f(size[0]/4*3, -size[1], size[2])
498 glVertex3f(-size[0], -size[1], size[2])
499 glVertex3f(-size[0], -size[1], size[2]/4*3)
500 glVertex3f(-size[0], -size[1], size[2])
501 glVertex3f(-size[0], -size[1]/4*3, size[2])
502 glVertex3f(-size[0], -size[1], size[2])
503 glVertex3f(-size[0]/4*3, -size[1], size[2])
505 glVertex3f(size[0], size[1], -size[2])
506 glVertex3f(size[0], size[1], -size[2]/4*3)
507 glVertex3f(size[0], size[1], -size[2])
508 glVertex3f(size[0], size[1]/4*3, -size[2])
509 glVertex3f(size[0], size[1], -size[2])
510 glVertex3f(size[0]/4*3, size[1], -size[2])
512 glVertex3f(-size[0], size[1], -size[2])
513 glVertex3f(-size[0], size[1], -size[2]/4*3)
514 glVertex3f(-size[0], size[1], -size[2])
515 glVertex3f(-size[0], size[1]/4*3, -size[2])
516 glVertex3f(-size[0], size[1], -size[2])
517 glVertex3f(-size[0]/4*3, size[1], -size[2])
519 glVertex3f(size[0], -size[1], -size[2])
520 glVertex3f(size[0], -size[1], -size[2]/4*3)
521 glVertex3f(size[0], -size[1], -size[2])
522 glVertex3f(size[0], -size[1]/4*3, -size[2])
523 glVertex3f(size[0], -size[1], -size[2])
524 glVertex3f(size[0]/4*3, -size[1], -size[2])
526 glVertex3f(-size[0], -size[1], -size[2])
527 glVertex3f(-size[0], -size[1], -size[2]/4*3)
528 glVertex3f(-size[0], -size[1], -size[2])
529 glVertex3f(-size[0], -size[1]/4*3, -size[2])
530 glVertex3f(-size[0], -size[1], -size[2])
531 glVertex3f(-size[0]/4*3, -size[1], -size[2])
534 glEnable(GL_DEPTH_TEST)