Created
August 14, 2020 16:57
-
-
Save viktorasm/0744a5f499fc7e5f4ad64cf089caa430 to your computer and use it in GitHub Desktop.
A bug in Autodesk Maya API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This is a test for Autodesk Maya to demonstrate that when skin cluster inputs are not transform nodes, | |
Maya simply crashes using MFnSkinCluster.setWeights() API call. | |
1. Run this script a few times to demonstrate that everything works as expected: you have a simple skinned mesh, | |
and you set weights for single joint, single vertex. | |
2. set "enable_bug_and_crash_maya" to True and rerun script - might need few reruns of the script. | |
Eventually, maya crashes. | |
""" | |
# set this to true to enable part of setup that breaks Maya | |
enable_bug_and_crash_maya = False | |
from maya import cmds | |
import maya.api.OpenMaya as om | |
import maya.api.OpenMayaAnim as omanim | |
def rebind_with_matrix(joint, skinCluster, index): | |
""" | |
simple helper to insert two inverseMatrix nodes between a joint and a skin cluster | |
""" | |
cmds.disconnectAttr(joint + ".worldMatrix[0]", skinCluster + ".matrix[%d]" % index) | |
m1 = cmds.createNode("inverseMatrix") | |
m2 = cmds.createNode("inverseMatrix") | |
cmds.connectAttr(joint + ".worldMatrix[0]", m1 + ".inputMatrix") | |
cmds.connectAttr(m1 + ".outputMatrix", m2 + ".inputMatrix") | |
cmds.connectAttr(m2 + ".outputMatrix", skinCluster + ".matrix[%d]" % index) | |
# SETUP SCENE: make new file with poly plane skinned to a joint | |
cmds.file(new=True, f=True) | |
cmds.polyPlane(name="testMesh", ch=False, w=12, h=12, sw=10, sh=10, cuv=2)[0] | |
cmds.select(cl=True) | |
cmds.joint() | |
cmds.joint() | |
cmds.joint() | |
skinCluster = cmds.skinCluster("joint1", "joint2", "joint3", "testMesh", toSelectedBones=True)[0] | |
if enable_bug_and_crash_maya: | |
# for first joint, reconnect in skin cluster j0->inverseMatrix->inverseMatrix->skinCluster | |
rebind_with_matrix("joint1", skinCluster, 0) | |
# convert things to API world | |
meshDagPath = om.MGlobal.getSelectionListByName("testMesh").getDagPath(0) | |
clusterFn = omanim.MFnSkinCluster(om.MGlobal.getSelectionListByName(skinCluster).getDependNode(0)) | |
# SET WEIGHTS: single joint, single vertex | |
comp = om.MFnSingleIndexedComponent() | |
verts = comp.create(om.MFn.kMeshVertComponent) | |
comp.addElement(0) | |
influences = om.MIntArray([0]) | |
weights = om.MDoubleArray([0.1]) | |
clusterFn.setWeights(meshDagPath, verts, influences, weights) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment