Exemple #1
0
    def create_ctrls(self, i, cv_loc):
        pmc.select(cl=1)
        ctrl_shape = pmc.circle(c=(0, 0, 0),
                                nr=(0, 1, 0),
                                sw=360,
                                r=3,
                                d=3,
                                s=8,
                                n="{0}_{1}_fk_CTRL_shape".format(
                                    self.model.module_name, (i + 1)),
                                ch=0)[0]
        ctrl = rig_lib.create_jnttype_ctrl(name="{0}_{1}_fk_CTRL".format(
            self.model.module_name, (i + 1)),
                                           shape=ctrl_shape,
                                           drawstyle=2,
                                           rotateorder=1)

        nearest_point_on_curve = pmc.createNode("nearestPointOnCurve",
                                                n="temp_NPOC")
        self.guides[1].worldSpace >> nearest_point_on_curve.inputCurve
        cv_loc.getShape().worldPosition >> nearest_point_on_curve.inPosition
        ctrl.setAttr("translate", nearest_point_on_curve.getAttr("position"))
        # nearest_point_on_curve.position >> ctrl.translate
        pmc.delete(nearest_point_on_curve)

        # ctrl.setAttr("translate", pmc.xform(cv_loc, q=1, ws=1, translation=1))
        if i == 0:
            pmc.parent(ctrl, self.ctrl_input_grp, r=0)
        else:
            pmc.parent(ctrl,
                       "{0}_{1}_fk_CTRL".format(self.model.module_name, i),
                       r=0)
            pmc.reorder(ctrl, front=1)
        pmc.parent(cv_loc, ctrl, r=0)
        self.created_fk_ctrls.append(ctrl)
Exemple #2
0
def reorder_outliner_nicely():
    # reorder the hierarchy so cameras are on top. Otherwise there is a
    # dumb bug where it is harder to select the top node in the outliner.
    #TODO: Fix this to work generically. Just move cameras to top
    return False
    for each in [x.getParent() for x in pm.ls(type='camera')
                 ] + [pm.PyNode('root')] + sandbox:
        pm.reorder(each, back=True)
Exemple #3
0
def reorder_sel(alphabet=False):
    sel = pm.ls(sl=True)

    # Reorder selection alphabetically
    if alphabet:
        sel = sorted(sel)

    # Reorder
    for each in sel:
        pm.reorder(each, back=1)
Exemple #4
0
def addShapeToTrans(shape, transform):
    """Add a shape to a transform node, and make it appear at the top of other shapes
    in the channel box. DOES NOT remove the shape from its current transform -
    shapes can have any number of  transforms of this kind. Args:
    - shape: the shape node to be added.
    - transform: the transform to receive the shape as an input."""
    shape.setParent(transform, add=True, shape=True)
    # shape is explicitly under original transform,
    # so to reorder need the lastest shape under ctrl
    ctrlShape = transform.getShapes()[-1]
    pmc.reorder(ctrlShape, front=True)
    print("Successfully added {0} to {1}".format(shape, transform))
Exemple #5
0
def setInOrder():
    objs = pm.listRelatives(ad=True, typ='joint')
    objs += pm.listRelatives(ad=True, typ='transform')
    objs += pm.ls(sl=True)
    num_list = []
    for obj in objs:
        num_list.append(int(re.sub(r"[^0-9]", "", obj.name())))
    for x in range(min(num_list), max(num_list)+1):
        for y in range(len(num_list)):
            if x == num_list[y]:
                pm.reorder(objs[y], b=True)
                break
Exemple #6
0
def create_renderMesh(ob, bsName='BodyBS'):
    if '_' in ul.get_name(ob):
        dupOb = ob.duplicate(name="_".join(ul.get_name(ob).split('_')[:-1]))
        for child in dupOb[0].listRelatives(ad=True):
            child.rename(name="_".join(ul.get_name(child).split('_')[:-1]))
        pm.reorder(dupOb[0], f=True)
    try:
        pm.delete(bsName)
    except pm.MayaNodeError:
        pass
    finally:
        pm.blendShape(ob, dupOb, name=bsName)
def addFKIKSwitchToCtrl(ctrl, shape=None, name="FK_IK_Switcher"):
	if not shape:
		# create the thing if it's not passed in
		l = pmc.spaceLocator(n=name)
		shape = l.getShape()
		shape.setAttr("visibility", False)
		for a in shape.listAttr(cb=True):
			a.set(channelBox=False)
		shape.addAttr("FK_IK_Switch", at="float", 
						keyable=True, min=0, max=1.0)
	new = shape.setParent(ctrl, add=True, shape=True)
	# shape is explicitly under original transform,
	# so to reorder need the lastest shape under ctrl
	ctrlShape = ctrl.getShapes()[-1]
	pmc.reorder(ctrlShape, front=True)
	
	return shape
Exemple #8
0
def reorder_outliner( objs ):
    '''
    Usage:
        reorder_outliner( pm.ls(sl=True) )
    '''
    for obj in objs:
        index_desired = detect_number( obj )
        siblings = obj.getParent().listRelatives( f = True, c = True, type = ['transform', 'shape'] )
        index_current = siblings.index( obj )
        index_diff = abs( index_current - index_desired )
        if index_desired < index_current:
            index_shift = -index_diff 
        if index_desired > index_current:
            index_shift = index_diff
        if index_desired == index_current:
            index_shift = 0
        pm.reorder( obj, relative=(index_shift-1) )
Exemple #9
0
def reorder_outliner(objs):
    """
    Usage:
        reorder_outliner( pm.ls(sl=True) )
    """
    for obj in objs:
        index_desired = detect_number(obj) - 1
        siblings = obj.getParent().listRelatives(f=True, c=True, type=["transform"])
        # print [sibling.name() for sibling in siblings]
        index_current = siblings.index(obj)
        index_shift = abs(index_current - index_desired)

        if index_desired < index_current:
            index_shift *= -1

        # print obj.name(), index_current, index_desired, index_shift
        pm.reorder(obj, relative=index_shift)
        pm.reorder(siblings[index_desired], relative=index_shift * -1)
    def makeRigid(self):
        """Rigid SetUp """
        selection = pm.selected()

        def makeCloth_node(msh):
            pm.select(msh)
            pm.mel.makeCollideNCloth()
            rigid = pm.rename('nRigid1', msh.split('cloth')[0] + '__nRigid__')
            pm.parent(rigid, pm.PyNode(msh).getParent())
            pm.select(None)
            return rigid

        all_rigid = []
        for each in selection:
            rigid = makeCloth_node(each)
            all_rigid.append(rigid)

        for sel, rigid in zip(selection, all_rigid):
            pm.reorder(sel, back=True)
            pm.reorder(rigid, back=True)
    def makeCloth(self):
        """cloth SetUp """
        selection = pm.selected()

        def makeCloth_node(msh):
            pm.select(msh)
            pm.mel.createNCloth(0)
            cloth = pm.rename('nCloth1', msh.split('cloth')[0] + '__ncloth__')
            pm.parent(cloth, pm.PyNode(msh).getParent())
            pm.select(None)
            return cloth

        all_cloth = []
        for each in selection:
            cloth = makeCloth_node(each)
            all_cloth.append(cloth)

        for sel, cloth in zip(selection, all_cloth):
            pm.reorder(sel, back=True)
            pm.reorder(cloth, back=True)
Exemple #12
0
def reorder_collection(oColl):
    for each in oColl:
        pm.reorder(each, back=True)
Exemple #13
0
def rigLimbCmd( prefix='leg_', suffix=None, side=LEFT_SIDE, hasStretch=False, hasFootRoll=False, footRollMode=FOOTROLL_AUTO ):

    suffix = suffix or ('_l','_r')[side]
    exp_template = ""

    labels = {
        'control'      : prefix + 'control' + suffix,
        'aimControl'   : prefix + 'aim'  + suffix,
        'ik'           : prefix + 'ik' + suffix,
        'ikEnd'        : prefix + 'ik_end' + suffix,
        'expression'   : prefix + 'control' + suffix + '_EXP',

        'guideJointIk' : prefix + 'ik_guide_',
        'guideJoint'   : prefix + 'guide_',
        'ikStretch'    : prefix + 'ik_stretch' + suffix,
        'locStart'     : prefix + 'loc_start' + suffix,
        'locMid'       : prefix + 'loc_mid' + suffix,
        'locEnd'       : prefix + 'loc_end' + suffix,
        'locGuide'     : prefix + 'loc_guide' + suffix,
        'ikGuide'      : prefix + 'ik_guide' + suffix,
    }


    try:
        start_joint, end_joint = pm.ls(sl=1,type="joint")
    except ValueError:
        raise ValueError, "Select the start and end joints to setup."

    mid_joint = end_joint.getParent()
    parent_joint = start_joint.getParent()

    unit_scale = start_joint.getRotatePivot(ws=1)[-1]

    # -- positions and length

    start_point = start_joint.getRotatePivot(ws=1) * unit_scale
    end_point =   end_joint.getRotatePivot(ws=1) * unit_scale
    mid_point =   mid_joint.getRotatePivot(ws=1) * unit_scale
    length =      start_point.distanceTo( end_point )

    # -- Create Control

    control = createNurbsShape( labels['control'], 'sphere', size=length*.2 )
    control2 = createNurbsShape( labels['control'], 'locator', size=length*.3 )
    pm.parent( control2.getShape(), control, r=1, s=1 )
    pm.delete( control2 )
    control.translate.set( end_point )

    pm.makeIdentity( control, apply=True, s=0, r=0, t=1, n=0 )

    control.addAttr( "ikBlend", at='double', k=1, dv=0, min=0, max=1 )
    control.addAttr( "orientBlend", at='double', k=1, dv=0, min=0, max=1 )

    # -- Create Aim Control

    v1 = end_point - start_point
    v2 = mid_point - start_point
    v3 = v1.cross( v2 )
    v4 = v3.cross( v1 )
    aim_point = start_point + ( v4.normal() * length * 1.5 )

    aim_control = createNurbsShape( labels['aimControl'], 'arrow', size=length/5 )
    pm.xform( aim_control, t=aim_point )
    pm.makeIdentity( apply=True, s=0, r=0, t=1, n=0 )

    pm.aimConstraint(  mid_joint, aim_control, weight=1, aimVector=(0, 0, 1) )

    # -- Create Aim Line

    aim_line = pm.curve( name=labels['aimControl']+'_line', d=1, p=[aim_point, mid_point], k=[0, 1] )

    line_cluster0, line_handle0 = pm.cluster( aim_line+'.cv[0]', n=labels['aimControl']+'_line_0', en=1, rel=1 )
    line_cluster1, line_handle1 = pm.cluster( aim_line+'.cv[1]', n=labels['aimControl']+'_line_1', en=1, rel=1 )

    pm.pointConstraint( aim_control, line_handle0, offset=(0,0,0), weight=1 )
    pm.pointConstraint( mid_joint, line_handle1, offset=(0,0,0), weight=1 )

    line_group0 = pm.group( line_handle0, name=line_handle0.name() + "_grp" )
    line_group1 = pm.group( line_handle1, name=line_handle0.name() + "_grp" )

    pm.parent( [aim_line,
                line_group0,
                line_group1,
                aim_control] )

    line_group0.v.set(0)
    line_group1.v.set(0)
    setAttrs( line_group0, ['t','r','s','v'], lock=1 )
    setAttrs( line_group1, ['t','r','s','v'], lock=1 )

    setAttrs( aim_line, ['t','r','s','v'], lock=1 )

    aim_line.overrideEnabled.set(1)
    aim_line.overrideDisplayType.set(1)


    if hasStretch:
        guide_ik_start = pm.duplicate( start_joint, rc=1 )[0]
        guide_ik_mid, guide_ik_end = pm.ls( guide_ik_start, dag=1 )[1:3]

        for n in pm.ls( guide_ik_start, dag=1 ):
            pm.rename( n, labels['guideJointIk'] + n[:-1] )

        guide_start = pm.duplicate( start_joint, rc=1 )[0]
        guide_mid, guide_end = pm.ls( guide_start, dag=1 )[1:3]

        for n in pm.ls( guide_start, dag=1 ):
            pm.rename( n, labels['guideJoint'] + n[:-1] )


        parent_group = pm.group( name=labels['ikStretch'], em=1 )

        if parent_joint is not None:
            parent_group.setRotatePivot( parent_joint.getRotatePivot(ws=1) * unit_scale, ws=1 )
            pm.parentConstraint( parent_joint, parent_group, weight=1 )

        pm.parent( guide_ik_start, guide_start, parent_group )

        # -- build a temp joint chain to get loc_mid position

        loc_start = pm.group( n=labels['locStart'], em=1 )

        pm.parent( loc_start, parent_group )


        loc_start.setRotatePivot( start_joint.getRotatePivot( ws=1) * unit_scale, ws=1 )

        pm.aimConstraint( control, loc_start, weight=1, aimVector=(1,0,0) )

        loc_end = pm.group( n=labels['locEnd'], em=1, parent=loc_start )
        loc_end.setRotatePivot( start_joint.getRotatePivot( ws=1) * unit_scale, ws=1 )

        pm.pointConstraint( control, loc_end, offset=(0,0,0), skip=('y','z'), weight=1 )


        pm.select(cl=1)
        temp_start = pm.joint( p=start_point )
        temp_end = pm.joint( p=end_point )
        pm.joint( temp_start, edit=1, oj='xyz', secondaryAxisOrient='yup', ch=1 )
        pm.pointConstraint( mid_joint, temp_end, offset=(0,0,0), skip=('y','z'), weight=1 )

        loc_mid_point =   temp_end.getRotatePivot(ws=1) * unit_scale
        pm.delete( temp_start )

        # -- create the mid locator

        loc_mid = pm.group( n=labels['locMid'], em=1)#spaceLocator()
        loc_mid.translate.set( loc_mid_point )
        pm.makeIdentity( apply=True, s=0, r=0, t=1, n=0 )

        pm.pointConstraint( loc_start, loc_mid, mo=1, weight=1 )
        pm.pointConstraint( loc_end,   loc_mid, mo=1, weight=1 )

        # -- create the guide locator

        loc_guide = pm.group( n=labels['locGuide'], em=1)

        guide_constraint = pm.pointConstraint( loc_mid, loc_guide, offset=(0,0,0), weight=1 )
        pm.pointConstraint( guide_ik_mid, loc_guide, offset=(0,0,0), weight=1 )

        pm.parent( loc_mid, loc_guide, parent_group )

        guide_ik, guide_ee = pm.ikHandle( sj=guide_ik_start, ee=guide_ik_end, solver="ikRPsolver", dh=1 )
        pm.poleVectorConstraint( aim_control, guide_ik, weight=1 )
        pm.delete( guide_ik_end )

        pm.rename( guide_ik, labels['ikGuide'] )

        # -- SET STRETCH BLEND START

        guide_ik.addAttr( "stretchStart", at='double', k=1 )
        guide_ik.stretchStart.set( loc_end.tx.get() )

        # -- SET STRETCH BLEND END

        guide_ik.addAttr( "stretchEnd", at='double', k=1 )
        guide_ik.stretchEnd.set( loc_end.tx.get()*1.1 )

        # -- SET STRETCH BLEND END

        guide_ik.addAttr( "stretchFactor", at='double', k=1 )
        guide_ik.stretchFactor.set( 0.22 )


        # -- setup guide joints

        pm.aimConstraint( loc_guide, guide_start, weight=1, aimVector=(1,0,0) )
        pm.aimConstraint( loc_end, guide_mid, weight=1, aimVector=(1,0,0) )

        pm.pointConstraint( loc_guide, guide_mid, offset=(0,0,0), skip=('y','z'), weight=1 )
        pm.pointConstraint( loc_end, guide_end, offset=(0,0,0), skip=('y','z'), weight=1 )

        pm.parent( guide_ik, loc_end )
        pm.parent( guide_ik, control )

        # -- add stretch addtributes

        start_joint.addAttr( "stretch", at='double', k=1, dv=0 )
        mid_joint.addAttr( "stretch", at='double', k=1, dv=0 )


        control.addAttr( "stretchBlend", at='double', k=1, dv=0, min=0, max=1 )

        # -- build the expression

        exp_template += EXP_STRETCH \
        % { 'guide_ik'     : guide_ik,
            'loc_end'      : loc_end,
            'constraint'   : guide_constraint,

            # -- we only need these names for the constraint attribute names

            'guide_ik_mid' : guide_ik_mid.split('|')[-1],
            'loc_mid'      : loc_mid.split('|')[-1],

            'control'      : control,
            'start_joint'  : start_joint,
            'mid_joint'    : mid_joint,
            'end_joint'    : end_joint,
            'guide_mid'    : guide_mid,
            'guide_end'    : guide_end,
            }

        # -- make things look pretty

        for n in pm.ls( [ parent_group, guide_ik ], dag=1 ):
            n.visibility.set(0)

        for obj in guide_end.getChildren( type='joint' ):
            try:
                pm.delete( obj )
            except:
                pass


    # -- hook up the original joints

    main_ik, main_ee = pm.ikHandle( sj=start_joint, ee=end_joint, solver="ikRPsolver", dh=1 )
    pm.poleVectorConstraint( aim_control, main_ik, weight=1 )
    pm.rename( main_ik, labels['ik'] )

    end_ik, end_ee = pm.ikHandle( sj=end_joint, ee=end_joint.getChildren(type='joint')[0], solver="ikRPsolver", dh=1 )
    pm.rename( end_ik, labels['ikEnd'] )

    pm.parent( main_ik, end_ik, control )

    # -- fill out the expression template
    exp_template += EXP_IKFK + EXP_VIS

    exp_str = exp_template \
    % {
        #'guide_ik'     : guide_ik,
        #'loc_end'      : loc_end,
        #'constraint'   : guide_constraint,

        #we only need these names for the constraint attribute names
        #'guide_ik_mid' : guide_ik_mid.split('|')[-1],
        #'loc_mid'      : loc_mid.split('|')[-1],

        'control'      : control,
        'start_joint'  : start_joint,
        'mid_joint'    : mid_joint,
        'end_joint'    : end_joint,
        #'guide_mid'    : guide_mid,
        #'guide_end'    : guide_end,
        'main_ik'      : main_ik,
        'end_ik'       : end_ik,

        'shape1'       : control.getChildren(type="nurbsCurve")[0],
        'shape2'       : control.getChildren(type="nurbsCurve")[1],
        }

    pm.expression( s=exp_str, o=control, n=labels['expression'], a=1, uc='all' )

    if hasFootRoll:
        rigFootRoll( end_joint, control, prefix, suffix, side=side, footRollMode=footRollMode )

    resetIkSetupCmd(end_joint, control)
    resetIkSetupCmd(start_joint, aim_control)

    # -- make things look pretty

    for n in pm.ls( control, dag=1, type="transform" )[1:]:
        if n.type() != "transform":
            n.visibility.set(0)

    setAttrs( control, ['sx','sy','sz'], channelBox=0, keyable=0, lock=1 )
    setAttrs( aim_control, ['rx','ry','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 )
    pm.setAttr(control.v, keyable=0 )
    pm.setAttr(aim_control.v, keyable=0 )

    addToSet( [control, aim_control], 'controlsSet' )

    pm.select( [control, aim_control], r=1 )
    pm.color( ud=(CntlColors.left, CntlColors.right)[side] )

    control.displayHandle.set(1)
    pm.select( control, r=1 )

    pm.reorder( control.getShape(), back=1 )

    return [ control, aim_control ]
Exemple #14
0
def rigRootCmd( prefix='root_', seperate_rotation=False, rotate_prefix='pelvis_' ):

    labels = {
        'control' : prefix + 'control',
        'rotateControl' : rotate_prefix + 'control'
    }

    try:
        start_joint = pm.ls(sl=1,type="joint")[0]
    except ValueError:
        raise ValueError, "Select the root joint to setup."


    start_point = start_joint.getRotatePivot(ws=1) * start_joint.getRotatePivot(ws=1)[-1]

    control = pm.circle( n=labels['control'], radius=(start_point[1] / .035), normal=(0,1,0), ch=0 )[0]
    control2 =  createNurbsShape( labels['rotateControl'],
                                  width=( start_point[1] / .025),
                                  height=(start_point[1] / .045),
                                  depth=( start_point[1] / .035),
                                  )

    control.translate.set( start_point )
    control2.translate.set( start_point )

    if not seperate_rotation:
        pm.parent( control2.getShape(), control, r=1, s=1 )
        pm.delete( control2 )
    else:
        pm.parent( control2, control )
        pm.makeIdentity( control2, apply=True, s=0, r=0, t=1, n=0 )

    pm.makeIdentity( control, apply=True, s=0, r=0, t=1, n=0 )


    pm.pointConstraint(  control, start_joint, offset=(0,0,0), weight=1 )

    if not seperate_rotation:
        pm.orientConstraint( control, start_joint, weight=1, mo=1 )
    else:
        pm.orientConstraint( control2, start_joint, weight=1, mo=1 )


    control.displayHandle.set(1)
    addToSet( [control], 'controlsSet' )

    setAttrs( control, ['sx','sy','sz'], channelBox=0, keyable=0, lock=1 )
    pm.setAttr(control.v, keyable=0 )

    pm.select( control, r=1 )
    pm.color( ud=CntlColors.center )

    pm.reorder( control.getShape(), back=1 )

    if seperate_rotation:
        addToSet( [control2], 'controlsSet' )

        setAttrs( control2, ['t','s'], channelBox=0, keyable=0, lock=1 )
        pm.setAttr(control2.v, keyable=0 )

        pm.select( control2, add=1 )
        pm.color( ud=CntlColors.center )


    return pm.ls(sl=1)
Exemple #15
0
def rigFootRoll( foot_joint, control, prefix, suffix=None, side=LEFT_SIDE, footRollMode=FOOTROLL_AUTO ):

    suffix = suffix or ('_l','_r')[side]
    exp_template = ""

    labels = {
        'expression'   : prefix + 'control' + suffix + '_EXP',
        'ikToe'        : prefix + 'ik_toe' + suffix,
        'pivotBall'    : prefix + 'pivot_ball' + suffix,
        'pivotToe'     : prefix + 'pivot_toe' + suffix,
        'rotateToe'    : prefix + 'rotate_toe' + suffix,
        'pivotHeel'    : prefix + 'pivot_heel' + suffix,
    }

    handles = control.getChildren(type='ikHandle')
    if len(handles) == 3:
        guide_ik, main_ik, end_ik = handles
    else:
        main_ik, end_ik = handles
        guide_ik = None

    toe_joint, heel_joint = foot_joint.getChildren( type='joint' )[:2]
    end_joint = toe_joint.getChildren( type='joint' )[0]

    toe_length = toe_joint.translate.get().length()
    heel_length = heel_joint.translate.get().length()


    pm.select( toe_joint, end_joint, r=1 )
    toe_ik, toe_ee = pm.ikHandle( name=labels['ikToe'], sol='ikRPsolver', dh=1 )

    # -- add pivot groups

    pivot_ball = createNurbsShape( labels['pivotBall'], shape='U', size=toe_length )
    pivot_ball.translate.set( toe_joint.getRotatePivot(ws=1)/100 )
    pivot_ball.ty.set( pivot_ball.ty.get() + toe_length/2 )
    pivot_ball.rotate.set(-90,90,0)
    pm.makeIdentity(pivot_ball, apply=True, translate=True, rotate=True, scale=True)
    pivot_ball.setRotatePivot( toe_joint.getRotatePivot(ws=1), ws=1 )

    if guide_ik:
        pm.parent( main_ik, guide_ik, pivot_ball )
    else:
        pm.parent( main_ik, pivot_ball )


    pivot_toe = createNurbsShape( labels['pivotToe'], shape='U', size=toe_length  )
    pivot_toe.translate.set( end_joint.getRotatePivot(ws=1)/100 )
    pm.makeIdentity(pivot_toe, apply=True, translate=True, rotate=True, scale=True)

    pm.parent( pivot_ball, end_ik, pivot_toe )

    rotate_toe = pm.group( toe_ik, n=labels['rotateToe'] )
    rotate_toe.setRotatePivot( toe_joint.getRotatePivot(ws=1), ws=1 )

    pivot_heel = createNurbsShape( labels['pivotHeel'], shape='U', size=heel_length  )
    pivot_heel.translate.set( heel_joint.getRotatePivot(ws=1)/100 )
    pivot_heel.ry.set(180)
    pm.makeIdentity(pivot_heel, apply=True, translate=True, rotate=True, scale=True)

    pm.parent( pivot_toe, rotate_toe, pivot_heel )

    pm.parent( pivot_heel, control )


    exp_str = pm.expression( labels['expression'], query=1, s=1 )

    # -- fill out the expression template

    exp_template += EXP_FOOT_IKFK

    exp_str += exp_template \
    % {
        'toe_ik'      : toe_ik,
        'end_ik'       : end_ik
        }


    if footRollMode == FOOTROLL_AUTO:

        control.addAttr( "footRoll",  sn="fr", at='double', k=1, dv=0, min=-10, max=20 )
        control.addAttr( "toeRotate", sn="tr", at='double', k=1, dv=0 )

        control.tr >> rotate_toe.rx

        # -- Set Driven Keys

        pm.setDrivenKeyframe( pivot_toe.rx, cd=control.fr,  dv=10,  v=0,   ott='linear' )
        pm.setDrivenKeyframe( pivot_toe.rx, cd=control.fr,  dv=20,  v=60, itt='linear' )

        pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=0,   v=0,   ott='linear' )
        pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=10,  v=60, itt='linear' )
        pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=20,  v=0, itt='linear' )

        pm.setDrivenKeyframe( pivot_heel.rx, cd=control.fr, dv=0,   v=0,   ott='linear' )
        pm.setDrivenKeyframe( pivot_heel.rx, cd=control.fr, dv=-10, v=-40,  itt='linear' )


    elif footRollMode == FOOTROLL_CONTROLS:

        for obj in pm.ls( control, dag=1, type="nurbsCurve" ):
            addToSet( [obj.getParent()], 'controlsSet' )

        exp_template += EXP_FOOT_IKFK

        exp_str += EXP_FOOT_IKFK_CONTROLS \
        % {
            'heel_pivot_shape'  : pivot_heel.getShape(),
            'ball_pivot_shape'  : pivot_ball.getShape(),
            'toe_pivot_shape'   : pivot_toe.getShape(),
            'end_ik'            : end_ik
            }

    else: #footRollMode == FOOTROLL_ATTRIBUTES

        control.addAttr( "heelPivot", sn="hp", at='double', k=1, dv=0 )
        control.addAttr( "ballPivot", sn="bp", at='double', k=1, dv=0 )
        control.addAttr( "toePivot",  sn="tp", at='double', k=1, dv=0 )
        control.addAttr( "toeRotate", sn="tr", at='double', k=1, dv=0 )

        control.hp >> pivot_heel.rx
        control.bp >> pivot_ball.rx
        control.tp >> pivot_toe.rx
        control.tr >> rotate_toe.rx


    for obj in pm.ls( control, dag=1, type="transform" ):
        shape = obj.getShape()

        if shape is not None:
            pm.reorder(shape, back=1)

        if obj != control:
            setAttrs( obj, ['t','s'], channelBox=0, keyable=0, lock=1 )
            if footRollMode != FOOTROLL_CONTROLS:
                setAttrs( obj, ['r'], channelBox=1, keyable=0, lock=0 )
                obj.visibility.set(0)

        obj.v.set( channelBox=0, keyable=0 )
        pm.select( obj, r=1 )
        pm.color( ud=(CntlColors.left, CntlColors.right)[side] )


    pm.expression( labels['expression'], edit=1, s=exp_str )
Exemple #16
0
    pm.skinPercent(skinCluster, cv, transformValue = [(jnt, 1)])
 
 #cmds.skinPercent( 'skinCluster1', 'pPlane1.vtx[100]', transformValue=[('joint1', 0.2), ('joint3', 0.8)])

/////

import pymel.core as pm

sel = pm.ls(sl = True)

tfm_list = pm.listRelatives(sel, ad = True)
tfm_list.sort()
tfm_list.reverse()

for tfm in tfm_list:
    pm.reorder(tfm, front = True)

/////

import pymel.core as pm

sel_list = pm.ls(sl = True)
jnt_list = pm.listRelatives(sel_list, ad = True)

tfm_grp = pm.group(em = True, n = 'pxy_grp')
pm.addAttr(tfm_grp, ln = 'par_max', at = 'double', min = 0, max = 1, dv = 1, keyable = True)
pm.addAttr(tfm_grp, ln = 'par_min', at = 'double', min = 0, max = 1, dv = 0, keyable = True)

target_crv = pm.PyNode('SL_rope_anim_crv')

counter = 0
Exemple #17
0
def _create_twist_rig(dson_node):
    """
    Some models have an unusual roll and twist joint setup: they put elbow rotation
    on the shoulder twist joint, and put elbow rotation control on the shoulder control
    as an alias (which we don't import).  All twisting is on the twist joint; there's
    no weighting to put some of the rotation on any other joints.  The deformations this
    gives are fine, but it's a bit weird, so clean it up.

    Reparent the elbow directly under the shoulder, so the twist joint is by itself,
    and use an aim constraint to make the twist joint follow the elbow.  This way,
    the elbow joint can be rotated normally, and the twist joint will follow.

    This depends on the structure of the skeleton and should be turned off with skeletons
    that use different structures.
    """
    if dson_node.node_type != 'bone':
        return

    # We use the asset to figure out which bone is which.
    if not dson_node.asset:
        return

    twist_rig_info = _twist_rig_map.get(dson_node.asset.get_value('name'))
    if not twist_rig_info:
        return

    # The roll joint is the joint we're on.
    roll_joint = dson_node
    roll_joint_maya_node = roll_joint.maya_node

    # Find the twist joint.
    twist_joint = roll_joint.find_asset_name(
        twist_rig_info['twist_joint_asset_id'])
    twist_joint_maya_node = twist_joint.maya_node

    # Find the end joint, which is the joint after the twist joint.
    end_joint = roll_joint.find_asset_name(
        twist_rig_info['end_joint_asset_id'])
    end_joint_maya_node = end_joint.maya_node

    # Don't apply this if there are incoming connections to nodes we're going to change.
    # It's OK for there to be outgoing connections.  For example, we don't want a "knee
    # bend" constraint that targets the thigh, since we're going to put constraints on
    # the thigh, but corrective modifiers that read the position of the thigh are fine.
    # These twist joints are intended to make external rigging easier, and if you're
    # putting a rig on the figure, you want all controls that take over joints disabled
    # anyway.
    def has_incoming_connections(node):
        attrs_to_check = ('translate', 'translateX', 'translateY',
                          'translateZ', 'rotate', 'rotateX', 'rotateY',
                          'rotateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ')
        nodes = [node.attr(attr) for attr in attrs_to_check]
        connections = pm.listConnections(nodes, s=True, d=False, p=True)
        if connections:
            log.warning(
                'Not creating twist rig for %s because it has incoming connections: %s'
                % (node, connections))
            return True
        return False

    if has_incoming_connections(
            roll_joint_maya_node) or has_incoming_connections(
                twist_joint_maya_node) or has_incoming_connections(
                    end_joint_maya_node):
        return

    # The roll joint is oriented towards the twist joint, but we need it oriented towards
    # the end joint.  We don't want to reorient the joint, since it'll break anything constrained
    # to it.  Instead, create a new joint to take its place, and hide and parent the skinned
    # roll joint to the new joint.  That lets us reorient the new joint however we want.
    roll_joint_name = roll_joint_maya_node.nodeName()
    pm.rename(roll_joint_maya_node, '%s_Skinned' % roll_joint_name)

    # Create the new roll joint, and position it in the same place as the skinned one.
    new_roll_joint = pm.duplicate(roll_joint_maya_node,
                                  parentOnly=True,
                                  n=roll_joint_name)[0]
    pm.reorder(new_roll_joint, front=True)

    # Mark the roll joint that we're controlling internal.
    mh.config_internal_control(roll_joint_maya_node)
    roll_joint_maya_node.attr('visibility').set(0)

    # The roll joint may have rotations on it from straighten_poses in addition to jointOrient.
    # Freeze the rotations, or orient joints won't work ("has non-zero rotations").  This
    # is only freezing this control, not the underlying joint.
    pm.makeIdentity(new_roll_joint, apply=True, t=0, r=1, s=0, n=0, pn=1)

    # Create a copy of the end joint to orient towards.  We need to freeze rotations on this too,
    # or pm.joint will spew warnings about non-zero rotations.  (That looks like a bug, since we're
    # not telling it to orient that joint.)
    temporary_joint = pm.createNode('joint', n='temp')
    pm.parent(temporary_joint, end_joint_maya_node, r=True)
    pm.parent(temporary_joint, new_roll_joint)
    pm.makeIdentity(temporary_joint, apply=True, t=0, r=1, s=0, n=0, pn=1)

    # Orient the roll joint towards the end joint.
    pm.joint(new_roll_joint,
             e=True,
             orientJoint=twist_rig_info['roll_orient_joint'],
             secondaryAxisOrient=twist_rig_info['roll_orient_sao'])
    pm.delete(temporary_joint)

    def create_rotation_node():
        # Don't do this if there aren't any connections to rotation.
        attrs_to_check = ('rotate', 'rotateX', 'rotateY', 'rotateZ')
        for attr in attrs_to_check:
            if pm.listConnections(end_joint_maya_node.attr(attr),
                                  s=False,
                                  d=True,
                                  p=True):
                break
        else:
            return

        # Create a placeholder node.  This follows the end joint around and is parented to the twist joint,
        # so it represents the rotation of the end joint relative to the twist joint.  We'll move outgoing
        # connections from the end joint's rotation to this.  That way, even though we'll be reparenting the
        # end joint to under the bend joint, other nodes still see rotation relative to twist, like they
        # did before.
        rotation_output_node = pm.createNode('joint',
                                             n=end_joint_maya_node.nodeName() +
                                             '_RelativeRotation',
                                             p=end_joint_maya_node)
        mh.config_internal_control(rotation_output_node)
        pm.parent(rotation_output_node, twist_joint_maya_node)

        for attr in attrs_to_check:
            for connected_attr in pm.listConnections(
                    end_joint_maya_node.attr(attr), s=False, d=True, p=True):
                pm.connectAttr(rotation_output_node.attr(attr),
                               connected_attr,
                               force=True)

        pm.parentConstraint(end_joint_maya_node,
                            rotation_output_node,
                            mo=False)

    create_rotation_node()

    # Move the end joint out from inside the twist joint into the new roll joint.
    pm.parent(end_joint_maya_node, new_roll_joint)

    # Put the children of the old roll joint under the new roll joint.
    for child in pm.listRelatives(roll_joint_maya_node, children=True):
        pm.parent(child, new_roll_joint)

    # Constrain the old roll joint to the new one.  We're keeping this joint around unchanged,
    # since there may be other things constrained to it.  For example, clothing conforms often
    # connect to these joints.
    pm.parentConstraint(new_roll_joint,
                        roll_joint_maya_node,
                        maintainOffset=True)
    pm.scaleConstraint(new_roll_joint,
                       roll_joint_maya_node,
                       maintainOffset=True)

    # Turn off segmentScaleCompensate on the original roll joint that we've scale constrained.
    # We have it on so modifiers work, but modifiers are now pointing at our new joint, and
    # scale constraints don't work correctly with segmentScaleCompensate.
    roll_joint_maya_node.attr('segmentScaleCompensate').set(0)

    # For some reason, the YZX rotate order on some thigh twist joints causes the aim constraint
    # to flip out, and changing it to XYZ fixes it.  The rotate order on the twist joint shouldn't
    # matter since we should only ever be rotating it on one axis anyway.
    pm.setAttr(twist_joint_maya_node.attr('rotateOrder'), 0)

    pm.aimConstraint(end_joint_maya_node,
                     twist_joint_maya_node,
                     mo=True,
                     worldUpType='objectrotation',
                     worldUpObject=end_joint_maya_node,
                     aimVector=twist_rig_info['aim_vector'],
                     upVector=twist_rig_info['up_vector'],
                     worldUpVector=twist_rig_info['up_vector'])

    # Bump the twist joint down one in the outliner, so pressing down from the parent joint
    # goes to the end joint and not the twist joint.
    pm.reorder(end_joint_maya_node, relative=1)

    # Put the twist joint inside two empty groups.  This prevents a bone from being
    # drawn from the roll joint to the twist joint, since Maya only searches up two
    # parenting levels for a parent joint.
    group_inner = pm.group(twist_joint_maya_node,
                           name='%s_Grp1' % twist_joint_maya_node.nodeName())
    group_outer = pm.group(group_inner,
                           name='%s_Grp' % twist_joint_maya_node.nodeName())
    mh.config_internal_control(group_outer)
    pm.setAttr(group_outer.attr('visibility'), 0)

    # Point the roll joint node at the new roll joint.
    roll_joint.maya_node = new_roll_joint
Exemple #18
0
def reorderAllShapesToTopOfTheirHierchy():
    for transform in pymel.ls(type='transform'):
        shapes = pymel.listRelatives(transform, shapes=True)
        if shapes:
            for shape in reversed(shapes):
                pymel.reorder(shape, front=True)
Exemple #19
0
def create_eye_rig():
    selection = pm.ls(sl=True)
    if len(selection) < 2:
        log.warning('Select both eye joints, then an optional control node.')
        return
    joints = selection[0:2]

    if not sanity_check_eyes(joints):
        return

    # If a third node is selected, we'll put the distance control attribute on it.
    control_node = None
    if len(selection) >= 3:
        control_node = selection[2]

    # We want the left eye, then the right eye.  Switch them if they're reversed.
    if pm.xform(joints[0], q=True, ws=True, t=True)[0] < pm.xform(
            joints[1], q=True, ws=True, t=True)[0]:
        joints[0], joints[1] = joints[1], joints[0]

    # Search upwards for a shared parent.
    def find_shared_ancestor(node1, node2):
        while True:
            if node1 == node2:
                return node1
            node1 = pm.listRelatives(node1, p=True, pa=True)
            node2 = pm.listRelatives(node2, p=True, pa=True)
            if not node1 or not node2:
                return None
            node1 = node1[0]
            node2 = node2[0]

    joint_parent = find_shared_ancestor(joints[0], joints[1])
    #    joint_parent = pm.listRelatives(joints[0], p=True, pa=True)[0]
    if not joint_parent:
        log.error('The selected eye joints don\'t have a shared ancestor.')
        return

    # Get the distance between the eyes, and use a factor of that as the default distance
    # from the eyes to the control.
    left_pos = pm.xform(joints[0], q=True, ws=True, t=True)[0]
    right_pos = pm.xform(joints[1], q=True, ws=True, t=True)[0]
    distance = abs(left_pos - right_pos)
    defaultDistance = distance * 3

    # Create the group that will hold the control.  This node sets the origin
    # for the control, and follows the parents of the eye joints (typically the
    # head joint).  We'll put as many nodes in this as possible, to encapsulate
    # what we're creating.
    container_node = create_new_node('transform', nodeName='EyeRig')
    pm.xform(container_node, ws=True, t=average_position(joints[0], joints[1]))
    pm.xform(container_node, ws=True, r=True, t=(0, 0, defaultDistance))
    pm.parentConstraint(joint_parent, container_node, mo=True)
    pm.scaleConstraint(joint_parent, container_node, mo=True)

    # Create a null centered between the eyes.  This is what the control will aim at.
    center_node = create_new_node('transform',
                                  nodeName='Eye_Center',
                                  parent=container_node)
    pm.xform(center_node, ws=True, t=average_position(joints[0], joints[1]))

    # Create the handle.
    control_mesh = create_handle('Eyes')
    control_mesh = pm.parent(pm.listRelatives(control_mesh, p=True, pa=True),
                             container_node)[0]
    pm.xform(control_mesh, os=True, t=(0, 0, 0))
    control_mesh.attr('shape').set(1)
    control_mesh.attr('localRotateX').set(90)
    control_mesh.attr('localScale').set((2, 2, 2))
    control_mesh.attr('v').set(keyable=False, channelBox=True)

    # Set the rotation order to ZXY.  The Z rotation has no effect on the output, since we only
    # connect to X and Y, so this keeps things transforming correctly.
    control_mesh.attr('rotateOrder').set(2)

    # If we weren't given a node to put controls on, put them on the control shape.
    if control_node is None:
        control_node = control_mesh

    # Scaling the control won't work as expected, so lock it.  Note that we don't
    # lock rz here, since that confuses the rotation manipulator.
    for lock in 'sx', 'sy', 'sz':
        control_mesh.attr(lock).set(lock=True, keyable=False, cb=False)

    # Create a null inside the handle, and aim constrain it towards the eyes.
    # Create a transform.  Point constrain it to the handle, and aim constrain
    # it to the eyes.  The handle will add the rotation of this transform, so
    # the handle points towards the eyes as it's moved around.
    handle_aim_node = create_new_node('transform',
                                      nodeName='EyeRig_HandleAim',
                                      parent=container_node)
    pm.pointConstraint(control_mesh, handle_aim_node, mo=False)
    pm.aimConstraint(center_node, handle_aim_node, mo=True)
    set_notes(
        handle_aim_node,
        'This node is aim constrained towards the eyes, and the main control receives this node\'s rotation, so it visually points at the eyes without affecting its rotation.'
    )

    # Set the transform of the handle to the rotation of the EyeHandleAim transform, so it's
    # added to the visible rotation of the handle.  We could just connect the rotation to the
    # localRotation of the handle, but we're using that to orient the handle correctly.
    comp_node = create_new_node('composeMatrix', nodeName='EyeRig_CompMatrix1')
    handle_aim_node.attr('rotate').connect(comp_node.attr('inputRotate'))
    comp_node.attr('outputMatrix').connect(control_mesh.attr('transform'))

    # Create a group to hold the eye locators.  This is point constrained to the control.
    eye_locator_group = create_new_node('transform',
                                        nodeName='EyeTargets',
                                        parent=container_node)
    pm.xform(eye_locator_group,
             ws=True,
             t=pm.xform(control_mesh, q=True, ws=True, t=True))
    eye_locator_group.attr('visibility').set(0)
    pm.pointConstraint(control_mesh, eye_locator_group, mo=True)

    # Create locators for the eye targets.  This is what the eyes actually aim towards (via
    # the orient locators).
    eye_locators = []
    for idx, node in enumerate(joints):
        eye_locator = create_new_node('locator',
                                      nodeName=['EyeLeft', 'EyeRight'][idx],
                                      parent=eye_locator_group)
        pm.xform(eye_locator,
                 ws=True,
                 t=pm.xform(node, q=True, ws=True, t=True))
        pm.xform(eye_locator, ws=True, r=True, t=(0, 0, defaultDistance))
        eye_locators.append(eye_locator)

    # Create nulls which will sit on top of the joints.  This is what we'll actually aim,
    # so we can attach any rigging we want to them, and the eye joints only need a simple
    # orient constraint to these.
    orient_locators = []
    for idx, node in enumerate(joints):
        shortName = node.split('|')[-1]
        orient_node = create_new_node('transform',
                                      nodeName='%s_Orient' % shortName,
                                      parent=container_node)
        pm.xform(orient_node,
                 ws=True,
                 t=pm.xform(node, q=True, ws=True, t=True))

        # Create an up vector for the aim constraint.
        up_node = create_new_node('transform',
                                  nodeName='%s_Up' % shortName,
                                  parent=container_node)
        pm.xform(up_node, ws=True, t=pm.xform(node, q=True, ws=True, t=True))
        pm.xform(up_node, ws=True, t=(0, 1, 0), r=True)

        # Note that we don't need maintain offset here, only on the final orient constraint.
        # This way, the orient of these is always 0, making it easier to adjust.
        pm.aimConstraint(eye_locators[idx],
                         orient_node,
                         mo=True,
                         worldUpType='object',
                         worldUpObject=up_node)

        # Create a transform inside the orient node.  This rotates along with the control.
        # By making this a child of the top-level orient transform, the aim and the rotation
        # will combine additively.  This is the node we actually orient contrain the eye
        # joints to.
        orient_inner_node = create_new_node('transform',
                                            nodeName='%s_OrientInner' %
                                            shortName,
                                            parent=orient_node)

        # We're going to connect RX and RY to control_mesh, so give this node the same
        # rotation order as control_mesh.
        orient_inner_node.attr('rotateOrder').set(2)
        orient_locators.append(orient_inner_node)

        control_mesh.attr('rotateX').connect(orient_inner_node.attr('rotateX'))
        control_mesh.attr('rotateY').connect(orient_inner_node.attr('rotateY'))

        # Now, create a helper to figure out the X/Y angle.  We don't need this for the eye
        # control itself, since an orient constraint will do that for us, but this gives us
        # a clean rotation value, which driven keys like eyelid controls can be placed against.
        attr_name = 'angle_%s' % ['left', 'right'][idx]
        create_vector_attribute(control_mesh, attr_name)
        maya_helpers.lock_attr(control_mesh.attr('%sX' % attr_name),
                               'unkeyable')
        maya_helpers.lock_attr(control_mesh.attr('%sY' % attr_name),
                               'unkeyable')
        maya_helpers.lock_attr(control_mesh.attr('%sZ' % attr_name), 'lock')

        origin_node = create_new_node('locator',
                                      nodeName='%s_Origin' % shortName,
                                      parent=container_node)
        pm.xform(origin_node,
                 ws=True,
                 t=pm.xform(node, q=True, ws=True, t=True))

        # When forwards_node points in this direction, the angle is zero.
        initial_vector_node = create_new_node('locator',
                                              nodeName='%s_InitialVector' %
                                              shortName,
                                              parent=origin_node)
        pm.xform(initial_vector_node, t=(0, 0, 10), os=True)
        initial_vector_node.attr('visibility').set(False)

        forwards_node = create_new_node('locator',
                                        nodeName='%s_Forwards' % shortName,
                                        parent=orient_inner_node)
        pm.xform(forwards_node, t=(0, 0, 10), os=True)
        forwards_node.attr('visibility').set(False)

        initial_vector_origin = pm.createNode('multMatrix',
                                              n='%s_InitialVectorOrigin' %
                                              shortName)
        initial_vector_node.worldMatrix[0].connect(
            initial_vector_origin.matrixIn[0])
        origin_node.worldInverseMatrix[0].connect(
            initial_vector_origin.matrixIn[1])

        forwards_origin = pm.createNode('multMatrix',
                                        n='%s_ForwardsOrigin' % shortName)
        forwards_node.worldMatrix[0].connect(forwards_origin.matrixIn[0])
        origin_node.worldInverseMatrix[0].connect(forwards_origin.matrixIn[1])

        initial_decompose = pm.createNode('decomposeMatrix',
                                          n='%s_InitialDecompose' % shortName)
        initial_vector_origin.matrixSum.connect(initial_decompose.inputMatrix)

        forwards_decompose = pm.createNode('decomposeMatrix',
                                           n='%s_ForwardsDecompose' %
                                           shortName)
        forwards_origin.matrixSum.connect(forwards_decompose.inputMatrix)

        angle_node = pm.createNode('angleBetween', n='%s_Angle' % shortName)
        initial_decompose.outputTranslate.connect(angle_node.vector1)
        forwards_decompose.outputTranslate.connect(angle_node.vector2)

        angle_node.euler.connect(control_mesh.attr(attr_name))

    # Constrain the eye joints to the orient transform.
    for idx, node in enumerate(joints):
        pm.orientConstraint(orient_locators[idx], joints[idx], mo=True)

    # Create a setRange node.  This will translate from the eye locator X position (distance from
    # the center to the locator) to a 0..1 range that can be used as a control.
    #
    # setRange nodes actually clamp to their min and max, rather than just adjusting the range.
    # We don't really want that, since it can be useful to set the distance to a slightly negative
    # number to move the eyes apart a bit.  Work around this: instead of scaling 0..1 to eyeLocatorXPos..0,
    # scale from -1..1 to eyeLocatorXPos*2..0.  This gives a wider range, if wanted.
    # In:  -5 -4 -3 -2 -1  0  1  2  3  4  5
    # Out:  6  5  4  3  2  1  0 -1 -2 -3 -4
    locator_distance_range = create_new_node(
        'setRange', nodeName='EyeRig_SetRangeEyeDistance')
    eye_locator1_x = pm.xform(eye_locators[0], q=True, t=True, os=True)[0]
    eye_locator2_x = pm.xform(eye_locators[1], q=True, t=True, os=True)[0]
    locator_distance_range.attr('oldMin').set((-5, -5, 0))
    locator_distance_range.attr('oldMax').set((5, 5, 0))
    locator_distance_range.attr('min').set(
        (eye_locator1_x * 6, eye_locator2_x * 6, 0))
    locator_distance_range.attr('max').set(
        (eye_locator1_x * -4, eye_locator2_x * -4, 0))

    # The output of the setRange controls the distance of the eye locator from the main center control.
    locator_distance_range.attr('outValueX').connect(
        eye_locators[0].attr('translateX'))
    locator_distance_range.attr('outValueY').connect(
        eye_locators[1].attr('translateX'))

    # Add an attribute to move the eye locators to the center.  The most useful values of this are
    # 0 and 1, but support moving further and going crosseyed.
    pm.addAttr(control_node,
               ln='EyesFocused',
               at='double',
               min=-5,
               max=5,
               dv=0)
    control_node.attr('EyesFocused').set(e=True, keyable=True)
    control_node.attr('EyesFocused').connect(
        locator_distance_range.attr('valueX'))
    control_node.attr('EyesFocused').connect(
        locator_distance_range.attr('valueY'))

    # Move the control mesh to the top of the container.
    pm.reorder(control_mesh, front=True)
    pm.select(control_mesh)
    return container_node
