Skip to content

Instantly share code, notes, and snippets.

@viktorasm
Created August 14, 2020 16:57
Show Gist options
  • Save viktorasm/0744a5f499fc7e5f4ad64cf089caa430 to your computer and use it in GitHub Desktop.
Save viktorasm/0744a5f499fc7e5f4ad64cf089caa430 to your computer and use it in GitHub Desktop.
A bug in Autodesk Maya API
"""
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