+class toolRotate(object):
+ def __init__(self, parent):
+ self.parent = parent
+ self.rotateRingDist = 1.5
+
+ def _ProjectToPlanes(self, p0, p1):
+ pp0 = p0 - [0,0,self.parent.getObjectSize()[2]/2]
+ pp1 = p1 - [0,0,self.parent.getObjectSize()[2]/2]
+ cursorX0 = pp0 - (pp1 - pp0) * (pp0[0] / (pp1[0] - pp0[0]))
+ cursorY0 = pp0 - (pp1 - pp0) * (pp0[1] / (pp1[1] - pp0[1]))
+ cursorZ0 = pp0 - (pp1 - pp0) * (pp0[2] / (pp1[2] - pp0[2]))
+ cursorYZ = math.sqrt((cursorX0[1] * cursorX0[1]) + (cursorX0[2] * cursorX0[2]))
+ cursorXZ = math.sqrt((cursorY0[0] * cursorY0[0]) + (cursorY0[2] * cursorY0[2]))
+ cursorXY = math.sqrt((cursorZ0[0] * cursorZ0[0]) + (cursorZ0[1] * cursorZ0[1]))
+ return cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY
+
+ def OnMouseMove(self, p0, p1):
+ radius = self.parent.getObjectBoundaryCircle()
+ cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY = self._ProjectToPlanes(p0, p1)
+ if radius * (self.rotateRingDist - 0.1) <= cursorXY <= radius * (self.rotateRingDist + 0.1) or radius * (self.rotateRingDist - 0.1) <= cursorYZ <= radius * (self.rotateRingDist + 0.1) or radius * (self.rotateRingDist - 0.1) <= cursorXZ <= radius * (self.rotateRingDist + 0.1):
+ self.parent.SetCursor(wx.StockCursor(wx.CURSOR_SIZING))
+ else:
+ self.parent.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
+
+ def OnDragStart(self, p0, p1):
+ radius = self.parent.getObjectBoundaryCircle()
+ cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY = self._ProjectToPlanes(p0, p1)
+ if radius * (self.rotateRingDist - 0.1) <= cursorXY <= radius * (self.rotateRingDist + 0.1) or radius * (self.rotateRingDist - 0.1) <= cursorYZ <= radius * (self.rotateRingDist + 0.1) or radius * (self.rotateRingDist - 0.1) <= cursorXZ <= radius * (self.rotateRingDist + 0.1):
+ if radius * (self.rotateRingDist - 0.1) <= cursorXY <= radius * (self.rotateRingDist + 0.1):
+ self.dragPlane = 'XY'
+ self.dragStartAngle = math.atan2(cursorZ0[1], cursorZ0[0]) * 180 / math.pi
+ elif radius * (self.rotateRingDist - 0.1) <= cursorXZ <= radius * (self.rotateRingDist + 0.1):
+ self.dragPlane = 'XZ'
+ self.dragStartAngle = math.atan2(cursorY0[2], cursorY0[0]) * 180 / math.pi
+ else:
+ self.dragPlane = 'YZ'
+ self.dragStartAngle = math.atan2(cursorX0[2], cursorX0[1]) * 180 / math.pi
+ return True
+ return False
+
+ def OnDrag(self, p0, p1):
+ cursorX0, cursorY0, cursorZ0, cursorYZ, cursorXZ, cursorXY = self._ProjectToPlanes(p0, p1)
+ if self.dragPlane == 'XY':
+ angle = math.atan2(cursorZ0[1], cursorZ0[0]) * 180 / math.pi
+ elif self.dragPlane == 'XZ':
+ angle = math.atan2(cursorY0[2], cursorY0[0]) * 180 / math.pi
+ else:
+ angle = math.atan2(cursorX0[2], cursorX0[1]) * 180 / math.pi
+ diff = angle - self.dragStartAngle
+ diff = round(diff / 5) * 5
+ rad = diff / 180.0 * math.pi
+ if self.dragPlane == 'XY':
+ self.parent.tempMatrix = numpy.matrix([[math.cos(rad), math.sin(rad), 0], [-math.sin(rad), math.cos(rad), 0], [0,0,1]], numpy.float64)
+ elif self.dragPlane == 'XZ':
+ self.parent.tempMatrix = numpy.matrix([[math.cos(rad), 0, math.sin(rad)], [0,1,0], [-math.sin(rad), 0, math.cos(rad)]], numpy.float64)
+ else:
+ self.parent.tempMatrix = numpy.matrix([[1,0,0], [0, math.cos(rad), math.sin(rad)], [0, -math.sin(rad), math.cos(rad)]], numpy.float64)
+
+ def OnDraw(self):
+ glDisable(GL_LIGHTING)
+ glDisable(GL_BLEND)
+ radius = self.parent.getObjectBoundaryCircle()
+ glScalef(radius, radius, radius)
+ glColor4ub(255,0,0,255)
+ glBegin(GL_LINE_LOOP)
+ for i in xrange(0, 64):
+ glVertex3f(self.rotateRingDist * math.cos(i/32.0*math.pi), self.rotateRingDist * math.sin(i/32.0*math.pi),0)
+ glEnd()
+ glColor4ub(0,255,0,255)
+ glBegin(GL_LINE_LOOP)
+ for i in xrange(0, 64):
+ glVertex3f(0, self.rotateRingDist * math.cos(i/32.0*math.pi), self.rotateRingDist * math.sin(i/32.0*math.pi))
+ glEnd()
+ glColor4ub(0,0,255,255)
+ glBegin(GL_LINE_LOOP)
+ for i in xrange(0, 64):
+ glVertex3f(self.rotateRingDist * math.cos(i/32.0*math.pi), 0, self.rotateRingDist * math.sin(i/32.0*math.pi))
+ glEnd()
+