Skip to content

Instantly share code, notes, and snippets.

@pmolodo
Created August 31, 2018 19:23
Show Gist options
  • Save pmolodo/f9ddb277da3eab2948d27ddb1f84aba0 to your computer and use it in GitHub Desktop.
Save pmolodo/f9ddb277da3eab2948d27ddb1f84aba0 to your computer and use it in GitHub Desktop.
Maya 2018 bug with rotateAxis evaluation
########################################################################
# DESCRIPTION:
#
# Produces the custom transform node "ConnectedToRotateAxisNode".
# All it really does is declare an attributeAffects relationship between
# a custom attribute and "rotateAxis", which, in maya 2018, causes a bug
# in evaluation of rotateAxis on the BASE / "normal" transform node!
#
########################################################################
import maya.OpenMaya as OpenMaya
import maya.OpenMayaMPx as OpenMayaMPx
import sys
kConnectedToRotateAxisPluginName = "connectedToRotateAxis"
kConnectedToRotateAxisNodeName = kConnectedToRotateAxisPluginName
kConnectedToRotateAxisNodeID = OpenMaya.MTypeId(0x87314)
class ConnectedToRotateAxisNode(OpenMayaMPx.MPxTransform):
aMyDouble = OpenMaya.MObject()
def __init__(self, transform=None):
if transform is None:
OpenMayaMPx.MPxTransform.__init__(self)
else:
OpenMayaMPx.MPxTransform.__init__(self, transform)
def className(self):
return kConnectedToRotateAxisNodeName
# create/initialize node
def nodeCreator():
return OpenMayaMPx.asMPxPtr( ConnectedToRotateAxisNode() )
def nodeInitializer():
numFn = OpenMaya.MFnNumericAttribute()
ConnectedToRotateAxisNode.aMyDouble = numFn.create("myDouble", "myd", OpenMaya.MFnNumericData.kDouble, 0.0)
ConnectedToRotateAxisNode.addAttribute(ConnectedToRotateAxisNode.aMyDouble)
# The rotateAxis property doesn't seem to work right - call fget manually
rotateAxis = ConnectedToRotateAxisNode.rotateAxis
if type(rotateAxis) == property:
rotateAxis = rotateAxis.fget()
ConnectedToRotateAxisNode.attributeAffects(ConnectedToRotateAxisNode.aMyDouble, rotateAxis)
return
# initialize the script plug-in
def initializePlugin(mobject):
mplugin = OpenMayaMPx.MFnPlugin(mobject)
matrixId = OpenMayaMPx.MPxTransformationMatrix.baseTransformationMatrixId
if type(matrixId) == property:
matrixId = matrixId.fget()
try:
mplugin.registerTransform( kConnectedToRotateAxisNodeName, kConnectedToRotateAxisNodeID, \
nodeCreator, nodeInitializer,
OpenMayaMPx.MPxTransformationMatrix.creator,
matrixId)
except:
sys.stderr.write( "Failed to register transform: %s\n" % kConnectedToRotateAxisNodeName )
raise
# uninitialize the script plug-in
def uninitializePlugin(mobject):
mplugin = OpenMayaMPx.MFnPlugin(mobject)
try:
mplugin.deregisterNode( kConnectedToRotateAxisNodeID )
except:
sys.stderr.write( "Failed to unregister node: %s\n" % kConnectedToRotateAxisNodeName )
raise
# This test shows that, in Maya 2018, evaluation of the "rotateAxis" can return
# the wrong result, to a visually noticeable degree
# Specifically, this error happens if there is any loaded plugin that has a
# custom MPxTransform node, that declares an "attributeAffects" relationship
# to rotateAxis. This is also disturbing because the bug happens on the BASE
# transform class, NOT just on the derived transform - nothing the derived
# subclass does should even affect the base class!
import maya.api.OpenMaya as om
import maya.api.OpenMayaAnim as oma
import maya.cmds as cmds
import math
import maya.cmds as cmds
if 'about' not in cmds.__dict__:
import maya.standalone
maya.standalone.initialize()
def doTest():
print
cmds.file(f=1, new=1)
cmds.evaluationManager(mode="parallel")
trans = cmds.createNode('transform')
expected = (10.2930077056, 46.7926766826, 10.5121514437)
cmds.setAttr(trans + ".rotateAxisX", expected[0])
cmds.setAttr(trans + ".rotateAxisY", expected[1])
cmds.setAttr(trans + ".rotateAxisZ", expected[2])
cmds.setAttr(trans + ".rotateOrder", 4)
print expected
origValX = cmds.getAttr(trans + ".rotateAxisX")
# Maya 2018 will return:
# (14.855915293065653, 45.81977083964443, 21.282749751988867)
# ...here if the plugin is loaded, which is noticably different!
combinedVal = cmds.getAttr(trans + ".rotateAxis")[0]
print combinedVal
newValX = cmds.getAttr(trans + ".rotateAxisX")
if origValX != newValX:
print origValX
print newValX
print "FAILURE - x val changed!"
return
print "test finished successfully!"
# this will pass, before plugin is loaded
doTest()
# ...but it will fail after plugin... ie, custom Transform is affecting when
# BASE transform class is evaluated!
cmds.loadPlugin("connectedToRotateAxis.py")
doTest()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment