Skip to content

Instantly share code, notes, and snippets.

@BigRoy
Created October 19, 2022 18:44
Show Gist options
  • Save BigRoy/8f73bf4aa96bf9a1c99986aad873ec6a to your computer and use it in GitHub Desktop.
Save BigRoy/8f73bf4aa96bf9a1c99986aad873ec6a to your computer and use it in GitHub Desktop.
Create a pre bind matrix joint for skincluster for selected joints to tweak the pre bind matrix easily
import re
from maya import cmds
import maya.api.OpenMaya as om
def nodename(n):
return n.rsplit("|", 1)[-1].rsplit(":", 1)[-1]
for joint in cmds.ls(type="joint", sl=True):
jointname = nodename(joint)
destinations = cmds.listConnections(joint + ".worldMatrix", source=False, destination=True, plugs=True, type="skinCluster") or []
for destination in destinations:
skin, attr = destination.split(".", 1)
match = re.search(r"^matrix\[(\d+)\]$", attr)
if not match:
continue
index = int(match.group(1))
# Get the bindPreMatrix for that influence index
bind_prematrix_plug = f"{skin}.bindPreMatrix[{index}]"
bind_prematrix = cmds.getAttr(bind_prematrix_plug)
if bind_prematrix is None:
# Can happen if the value is not initialiezd - if so
# assume the current joints position
bind_prematrix = cmds.xform(joint, query=True, worldSpace=True, matrix=True)
bind_prematrix = om.MMatrix(bind_prematrix).inverse()
bind_prematrix_inv = om.MMatrix(bind_prematrix).inverse()
bind_prematrix_inv = list(bind_prematrix_inv)
# Create matching prebind joint as input
bind_prematrix_joint = cmds.createNode("joint", name=f"{jointname}_bindPreMatrix_for_{skin}")
cmds.xform(bind_prematrix_joint, worldSpace=True, matrix=bind_prematrix_inv)
cmds.connectAttr(bind_prematrix_joint + ".worldInverseMatrix[0]", bind_prematrix_plug)
@BigRoy
Copy link
Author

BigRoy commented Oct 19, 2022

Deleting or disconnecting the bindPreMatrix joints that are created will clear the bindPreMatrix value instead of persisting them for the skincluster. As such, we'll need to disconnect and set the value explicitly. Here's a trivial way to do so after using the script above:

from maya import cmds

def pairwise(iterable):
    it = iter(iterable)
    return zip(it, it)


for skin in cmds.ls(type="skinCluster"):
    connections = cmds.listConnections(skin + ".bindPreMatrix", source=True, destination=False, connections=True, plugs=True) or []
    for dest, src in pairwise(connections):
        value = cmds.getAttr(dest)
        cmds.disconnectAttr(src, dest)
        cmds.setAttr(dest, value, type="matrix")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment