Maya: соедините две объединенные цепи родительским ограничением - PullRequest
0 голосов
/ 24 апреля 2020

Итак, вот фрагмент IK позвоночника, над которым я работал. Я выяснил, как сделать списки для дублирования границы в цепочку IK, но я застрял на том, что я хочу, чтобы мой список и для l oop родительское ограничение каждого соединения в иерархии привязок соответствовало своему соединению в иерархии ik:

    import maya.cmds as cmds

def linkJointChain(lookFor='joint'):
    namePref = 'ct_'
    limbPref = 'spine'
    ctlName = namePref + limbPref

    #list selection to get the joint and their children
    root = cmds.ls(sl=True)[0] # adding a zero bracket makes sure it counts the head of the herarchy too
    child = cmds.listRelatives(root,ad=1,type='joint')
    child.append(root)
    child.reverse()
    limbJnt = child
    print(child)

    #list all joints in chain, this list will be refrenced by all the commands beneath it
    root = cmds.ls(sl=True)[0]
    child = cmds.listRelatives(root,ad=1,f=True,children=True,type='joint')

    #rename the joints
    for 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 respectivly
    root = 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 spine
    root = 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 chain
        cmds.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 spine
    ikJntChain=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 append
    ikJntChain.reverse()
    ikLimbJnt = ikJntChain

    boundJntChain=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 append
    boundJntChain.reverse()
    boundLimbJnt = boundJntChain

    limbJnt = ikJntChain+boundJntChain

    print(limbJnt)

    for j in limbJnt:
        spineCons = cmds.parentConstraint(ikJntChain[0],boundJntChain[0])
        #ikParChain = cmds.parentConstraint(j,ikJntChain)

linkJointChain()

сценарий имеет жестко закодированные имена для listRelatives, поскольку полный сценарий считывает цепочку соединений и размещает элементы управления в начале и конце соединения после переименования первого и последнего соединений в списке, Я знаю, что это как-то связано с скобками в cmds.parentConstraint

1 Ответ

0 голосов
/ 24 апреля 2020

Вот пример, который создаст 2 отдельные цепочки соединений с нуля, затем применяет родительское ограничение к каждому соединению, так что одна цепочка управляет другим:

import maya.cmds as cmds

joint_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

Основная идея состоит в том, что вы получаете 2 списка у каждого свои суставы. Затем вы передаете эти 2 списка в zip, так что когда вы выполняете итерацию по нему, он сначала go пройдет через оба 1-го соединения, затем через 2-е соединение и т. Д.

Чтобы заставить это работать правильно вы должны убедиться, что оба списка имеют одинаковую длину, и оба используют один и тот же общий порядок. Таким образом, вам не нужно ничего кодировать жестко, вместо этого вы можете сделать это процедурно (например, вы можете изменить joint_count на любое число, и оно все равно будет работать).

На самом деле вам даже не нужно использовать zip и можно достичь того же, заменив окончание следующим образом:

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

Хотя использование zip вызывает больше «pythoni c».

...