Add Parent Switch

Download addParentSwitch.py

python, pyfuncs, maya

This function creates a parentConstraint on the object's parent and add an enum list attribute on the object, so you can switch the parenting of your node easily, can be useful in a rig to add some switches for the hands' parent for instance.
You can use it this way ;

1
2
3
4
object  = cmds.ls(sl=True)[0]        # first object will be the target
parents = cmds.ls(sl=True)[1:]       # all the others  will be parents
ordered = ['Parent to %s' % p for p in parents]        # order example
add_parent_switch(object, 'Whosyourdaddy', parents, order=ordered)

This will add an Enumerate Attribute named Whosyourdaddy on the first object selected, all the other objects will be the potential parents, or simply

1
2
sel  = cmds.ls(sl=True)
add_parent_switch(sel[0], 'Whosyourdaddy', sel[1:])

You'll get ;


Full code here ;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def add_separator(obj, name=''):
    """
    Creates a separator attribute then lock it
    :param  obj: object to add the separator on
    :param name: name of the separator
    """
    cmds.addAttr(obj, ln='sep' + name, nn=name, at='enum',
                  en='_____', h=False, k=False)
    cmds.setAttr('%s.%s' % (obj, 'sep' + name), e=True, k=True, l=True)


def add_parent_switch(node, name, targets, separator=True, order=None, redirect=None):
    """
    Creates a parentConstraint and an enum attribute to switch the parenting of a
    node
    :param      node: object's parent will get the parentConstraint
    :param      name: name of the parenting attribute
    :param   targets: list of parents
    :param separator: if set will create a separator attr above this one
    :param     order: if provided will override the parent's name for the enum attr
    :param  redirect: will create the attribute on another object
    :return         : returns the parentAttribute if ever you need it
    """
    try:
        ctrl = cmds.listRelatives(node, p=True)[0]
    except TypeError:
        cmds.warning('Object must have at least one parent, maybe a zero ?')
        return 0
    name = name.replace(' ', '')
    if redirect:
        node = redirect
    if separator:
        add_separator(node, '%s_Parent' % name)
    enums = ':'.join(order if order else targets)
    cmds.addAttr(node, ln='%sParent' % name, nn=name, at='enum', en=enums, dv=0,
        h=False, k=True)

    order = order if order else [i for i in range(len(targets))]

    inf = [targets[i] for i, p in enumerate(order)]
    for p in range(len(order)):
        pc = cmds.parentConstraint(targets[p], ctrl, mo=True, w=1.0)[0]
    cmds.setAttr('%s.interpType' % pc, 2)
    for i in range(len(order)):
        cond = cmds.shadingNode('condition', au=True,
                           n='cond_%sParent_m_%s' % (name, inf[i]))
        cmds.connectAttr('%s.%sParent' % (node, name), '%s.ft' % cond, f=True)
        cmds.setAttr('%s.st' % cond, i)
        cmds.setAttr('%s.cf.cfr' % cond, 0)
        cmds.setAttr('%s.ct.ctr' % cond, 1)
        cmds.connectAttr('%s.oc.ocr' % cond, '%s.%sW%d' % (pc, inf[i], i), f=True)
    cmds.select(node)
    return '%s.%sParent' % (node, name)

If you have any questions... =)