10

This might be a rather complex question since it's possible a lot of you don't know the software that I'm writing it for: Autodesk Maya 2011. I am trying to speed up a tedious slow process (rigging: giving 3d characters the ability to move) by writing a script that does it automatically.

I'll try my best to explain the situation.

I have a script that takes an object, iterates through the children of that object, stores them in a list, then puts the initial object at the end of the list, reverses the list because it's the wrong way around, then puts the initial object at the front.

Issue: There are three different lists all of the same object TYPE but with different names and they are actually different objects. My goal is to connect them together by generating nodes called 'blendcolors'. But if I have a loop to generate them for each object in list A, then I need loops that also connect them to the objects in other lists and I can not figure this out.

Here is my code, it has been played with so is more incomplete than before as far as the actual loop goes.

    import maya.cmds as cmds

    def crBC(IKJoint, FKJoint, bindJoint, xQuan, switch):

        # gets children joints of the selected joint
        chHipIK = cmds.listRelatives(IKJoint, ad = True, type = 'joint')
        chHipFK = cmds.listRelatives(FKJoint, ad = True, type = 'joint')
        chHipBind = cmds.listRelatives(bindJoint, ad = True, type = 'joint')
        # list is built backwards, this reverses the list
        chHipIK.reverse()
        chHipFK.reverse()
        chHipBind.reverse()
        # appends the initial joint to the list
        chHipIK.append(IKJoint)
        chHipFK.append(FKJoint)
        chHipBind.append(bindJoint)
        # puts the last joint at the start of the list because the initial joint
        # was added to the end
        chHipIK.insert(0, chHipIK.pop())
        chHipFK.insert(0, chHipFK.pop())
        chHipBind.insert(0, chHipBind.pop())


        # pops off the remaining joints in the list the user does not wish to be blended
        chHipBind[xQuan:] = []

        chHipIK[xQuan:] = []

        chHipFK[xQuan:] = []

       # goes through the bind joints, makes a blend colors for each one, connects
       # the switch to the blender

        for a in chHipBind


            rotBC = cmds.shadingNode('blendColors', asUtility = True, n = a + 'rotate_BC')
            tranBC = cmds.shadingNode('blendColors', asUtility = True, n = a + 'tran_BC')
            scaleBC = cmds.shadingNode('blendColors', asUtility = True, n = a + 'scale_BC')

            cmds.connectAttr(switch + '.ikFkSwitch', rotBC + '.blender')
            cmds.connectAttr(switch + '.ikFkSwitch', tranBC + '.blender')
            cmds.connectAttr(switch + '.ikFkSwitch', scaleBC + '.blender')

        # goes through the ik joints, connects to the blend colors

            for b in chHipIK:
                cmds.connectAttr(b + '.rotate', rotBC + '.color1')
                cmds.connectAttr(b + '.translate', tranBC + '.color1')
                cmds.connectAttr(b + '.scale', scaleBC + '.color1')


            # connects FK joints to the blend colors

            for c in chHipFK:
                cmds.connectAttr(c + '.rotate', rotBC + '.color2')
                cmds.connectAttr(c + '.translate', tranBC + '.color2')
                cmds.connectAttr(c + '.scale', scaleBC + '.color2')

        # connects blend colors to bind joints


            cmds.connectAttr(rotBC + '.output', d + '.rotate')
            cmds.connectAttr(tranBC + '.output', d + '.translate')
            cmds.connectAttr(scaleBC + '.output', d + '.scale')                






    # executes function


    crBC('L_hip_IK', 'L_hip_FK', 'L_hip_JNT', 6, 'L_legSwitch_CTRL')
Jared
  • 537
  • 2
  • 6
  • 14

4 Answers4

32

I do not quite understand the question, are you looking for

import itertools
for a, b, c in itertools.izip(lst1, lst2, lst3):
    ...

?

What izip does is it takes a variable number of arguments and returns an iterator that always yields the respective items of the arguments (a tuple of the first arguments in the first run, a tuple of the second arguments in the second run, and so on and so forth).

Florian Mayer
  • 3,041
  • 24
  • 17
  • 4
    `zip()` in python3 is also doing the same now and `izip` no longer exists. – Keivan Sep 14 '20 at 13:50
  • NOTE: If the lists are not equal size, `zip` will stop when the shortest list is exhausted. [Source](https://docs.python.org/3/library/functions.html#zip). – young_souvlaki Nov 07 '22 at 20:06
2

Python3 answer:

for a, b, c in zip(lst1, lst2, lst3):
    ...
Rexcirus
  • 2,459
  • 3
  • 22
  • 42
1

@florian mayer way with zip or izip works really fine, but you can also use the enumerate to get the list count,

list_a  = ["x", "y"]
list_b  = ["k", "j"]
list_c  = ["m", "n"]

for count, item in enumerate(list_a):
    print item, list_b[count], list_c[count]
Ari Gold
  • 1,528
  • 11
  • 18
  • I agree with you, even though I would name the first indexing variable "idx" or something similar instead of "count". Count sounds rather like an aggregated variable to me – Ursin Brunner Feb 15 '19 at 07:45
1

Why are there "There are three different lists all of the same object TYPE"? Why can't this be fixed to create one list, where all three objects are matched correctly?

Odds are good that a simple mapping would be better than three parallel lists.

Specifically, you need to fix chHipIK = cmds.listRelatives(IKJoint, ad = True, type = 'joint') to work like this.

chHipIK = [ { 'IK': ik } for ik in mds.listRelatives(IKJoint, ad = True, type = 'joint') ]
for i, fk in enumerate(cmds.listRelatives(FKJoint, ad = True, type = 'joint')):
    chHipIK[i]['FK']= fk
for i, bind in enumerate(cmds.listRelatives(bindJoint, ad = True, type = 'joint')):
    chHipIK[i]['FK']= bind

So that chHipIK is a list of mappings that has all three pieces of information.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • Hi there, maybe I'm doing it wrong but this doesn't work for me, there could be any number of joints in the joint chain, so I can't specify which ones for it to connect if I have one list. I tried appending to a master list and just using list[1] etc. but same problem. I really am new to python, only had a week. Just for the record, no such command as update relatives in maya hence my hapdash method of just appending to a master list, I hope you can think of another way because I'm totally lost... :) – Jared Jun 27 '11 at 19:45
  • @Jared: A list of mappings is not appending to one master list. In this case, you'll need to write your own update loop. – S.Lott Jun 27 '11 at 19:46