Maya: Connect two Joint chains with Parent Constraint

2024/10/5 22:25:26

So here is a snipit of an IK spine builder I've been working on. I've figure out how to make lists to duplicate the bound into an IK chain, what I've got stuck on however is I want my list and for loop to parent constraint each joint in the bound hierarchy to it's corresponding joint in the ik hierarchy:

    import maya.cmds as cmdsdef linkJointChain(lookFor='joint'):namePref = 'ct_'limbPref = 'spine'ctlName = namePref + limbPref#list selection to get the joint and their childrenroot = cmds.ls(sl=True)[0] # adding a zero bracket makes sure it counts the head of the herarchy toochild = cmds.listRelatives(root,ad=1,type='joint')child.append(root)child.reverse()limbJnt = childprint(child)#list all joints in chain, this list will be refrenced by all the commands beneath itroot = cmds.ls(sl=True)[0]child = cmds.listRelatives(root,ad=1,f=True,children=True,type='joint')#rename the jointsfor j, name in enumerate(child):cmds.rename(name,namePref + limbPref + 'AJ{0}_BIND_JNT'.format(len(child)-j))print(child)#rename beggining and end joints to start and end respectivlyroot = cmds.ls(sl=True)child = cmds.listRelatives(root,ad=1,f=True,children=True,type='joint')cmds.rename(child[0],ctlName +'AJ_BIND_END_JNT')cmds.rename(root,ctlName + 'AJ_BIND_START_JNT')#duplicate bound chain for ik spineroot = cmds.ls(sl=True)IKChain = cmds.duplicate(root,n=ctlName + 'AJ_IK_START_JNT')IKList = cmds.listRelatives(ctlName + 'AJ_IK_START_JNT', ad=True,pa=True)for IKn, name in enumerate(IKList):cmds.rename(name, ctlName +'AJ{0}_IK_JNT'.format(len(IKList)-IKn))print(IKList)#select IK chain, then,set joints size for easy grabbing on IK chaincmds.select(ctlName +'AJ_IK_START_JNT')IKRoot = cmds.ls(sl=True)[0] IKChild = cmds.listRelatives(ctlName +'AJ_IK_START_JNT', ad=True,pa=True)IKChild.append(IKRoot)for r in IKChild:cmds.setAttr(r + '.radius', 1.5)#parent constrain bound spine to ik spineikJntChain=cmds.listRelatives(ctlName +'AJ_IK_START_JNT',ad=1,type='joint')ikJntChain.append(ctlName +'AJ_IK_START_JNT') #try appending your other joint chain to create a double list with which to appendikJntChain.reverse()ikLimbJnt = ikJntChainboundJntChain=cmds.listRelatives(ctlName +'AJ_BIND_START_JNT',ad=1,type='joint')boundJntChain.append(ctlName +'AJ_BIND_START_JNT') #try appending your other joint chain to create a double list with which to appendboundJntChain.reverse()boundLimbJnt = boundJntChainlimbJnt = ikJntChain+boundJntChainprint(limbJnt)for j in limbJnt:spineCons = cmds.parentConstraint(ikJntChain[0],boundJntChain[0])#ikParChain = cmds.parentConstraint(j,ikJntChain)linkJointChain()

the script has hardcoded names for the listRelatives because the full script reads the joint chain and places controls at the start and end joint after renaming the first and last joints in the list, I know it has something to do with the brackets in cmds.parentConstraint

Answer

Here's an example that will create 2 separate joint chains from scratch, then applies a parent constraint to each joint so that one chain drives the other:

import maya.cmds as cmdsjoint_count = 10# Create 1st joint chain 'a'.
chain_a = [cmds.joint(position=[0, i * -2 + ((joint_count - 1) * 2), 0], name="a#")for i in range(joint_count)]cmds.select(clear=True)  # Need to clear selection so the next chain doesn't accidentally parent to chain a.# Create 2nd joint chain 'b'.
chain_b = [cmds.joint(position=[0, i * -2 + ((joint_count - 1) * 2), -10], name="b#")for i in range(joint_count)]# Use `zip` to iterate through both lists at the same time.
for jnt_a, jnt_b in zip(chain_a, chain_b):cmds.parentConstraint(jnt_a, jnt_b, maintainOffset=True)  # Constraint b->a

The main idea is that you get 2 lists each with their own joints. You then pass those 2 lists to zip, so that when you iterate through it, it will first go through both 1st joints, then both 2nd joints, and so on.

To get this to work correctly you must make sure both lists have the same length, and both are using the same joint order. That way you don't have to hard-code anything and instead can do it procedurally (for example you can change joint_count to whatever number and it will still work).

You actually don't even need to use zip and can achieve the same thing by replacing the ending like this:

for i in range(len(chain_a)):cmds.parentConstraint(chain_a[i], chain_b[i], maintainOffset=True)  # Constraint b->a

Though using zip feels more 'pythonic'.

https://en.xdnf.cn/q/119021.html

Related Q&A

What is the equivalent for onkeydown and onkeyup (Javascript events) in python?

There are events called onkeydown and onkeyup in Javascript. Can anyone please suggest the python equivalent of it?

Matching number string pairs

I have the following sample string:R10666: 273141 C1 + 273141 C2 + 273141 C3 + 273141 C4 + 273141 C5 - 273141 C6I want to obtain:[(273141,C1), ..., (- 273141, C6)]The numbers can be floating point numb…

Turning a text file into a tabular format [duplicate]

This question already has answers here:How do I print parameters of multiple objects in table form? [duplicate](2 answers)Line up columns of numbers (print output in table format)(7 answers)Closed 5 y…

Python: Read file with list as list

I have placed a list in a text file. I want python to read the text file and return the contents as a list. However, it is instead reading the content as a string:Text file:[a,b,c]Python:ids=[]writtenF…

Tkinter scrollbar not scrollable

I followed some tutorial on attaching a scrollbar to a textbox. However, in the tutorial, the scrollbar is really a "bar". When I tried myself, I can only press the arrows to move up or down,…

How to create multiple roles through discord.py bot?

I have been trying to make my discord bot create multiple roles through a command. But it simply doesnt work. Here is what I have done so far: @commands.command()async def create_roles(self, ctx):guild…

python: how do i know when i am on the last for cycle

for i in range(len(results_histogram)):if i!=len(results_histogram)-1:url+=str(results_histogram[i])+,my if statement is checking whether i am on the last loop, but it is not working. what am i doing w…

scrape text in python from https://brainly.co.id/tugas/148

scrape "Jawaban terverifikasi ahli" in green box from the url https://brainly.co.id/tugas/148, possibly the color of green tick icon to the left of it also(tag <use xlink:href="#icon-…

Percentage of how similar strings are in Python? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic…

A Python dictionary with repeated fields

Im constructing a dictionary with Python to use with a SOAP API.My SOAP API takes an input like this:<dataArray><AccountingYearData><Handle><Year>string</Year></Handle&…