__all__ = ["TransformCustom", "instantiate"]
import math
from ActionRegistry import theActionRegistry
from awSupportApi import Vector
from MessageInterpreter import MessageInterpreter
from MessageRegistry import theMessageRegistry
from Modes import SelectionMode
from RTFapi import Event
from UserCustomization import UserCustomBase, CustomInfo
from Application import theApplication
CUSTOM_TRANSFORM_ENABLE_Doc = \
[(
"""
Enable or disable custom transform feature. When enable, left mouse
button will transform the scene and right mouse button will rotate
the scene.
"""
),
[[("state"),("True to enable and False to disable")],
]
]
theMessageRegistry.register("CUSTOM_TRANSFORM_ENABLE",
(bool,), 0, CUSTOM_TRANSFORM_ENABLE_Doc)
class TransformCustom(UserCustomBase):
__kMenuId = u"Edit"
def __init__(self):
self.__myMenu = None
self.__myMenuItemId = None
self.__myInterpreter = TransformInterpreter()
def getInterpreter(self, isInteractive):
if isInteractive:
return self.__myInterpreter
return None
def appendMenuItems(self, id, menu):
if TransformCustom.__kMenuId == id:
self.__myMenu = menu
menu.appendSeparator()
self.__myMenuItemId = menu.appendCheckItem(
_("Custom Transform"), self.OnTransform)
def enableMenuStates(self, id, enableStates):
if TransformCustom.__kMenuId == id:
enableStates[self.__myMenuItemId] = True
def resetMenuStates(self, id):
if TransformCustom.__kMenuId == id:
menuItemStates = {}
menuItemStates[self.__myMenuItemId] = False
self.__myMenu.checkMenuItems(menuItemStates)
def OnTransform(self, event):
isOn = bool(self.__myMenu.IsChecked(self.__myMenuItemId))
if isOn:
self.sendMessage("SELECT", ((), SelectionMode.kReplace))
self.sendMessage("CUSTOM_TRANSFORM_ENABLE", (isOn,))
class TransformInterpreter(MessageInterpreter):
__kMoveStartKeyMappingId = "MoveStart"
__kMoveKeyMappingId = "Move"
__kRotateStartKeyMappingId = "RotateStart"
__kRotateKeyMappingId = "Rotate"
def __init__(self):
MessageInterpreter.__init__(self)
self.__myDisplay = None
self.__myRotatePivot = (0.0, 0.0, 0.0)
self.__myLastPosition = (0.0, 0.0)
self.__myAzimuth = 0.0
keyMappings = (
(Event.BUTTON_LMB, (), True, Event.BUTTONDOWN, "MyMoveStart"),
)
theActionRegistry.registerList(TransformInterpreter.__kMoveStartKeyMappingId, keyMappings)
keyMappings = (
(Event.BUTTON_LMB, (), False, Event.BUTTONUP, "MyMoveStop")
, (Event.BUTTON_None, (), False, Event.MOVE, "MyMove")
)
theActionRegistry.registerList(TransformInterpreter.__kMoveKeyMappingId, keyMappings)
keyMappings = (
(Event.BUTTON_RMB, (), True, Event.BUTTONDOWN, "MyRotateStart"),
)
theActionRegistry.registerList(TransformInterpreter.__kRotateStartKeyMappingId, keyMappings)
keyMappings = (
(Event.BUTTON_RMB, (), False, Event.BUTTONUP, "MyRotateStop")
, (Event.BUTTON_None, (), False, Event.MOVE, "MyRotate")
)
theActionRegistry.registerList(TransformInterpreter.__kRotateKeyMappingId, keyMappings)
def getPosition(self, event):
x = event.getValue(Event.kNormalizedWinX)
y = event.getValue(Event.kNormalizedWinY)
return x, y
def MyMoveStart(self, event):
if self.__myDisplay is None or \
theApplication.getCurrentDocument().getModels().root is None:
return False
self.__myLastPosition = self.getPosition(event)
theActionRegistry.addSetToStack(TransformInterpreter.__kMoveKeyMappingId)
theActionRegistry.activateSet(TransformInterpreter.__kMoveKeyMappingId, True)
camera = self.__myDisplay.getCamera()
position = camera.getPosition()
lookAt = camera.getCOI()
viewDirection = Vector(0, 0, 0)
viewDirection.minus(lookAt, position)
viewDirection[2] = 0.0
viewDirection.normalize()
self.__myAzimuth = math.atan2(viewDirection[1], viewDirection[0])
return True
def MyMove(self, event):
x, y = self.getPosition(event)
lastX, lastY = self.__myLastPosition
dx = x - lastX
dy = y - lastY
cosTheta = math.cos(self.__myAzimuth)
sinTheta = math.sin(self.__myAzimuth)
tx = sinTheta * dx + cosTheta * dy
ty = -cosTheta * dx + sinTheta * dy
tx *= 100.0
ty *= 100.0
self.sendMessage("TRANSLATE_WORLDSPACE",
(tx, ty, 0.0, True, (theApplication.getCurrentDocument().getModels().root.getUniqueId(),)),
requestUndo=False)
x, y, z = self.__myRotatePivot
x += tx
y += ty
self.__myRotatePivot = (x, y, z)
self.__myLastPosition = self.getPosition(event)
return True
def MyMoveStop(self, event):
self.__myLastPosition = self.getPosition(event)
theActionRegistry.removeSetFromStack(TransformInterpreter.__kMoveKeyMappingId)
theActionRegistry.activateSet(TransformInterpreter.__kMoveKeyMappingId, False)
return True
def MyRotateStart(self, event):
if self.__myDisplay is None or \
theApplication.getCurrentDocument().getModels().root is None:
return False
self.__myLastPosition = self.getPosition(event)
theActionRegistry.addSetToStack(TransformInterpreter.__kRotateKeyMappingId)
theActionRegistry.activateSet(TransformInterpreter.__kRotateKeyMappingId, True)
return True
def MyRotate(self, event):
x, y = self.getPosition(event)
lastX, lastY = self.__myLastPosition
dx = x - lastX
dy = y - lastY
degrees = dx * 180.0
radians = math.radians(degrees)
self.sendMessage("ROTATE_WORLDSPACE",
(radians, (0.0, 0.0, 1.0), self.__myRotatePivot, True,
(theApplication.getCurrentDocument().getModels().root.getUniqueId(),)),
requestUndo=False)
self.__myLastPosition = self.getPosition(event)
return True
def MyRotateStop(self, event):
self.__myLastPosition = self.getPosition(event)
theActionRegistry.removeSetFromStack(TransformInterpreter.__kRotateKeyMappingId)
theActionRegistry.activateSet(TransformInterpreter.__kRotateKeyMappingId, False)
return True
def APPLICATION_CLOSE_SCENE(self, message):
self.__myRotatePivot = (0.0, 0.0, 0.0)
self.__myLastPosition = (0.0, 0.0)
theActionRegistry.removeSetFromStack(TransformInterpreter.__kMoveKeyMappingId)
theActionRegistry.removeSetFromStack(TransformInterpreter.__kMoveStartKeyMappingId)
theActionRegistry.removeSetFromStack(TransformInterpreter.__kRotateKeyMappingId)
theActionRegistry.removeSetFromStack(TransformInterpreter.__kRotateStartKeyMappingId)
def CUSTOM_TRANSFORM_ENABLE(self, message):
(isOn,) = message.data
if isOn:
theActionRegistry.addSetToStack(TransformInterpreter.__kMoveStartKeyMappingId)
theActionRegistry.addSetToStack(TransformInterpreter.__kRotateStartKeyMappingId)
else:
theActionRegistry.removeSetFromStack(TransformInterpreter.__kMoveStartKeyMappingId)
theActionRegistry.removeSetFromStack(TransformInterpreter.__kRotateStartKeyMappingId)
theActionRegistry.activateSet(TransformInterpreter.__kMoveStartKeyMappingId, isOn)
theActionRegistry.activateSet(TransformInterpreter.__kRotateStartKeyMappingId, isOn)
def SET_DISPLAY(self, message):
(self.__myDisplay,) = message.data
def instantiate():
return TransformCustom()
def info():
customInfo = CustomInfo()
customInfo.vendor = 'Autodesk'
customInfo.version = '2.0'
customInfo.api = '2013'
customInfo.shortInfo = "Custom transform feature."
customInfo.longInfo = \
"""Enable or disable custom transform feature. When enabled, left mouse button will transform the \
scene and right mouse button will rotate the scene.
"""
return customInfo