Exemple #20
0
    '''
    Usage:
        reorder_outliner( pm.ls(sl=True) )
    '''
    for obj in objs:
        index_desired = detect_number( obj ) - 1
        siblings = obj.getParent().listRelatives( f = True, c = True, type = ['transform'] )
        print [sibling.name() for sibling in siblings]
        index_current = siblings.index( obj )
        index_shift = abs( index_current - index_desired )
        
        if index_desired < index_current:
            index_shift *= -1
            
        print obj.name(), index_current, index_desired, index_shift
        pm.reorder(obj, relative = index_shift)
        pm.reorder(siblings[index_desired], relative = index_shift*-1)
test = pm.ls(sl=True)[0]
siblings = [obj.name() for obj in test.getParent().listRelatives(f=True,c=True,type='transform')]
siblings.sort()
print siblings
def detect_number( obj ):
    splits = obj.name().split('_')
    if len(splits)>1:
        for split in splits:
            try:
                return int(split) 
            except:
                pass
        
        return -1
Exemple #21
0
 def reorder_children(self ,target):
     target = pm.PyNode(target)
     children_list = target.getChildren()
     children_list = self.natural_sort(children_list)
     for children in children_list[::-1]:
         pm.reorder(children, front = True)
def create_eye_rig():
    selection = pm.ls(sl=True)
    if len(selection) < 2:
        log.warning('Select both eye joints, then an optional control node.')
        return
    joints = selection[0:2]
    
    if not sanity_check_eyes(joints):
        return

    # If a third node is selected, we'll put the distance control attribute on it.
    control_node = None
    if len(selection) >= 3:
        control_node = selection[2]

    # We want the left eye, then the right eye.  Switch them if they're reversed.
    if pm.xform(joints[0], q=True, ws=True, t=True)[0] < pm.xform(joints[1], q=True, ws=True, t=True)[0]:
        joints[0], joints[1] = joints[1], joints[0]
            
    # Search upwards for a shared parent.
    def find_shared_ancestor(node1, node2):
        while True:
            if node1 == node2:
                return node1
            node1 = pm.listRelatives(node1, p=True, pa=True)
            node2 = pm.listRelatives(node2, p=True, pa=True)
            if not node1 or not node2:
                return None
            node1 = node1[0]
            node2 = node2[0]

    joint_parent = find_shared_ancestor(joints[0], joints[1])
    if not joint_parent:
        log.error('The selected eye joints don\'t have a shared ancestor.')
        return

    # Get the distance between the eyes, and use a factor of that as the default distance
    # from the eyes to the control.
    left_pos = pm.xform(joints[0], q=True, ws=True, t=True)[0]
    right_pos = pm.xform(joints[1], q=True, ws=True, t=True)[0]
    distance = abs(left_pos - right_pos)
    defaultDistance = distance * 2
    
    # Create the group that will hold the control.  This node sets the origin for the control,
    # and follows the parents of the eye joints (typically the head joint).  This is positioned
    # at the head, but we set its world space rotation to identity, so the rig is always oriented
    # the same way and not in the head's local orientation.
    container_node = create_new_node('transform', nodeName='EyeRig')
    joint_parent.worldMatrix[0].connect(container_node.offsetParentMatrix)
    pm.xform(container_node, ws=True, ro=(0,0,0))
    container_node.inheritsTransform.set(False)
            
    # Create a null centered between the eyes.  This is what the control will aim at.
    center_node = create_new_node('transform', nodeName='Eye_Center', parent=container_node)
    pm.xform(center_node, ws=True, t=average_position(joints[0], joints[1]))

    # Create the handle.
    control_mesh = create_handle('Eyes')
    control_mesh = pm.parent(pm.listRelatives(control_mesh, p=True, pa=True), container_node, r=True)[0]
    control_mesh.shape.set(1)
    control_mesh.localRotateX.set(90)
    control_mesh.localScale.set((2, 2, 2))
    control_mesh.visibility.set(keyable=False, channelBox=True)

    # Center the handle between the eyes, then move it forward.
    pm.xform(control_mesh, ws=True, t=average_position(joints[0], joints[1]))
    pm.xform(control_mesh, ws=True, r=True, t=(0,0,defaultDistance))

    # Put the base transform in offsetParentMatrix, so the control's TRS is zero.
    control_mesh.offsetParentMatrix.set(control_mesh.matrix.get())
    control_mesh.t.set((0,0,0))

    # Combine the control transform's offsetParentMatrix and matrix.  This is the actual position
    # of the control within the coordinate space of the rig.
    control_transform = pm.createNode('multMatrix', n='EyeRig_ControlTransform')
    control_mesh.matrix.connect(control_transform.matrixIn[0])
    control_mesh.offsetParentMatrix.connect(control_transform.matrixIn[1])
    control_mesh_matrix = control_transform.matrixSum

    # Set the rotation order to ZXY.  We're only rotating on X and Y, so putting Z first
    # means we can ignore it without affecting the result.
    control_mesh.rotateOrder.set(2)

    # If we weren't given a node to put controls on, put them on the control shape.
    if control_node is None:
        control_node = control_mesh
            
    # Scaling the control won't work as expected, so lock it.  Note that we don't
    # lock rz here, since that confuses the rotation manipulator.
    for lock in 'sx', 'sy', 'sz':
        maya_helpers.lock_scale(control_mesh, lock='hide')

    # Create a matrix that aims the translation control towards the center of the eyes.
    # This gives us the rotation caused by translating the control.
    aim_matrix = pm.createNode('aimMatrix', n='EyeRig_HandleAim')
    aim_matrix.primaryInputAxis.set((0,0,-1))

    # If we leave secondaryInputAxis disabled, the aimMatrix will aim the X and Y axes and pass
    # through Z (twist).  Align the twist axis to zero it out.
    aim_matrix.secondaryInputAxis.set((0,1,0))
    aim_matrix.secondaryTargetVector.set((0,1,0))
    aim_matrix.secondaryMode.set(2) # align
    control_mesh_matrix.connect(aim_matrix.inputMatrix)
    center_node.matrix.connect(aim_matrix.primaryTargetMatrix)

    # The aimMatrix includes the translation, which is a bit weird.  It's an aim matrix, why
    # would you want it to include translation?  Use pickMatrix to grab just rotation.
    pick_rotation = pm.createNode('pickMatrix', n='EyeRig_PickAimRotation')
    pick_rotation.useTranslate.set(False)
    pick_rotation.useScale.set(False)
    pick_rotation.useShear.set(False)
    aim_matrix.outputMatrix.connect(pick_rotation.inputMatrix)

    translation_rotation_matrix = pick_rotation.outputMatrix

    # Rotate the handle with the aim matrix, so it points towards the eyes when it's translated around.
    # This is purely cosmetic.
    translation_rotation_matrix.connect(control_mesh.transform)

    # Create a setRange node to scale the eyesFocused value to an angle.
    locator_distance_range = create_new_node('setRange', nodeName='EyeRig_SetRangeEyeDistance')
    locator_distance_range.oldMin.set((-5, -5, 0))
    locator_distance_range.oldMax.set((5, 5, 0))
    locator_distance_range.min.set((30, -30, 0))
    locator_distance_range.max.set((-30, 30, 0))

    # Add an attribute to move the eyes inwards and outwards.
    pm.addAttr(control_node, ln='eyesFocused', at='double', min=-5, max=5, dv=0)
    control_node.eyesFocused.set(e=True, keyable=True)
    control_node.eyesFocused.connect(locator_distance_range.valueX)
    control_node.eyesFocused.connect(locator_distance_range.valueY)

    for idx, node in enumerate(joints):
        shortName = node.nodeName(stripNamespace=True)

        # Extract the rotation part of the eye transform.  We could use .rotate, but we'd need to compose it
        # to a matrix anyway, so this is faster and doesn't care about rotation order.
        pick_rotation = pm.createNode('pickMatrix', n='PickTransformRotation_%s' % shortName)
        pick_rotation.useTranslate.set(False)
        pick_rotation.useScale.set(False)
        pick_rotation.useShear.set(False)
        control_mesh_matrix.connect(pick_rotation.inputMatrix)

        # Compose the eyesFocused value, which also contributes to the rotation.
        eyes_focused_compose = pm.createNode('composeMatrix', n='EyeRig_ComposeFocusedMatrix_%s' % shortName)
        focused_angle = [locator_distance_range.outValueX, locator_distance_range.outValueY][idx]
        focused_angle.connect(eyes_focused_compose.inputRotateY)

        # Finally, combine the three parts of the rotation.
        combine_rotations = pm.createNode('multMatrix', n='EyeRig_CombineRotations_%s' % shortName)
        translation_rotation_matrix.connect(combine_rotations.matrixIn[0])
        pick_rotation.outputMatrix.connect(combine_rotations.matrixIn[1])
        eyes_focused_compose.outputMatrix.connect(combine_rotations.matrixIn[2])

        # Decompose the result back to euler rotations and connect it to the angle attribute.
        # We're only rotating on X and Y, and putting Z first so it doesn't affect the others.
        # Only connect X and Y so any rotations on Z are discarded.
        decompose_rotation = pm.createNode('decomposeMatrix', n='EyeRig_DecomposeFinalRotations_%s' % shortName)
        decompose_rotation.inputRotateOrder.set(2) # zxy
        combine_rotations.matrixSum.connect(decompose_rotation.inputMatrix)

        # Create a node that will receive the final rotation, and constrain the joint to it.
        output_node = create_new_node('transform', nodeName='%s_Output' % shortName, parent=container_node)
        pm.xform(output_node, ws=True, t=pm.xform(node, q=True, ws=True, t=True))
        decompose_rotation.outputRotateX.connect(output_node.rotateX)
        decompose_rotation.outputRotateY.connect(output_node.rotateY)
        output_node.rotateOrder.set(2)
        pm.orientConstraint(output_node, joints[idx], mo=True)

    # Move the control mesh to the top of the container.
    pm.reorder(control_mesh, front=True)
    pm.select(control_mesh)
    return container_node